[
  {
    "path": ".codeclimate.yml",
    "content": "engines:\n  duplication:\n    enabled: true\n    config:\n      languages:\n      - python\n  fixme:\n    enabled: true\n  radon:\n    enabled: true\n  pep8:\n    enabled: true\n  shellcheck:\n    enabled: true\nratings:\n  paths:\n  - \"**.py\"\n  - \"**.sh\"\nexclude_paths:\n- doc/**/*\n- scripts/**/*\n- \"**/tests/\"\n"
  },
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nenv/\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\n*.egg-info/\n.installed.cfg\n*.egg\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*,cover\n.hypothesis/\n\n# Sphinx documentation\ndocs/_build/\n\n# pyenv\n.python-version\n\n# kicad specific files\n*.kicad_mod\n*.pretty/\n"
  },
  {
    "path": ".travis.yml",
    "content": "sudo: false\ncache:\n  - pip\n  - directories:\n    - $HOME/.cache/pip\nlanguage: python\npython:\n  - \"2.7\"\n  - \"3.4\"\n  - \"3.5\"\n  - \"3.6\"\n  - \"3.7\"\ninstall:\n  - ./manage.sh update_dev_packages\nscript:\n  - ./manage.sh pep8_check\n  - ./manage.sh unit_tests\n  - ./manage.sh py_test_coverage\n"
  },
  {
    "path": "AUTHORS.md",
    "content": "**Maintainer:**\n\n* Thomas Pointhuber <thomas.pointhuber@gmx.at> @pointhi\n* Rene Pöschl, @poeschlr\n* @evanshultz\n\n**Contributors:**\n\nPeople who have submitted patches, reported bugs, consulted features or generally made KicadModTree better\n\n* Oliver, @SchrodingersGat\n* Jan W. Krieger, @jkriege2\n* Frank, @Frankkkkk\n* @Hackscribble\n* @stoth\n* Patrick Pelletier, @ppelleti\n* @DASFrank\n* Dominik Baack, @matyro\n* Jordi Pakey-Rodriguez, @0xdec\n* George, @grob6000\n* Tobias Müller, @twam\n* Terje Io, @terjeio\n* Frank Severinsen, @Shackmeister\n* @robertlong13\n* Julien Cassette, @jcassette\n* Trevor Vannoy,  @tvannoy\n* Kari Hautio, @kh4\n* Stefan, @Misca1234\n* Antonio Vazquez, @antoniovazquezblanco\n* Hendrik v. Raven, @lorem-ipsum\n* Asuki Kono, @asukiaaa\n* Xathar, @jneiva08\n* @matthuszagh\n* @ferdymercury\n* @jhalmen\n* @herostrat\n* @fauxpark\n* @matthijskooijman\n* Clara Hobbs, @Ratfink\n* @MRQ\n* Stefan Krüger, @s-light\n* John Whitmore, @johnfwhitmore\n* Daniel Mack, @zonque\n* @dominformant\n* @tpambor\n* @nivekg\n* Joel, @myfreescalewebpage\n* JonRB, @eeyrjmr\n* Alexander Ransmann, @cronJ\n* Christian Schlüter, @chschlue\n* Chase Patterson, @chapatt\n* Rolf Schäuble, @rschaeuble\n* @penoud\n* @ki5libs\n* @fvollmer\n* @cp-aquila\n* Anders Wallin, @aewallin\n* Jonas Schievink, @jonas-schievink\n* Diego Herranz, @diegoherranz\n* Alexandre Oliveira, @RockyTV\n* Konstantin Oblaukhov, @ObKo\n* Jesper, @JeppeSRC\n* Jacob E. F. Overgaard @JacobEFO\n* Ed Peguillan III, @yankee14\n* Thomas Schmid, @rckTom\n* @mitch354\n* Jan Krueger, @einball\n* @dogtopus\n* Darrell Harmon, @dlharmon\n* David Imhoff, @dimhoff\n* marble, @cyber-murmel\n* @chemicstry\n* @awygle\n* @TiZed\n* Sean Leavey, @SeanDS\n* @Schlumpf\n* Daniel Giesbrecht, @DanSGiesbrecht\n* Caleb Reister, @calebreister\n* Greg Cormier, @gcormier\n* Ilya Elenskiy, @EvilMav\n* Mathias Walter, @tolot27\n* Michael Munch, @Munken\n* @waschhauser\n"
  },
  {
    "path": "KicadModTree/FileHandler.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016-2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport io\n\n\nclass FileHandler(object):\n    r\"\"\"some basic methods to write footprints, and which is the base class of footprint writer implementations\n\n    :param kicad_mod:\n        Main object representing the footprint\n    :type kicad_mod: ``KicadModTree.Footprint``\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> kicad_mod = Footprint(\"example_footprint\")\n    >>> file_handler = KicadFileHandler(kicad_mod)  # KicadFileHandler is a implementation of FileHandler\n    >>> file_handler.writeFile('example_footprint.kicad_mod')\n    \"\"\"\n\n    def __init__(self, kicad_mod):\n        self.kicad_mod = kicad_mod\n\n    def writeFile(self, filename, **kwargs):\n        r\"\"\"Write the output of FileHandler.serialize to a file\n\n        :param filename:\n            path of the output file\n        :type filename: ``str``\n\n        :Example:\n\n        >>> from KicadModTree import *\n        >>> kicad_mod = Footprint(\"example_footprint\")\n        >>> file_handler = KicadFileHandler(kicad_mod)  # KicadFileHandler is a implementation of FileHandler\n        >>> file_handler.writeFile('example_footprint.kicad_mod')\n        \"\"\"\n\n        with io.open(filename, \"w\", newline='\\n') as f:\n            output = self.serialize(**kwargs)\n\n            # convert to unicode if running python2\n            if sys.version_info[0] == 2 and type(output) != unicode:\n                output = unicode(output, \"utf-8\")\n\n            f.write(output)\n\n            f.close()\n\n    def serialize(self, **kwargs):\n        r\"\"\"Get a valid string representation of the footprint in the specified format\n\n        :Example:\n\n        >>> from KicadModTree import *\n        >>> kicad_mod = Footprint(\"example_footprint\")\n        >>> file_handler = KicadFileHandler(kicad_mod)  # KicadFileHandler is a implementation of FileHandler\n        >>> print(file_handler.serialize())\n        \"\"\"\n\n        raise NotImplementedError(\"serialize has to be implemented by child class\")\n"
  },
  {
    "path": "KicadModTree/KicadFileHandler.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016-2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.FileHandler import FileHandler\nfrom KicadModTree.util.kicad_util import *\nfrom KicadModTree.nodes.base.Pad import Pad  # TODO: why .KicadModTree is not enough?\nfrom KicadModTree.nodes.base.Arc import Arc\nfrom KicadModTree.nodes.base.Circle import Circle\nfrom KicadModTree.nodes.base.Line import Line\nfrom KicadModTree.nodes.base.Polygon import Polygon\n\n\nDEFAULT_LAYER_WIDTH = {'F.SilkS': 0.12,\n                       'B.SilkS': 0.12,\n                       'F.Fab': 0.10,\n                       'B.Fab': 0.10,\n                       'F.CrtYd': 0.05,\n                       'B.CrtYd': 0.05}\n\nDEFAULT_WIDTH_POLYGON_PAD = 0\n\nDEFAULT_WIDTH = 0.15\n\n\ndef _get_layer_width(layer, width=None):\n    if width is not None:\n        return width\n    else:\n        return DEFAULT_LAYER_WIDTH.get(layer, DEFAULT_WIDTH)\n\n\nclass KicadFileHandler(FileHandler):\n    r\"\"\"Implementation of the FileHandler for .kicad_mod files\n\n    :param kicad_mod:\n        Main object representing the footprint\n    :type kicad_mod: ``KicadModTree.Footprint``\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> kicad_mod = Footprint(\"example_footprint\")\n    >>> file_handler = KicadFileHandler(kicad_mod)\n    >>> file_handler.writeFile('example_footprint.kicad_mod')\n    \"\"\"\n\n    def __init__(self, kicad_mod):\n        FileHandler.__init__(self, kicad_mod)\n\n    def serialize(self, **kwargs):\n        r\"\"\"Get a valid string representation of the footprint in the .kicad_mod format\n\n        :Example:\n\n        >>> from KicadModTree import *\n        >>> kicad_mod = Footprint(\"example_footprint\")\n        >>> file_handler = KicadFileHandler(kicad_mod)\n        >>> print(file_handler.serialize())\n        \"\"\"\n\n        sexpr = ['module', self.kicad_mod.name,\n                 ['layer', 'F.Cu'],\n                 ['tedit', formatTimestamp(kwargs.get('timestamp'))],\n                 SexprSerializer.NEW_LINE\n                ]  # NOQA\n\n        if self.kicad_mod.description:\n            sexpr.append(['descr', self.kicad_mod.description])\n            sexpr.append(SexprSerializer.NEW_LINE)\n\n        if self.kicad_mod.tags:\n            sexpr.append(['tags', self.kicad_mod.tags])\n            sexpr.append(SexprSerializer.NEW_LINE)\n\n        if self.kicad_mod.attribute:\n            sexpr.append(['attr', self.kicad_mod.attribute])\n            sexpr.append(SexprSerializer.NEW_LINE)\n\n        if self.kicad_mod.maskMargin:\n            sexpr.append(['solder_mask_margin', self.kicad_mod.maskMargin])\n            sexpr.append(SexprSerializer.NEW_LINE)\n\n        if self.kicad_mod.pasteMargin:\n            sexpr.append(['solder_paste_margin', self.kicad_mod.pasteMargin])\n            sexpr.append(SexprSerializer.NEW_LINE)\n\n        if self.kicad_mod.pasteMarginRatio:\n            sexpr.append(['solder_paste_ratio', self.kicad_mod.pasteMarginRatio])\n            sexpr.append(SexprSerializer.NEW_LINE)\n\n        sexpr.extend(self._serializeTree())\n\n        return str(SexprSerializer(sexpr))\n\n    def _serializeTree(self):\n        nodes = self.kicad_mod.serialize()\n\n        grouped_nodes = {}\n\n        for single_node in nodes:\n            node_type = single_node.__class__.__name__\n\n            current_nodes = grouped_nodes.get(node_type, [])\n            current_nodes.append(single_node)\n\n            grouped_nodes[node_type] = current_nodes\n\n        sexpr = []\n\n        # serialize initial text nodes\n        if 'Text' in grouped_nodes:\n            reference_nodes = list(filter(lambda node: node.type == 'reference', grouped_nodes['Text']))\n            for node in reference_nodes:\n                sexpr.append(self._serialize_Text(node))\n                sexpr.append(SexprSerializer.NEW_LINE)\n                grouped_nodes['Text'].remove(node)\n\n            value_nodes = list(filter(lambda node: node.type == 'value', grouped_nodes['Text']))\n            for node in value_nodes:\n                sexpr.append(self._serialize_Text(node))\n                sexpr.append(SexprSerializer.NEW_LINE)\n                grouped_nodes['Text'].remove(node)\n\n        for key, value in sorted(grouped_nodes.items()):\n            # check if key is a base node, except Model\n            if key not in {'Arc', 'Circle', 'Line', 'Pad', 'Polygon', 'Text'}:\n                continue\n\n            # render base nodes\n            for node in value:\n                sexpr.append(self._callSerialize(node))\n                sexpr.append(SexprSerializer.NEW_LINE)\n\n        # serialize 3D Models at the end\n        if grouped_nodes.get('Model'):\n            for node in grouped_nodes.get('Model'):\n                sexpr.append(self._serialize_Model(node))\n                sexpr.append(SexprSerializer.NEW_LINE)\n\n        return sexpr\n\n    def _callSerialize(self, node):\n        '''\n        call the corresponding method to serialize the node\n        '''\n        method_type = node.__class__.__name__\n        method_name = \"_serialize_{0}\".format(method_type)\n        if hasattr(self, method_name):\n            return getattr(self, method_name)(node)\n        else:\n            exception_string = \"{name} (node) not found, cannot serialized the node of type {type}\"\n            raise NotImplementedError(exception_string.format(name=method_name, type=method_type))\n\n    def _serialize_ArcPoints(self, node):\n        # in KiCAD, some file attributes of Arc are named not in the way of their real meaning\n        center_pos = node.getRealPosition(node.center_pos)\n        end_pos = node.getRealPosition(node.start_pos)\n\n        return [\n                ['start', center_pos.x, center_pos.y],\n                ['end', end_pos.x, end_pos.y],\n                ['angle', node.angle]\n               ]\n\n    def _serialize_Arc(self, node):\n        sexpr = ['fp_arc']\n        sexpr += self._serialize_ArcPoints(node)\n        sexpr += [\n                  ['layer', node.layer],\n                  ['width', _get_layer_width(node.layer, node.width)]\n                 ]  # NOQA\n\n        return sexpr\n\n    def _serialize_CirclePoints(self, node):\n        center_pos = node.getRealPosition(node.center_pos)\n        end_pos = node.getRealPosition(node.center_pos + (node.radius, 0))\n\n        return [\n                ['center', center_pos.x, center_pos.y],\n                ['end', end_pos.x, end_pos.y]\n               ]\n\n    def _serialize_Circle(self, node):\n        sexpr = ['fp_circle']\n        sexpr += self._serialize_CirclePoints(node)\n        sexpr += [\n                  ['layer', node.layer],\n                  ['width', _get_layer_width(node.layer, node.width)]\n                 ]  # NOQA\n\n        return sexpr\n\n    def _serialize_LinePoints(self, node):\n        start_pos = node.getRealPosition(node.start_pos)\n        end_pos = node.getRealPosition(node.end_pos)\n        return [\n                ['start', start_pos.x, start_pos.y],\n                ['end', end_pos.x, end_pos.y]\n               ]\n\n    def _serialize_Line(self, node):\n        start_pos = node.getRealPosition(node.start_pos)\n        end_pos = node.getRealPosition(node.end_pos)\n\n        sexpr = ['fp_line']\n        sexpr += self._serialize_LinePoints(node)\n        sexpr += [\n                ['layer', node.layer],\n                 ['width', _get_layer_width(node.layer, node.width)]\n                ]  # NOQA\n\n        return sexpr\n\n    def _serialize_Text(self, node):\n        sexpr = ['fp_text', node.type, node.text]\n\n        position, rotation = node.getRealPosition(node.at, node.rotation)\n        if rotation:\n            sexpr.append(['at', position.x, position.y, rotation])\n        else:\n            sexpr.append(['at', position.x, position.y])\n\n        sexpr.append(['layer', node.layer])\n        if node.hide:\n            sexpr.append('hide')\n        sexpr.append(SexprSerializer.NEW_LINE)\n\n        effects = [\n                'effects',\n                ['font',\n                    ['size', node.size.x, node.size.y],\n                    ['thickness', node.thickness]]]\n\n        if node.mirror:\n            effects.append(['justify', 'mirror'])\n\n        sexpr.append(effects)\n        sexpr.append(SexprSerializer.NEW_LINE)\n\n        return sexpr\n\n    def _serialize_Model(self, node):\n        sexpr = ['model', node.filename,\n                 SexprSerializer.NEW_LINE,\n                 ['at', ['xyz', node.at.x, node.at.y, node.at.z]],\n                 SexprSerializer.NEW_LINE,\n                 ['scale', ['xyz', node.scale.x, node.scale.y, node.scale.z]],\n                 SexprSerializer.NEW_LINE,\n                 ['rotate', ['xyz', node.rotate.x, node.rotate.y, node.rotate.z]],\n                 SexprSerializer.NEW_LINE\n                ]  # NOQA\n\n        return sexpr\n\n    def _serialize_CustomPadPrimitives(self, pad):\n        all_primitives = []\n        for p in pad.primitives:\n            all_primitives.extend(p.serialize())\n\n        grouped_nodes = {}\n\n        for single_node in all_primitives:\n            node_type = single_node.__class__.__name__\n\n            current_nodes = grouped_nodes.get(node_type, [])\n            current_nodes.append(single_node)\n\n            grouped_nodes[node_type] = current_nodes\n\n        sexpr_primitives = []\n\n        for key, value in sorted(grouped_nodes.items()):\n            # check if key is a base node, except Model\n            if key not in {'Arc', 'Circle', 'Line', 'Pad', 'Polygon', 'Text'}:\n                continue\n\n            # render base nodes\n            for p in value:\n                if isinstance(p, Polygon):\n                    sp = ['gr_poly',\n                          self._serialize_PolygonPoints(p, newline_after_pts=True)\n                         ]  # NOQA\n                elif isinstance(p, Line):\n                    sp = ['gr_line'] + self._serialize_LinePoints(p)\n                elif isinstance(p, Circle):\n                    sp = ['gr_circle'] + self._serialize_CirclePoints(p)\n                elif isinstance(p, Arc):\n                    sp = ['gr_arc'] + self._serialize_ArcPoints(p)\n                else:\n                    raise TypeError('Unsuported type of primitive for custom pad.')\n                sp.append(['width', DEFAULT_WIDTH_POLYGON_PAD if p.width is None else p.width])\n                sexpr_primitives.append(sp)\n                sexpr_primitives.append(SexprSerializer.NEW_LINE)\n\n        return sexpr_primitives\n\n    def _serialize_Pad(self, node):\n        sexpr = ['pad', node.number, node.type, node.shape]\n\n        position, rotation = node.getRealPosition(node.at, node.rotation)\n        if not rotation % 360 == 0:\n            sexpr.append(['at', position.x, position.y, rotation])\n        else:\n            sexpr.append(['at', position.x, position.y])\n\n        sexpr.append(['size', node.size.x, node.size.y])\n\n        if node.type in [Pad.TYPE_THT, Pad.TYPE_NPTH]:\n            if node.drill.x == node.drill.y:\n                sexpr.append(['drill', node.drill.x])\n            else:\n                sexpr.append(['drill', 'oval', node.drill.x, node.drill.y])\n\n        sexpr.append(['layers'] + node.layers)\n        if node.shape == Pad.SHAPE_ROUNDRECT:\n            sexpr.append(['roundrect_rratio', node.radius_ratio])\n\n        if node.shape == Pad.SHAPE_CUSTOM:\n            # gr_line, gr_arc, gr_circle or gr_poly\n            sexpr.append(SexprSerializer.NEW_LINE)\n            sexpr.append(['options',\n                         ['clearance', node.shape_in_zone],\n                         ['anchor', node.anchor_shape]\n                        ])  # NOQA\n            sexpr.append(SexprSerializer.NEW_LINE)\n            sexpr_primitives = self._serialize_CustomPadPrimitives(node)\n            sexpr.append(['primitives', SexprSerializer.NEW_LINE] + sexpr_primitives)\n\n        if node.solder_paste_margin_ratio != 0 or node.solder_mask_margin != 0 or node.solder_paste_margin != 0:\n            sexpr.append(SexprSerializer.NEW_LINE)\n            if node.solder_mask_margin != 0:\n                sexpr.append(['solder_mask_margin', node.solder_mask_margin])\n            if node.solder_paste_margin_ratio != 0:\n                sexpr.append(['solder_paste_margin_ratio', node.solder_paste_margin_ratio])\n            if node.solder_paste_margin != 0:\n                sexpr.append(['solder_paste_margin', node.solder_paste_margin])\n\n        return sexpr\n\n    def _serialize_PolygonPoints(self, node, newline_after_pts=False):\n        node_points = ['pts']\n        if newline_after_pts:\n            node_points.append(SexprSerializer.NEW_LINE)\n        points_appended = 0\n        for n in node.nodes:\n            if points_appended >= 4:\n                points_appended = 0\n                node_points.append(SexprSerializer.NEW_LINE)\n            points_appended += 1\n\n            n_pos = node.getRealPosition(n)\n            node_points.append(['xy', n_pos.x, n_pos.y])\n\n        return node_points\n\n    def _serialize_Polygon(self, node):\n        node_points = self._serialize_PolygonPoints(node)\n\n        sexpr = ['fp_poly',\n                 node_points,\n                 ['layer', node.layer],\n                 ['width', _get_layer_width(node.layer, node.width)]\n                ]  # NOQA\n\n        return sexpr\n"
  },
  {
    "path": "KicadModTree/ModArgparser.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2017 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport argparse\nimport csv\n\ntry:\n    import yaml\n    YAML_AVAILABLE = True\nexcept ImportError:\n    YAML_AVAILABLE = False\n\n\nclass ParserException(Exception):\n    def __itruediv__(self, *args, **kwargs):\n        Exception.__init__(self, *args, **kwargs)\n\n\nclass ModArgparser(object):\n    r\"\"\"A general data loading class, which allows us to specify parts using .yml or .csv files.\n\n    Using this class allows us to seperate between the implementation of a footprint generator, and the data which\n    represents a single footprint. To do so, we need to define which parameters are expected in those data-files.\n\n    To improve the usablity of this class, it is able to do type checks of provided parameters, as well as defining\n    default values and do a simple check if a parameter can be considered as required or optional.\n\n    :param footprint_function:\n        A function which is called for every footprint we want to generate\n    :type footprint_function: ``function reference``\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> def footprint_gen(args):\n    ...    print(\"create footprint: {}\".format(args['name']))\n    ...\n    >>> parser = ModArgparser(footprint_gen)\n    >>> parser.add_parameter(\"name\", type=str, required=True)  # the root node of .yml files is parsed as name\n    >>> parser.add_parameter(\"datasheet\", type=str, required=False)\n    >>> parser.add_parameter(\"courtyard\", type=float, required=False, default=0.25)\n    >>> parser.add_parameter(\"pincount\", type=int, required=True)\n    >>> parser.run()  # now run our script which handles the whole part of parsing the files\n    \"\"\"\n\n    def __init__(self, footprint_function):\n        self._footprint_function = footprint_function\n        self._params = {}\n\n    def add_parameter(self, name, **kwargs):\n        r\"\"\"Add a parameter to the ModArgparser\n\n        :param name:\n            name of the argument\n        :param \\**kwargs:\n            See below\n        :type name: ``str``\n\n        :Keyword Arguments:\n            * *type* (``type``) --\n              type of the argument\n            * *required* (``bool``) --\n              is the argument required or optional\n            * *default* --\n              a default value which is used when there is no value defined\n\n        :Example:\n\n        >>> from KicadModTree import *\n        >>> def footprint_gen(args):\n        ...    print(\"create footprint: {}\".format(args['name']))\n        ...\n        >>> parser = ModArgparser(footprint_gen)\n        >>> parser.add_parameter(\"name\", type=str, required=True)  # the root node of .yml files is parsed as name\n        >>> parser.add_parameter(\"datasheet\", type=str, required=False)\n        >>> parser.add_parameter(\"courtyard\", type=float, required=False, default=0.25)\n        \"\"\"\n\n        self._params[name] = kwargs\n\n    def run(self):\n        r\"\"\"Execute the ModArgparser and run all tasks defined via the commandline arguments of this script\n\n        This method parses the commandline arguments to determine which actions to take. Beside of parsing .yml and .csv\n        files, it also allows us to output example files.\n\n        >>> from KicadModTree import *\n        >>> def footprint_gen(args):\n        ...    print(\"create footprint: {}\".format(args['name']))\n        ...\n        >>> parser = ModArgparser(footprint_gen)\n        >>> parser.add_parameter(\"name\", type=str, required=True)  # the root node of .yml files is parsed as name\n        >>> parser.run()  # now run our script which handles the whole part of parsing the files\n        \"\"\"\n\n        parser = argparse.ArgumentParser(description='Parse footprint defintion file(s) and create matching footprints')\n        parser.add_argument('files', metavar='file', type=str, nargs='*', help='.yml or .csv files which contains data')\n        parser.add_argument('-v', '--verbose', help='show some additional information', action='store_true')  # TODO\n        parser.add_argument('--print_yml', help='print example .yml file', action='store_true')\n        parser.add_argument('--print_csv', help='print example .csv file', action='store_true')\n\n        # TODO: allow writing into sub dir\n\n        args = parser.parse_args()\n\n        if args.print_yml:\n            self._print_example_yml()\n            return\n\n        if args.print_csv:\n            self._print_example_csv()\n            return\n\n        if len(args.files) == 0:\n            parser.print_help()\n            return\n\n        for filepath in args.files:\n            print(\"use file: {0}\".format(filepath))\n            if filepath.endswith('.yml') or filepath.endswith('.yaml'):\n                self._parse_and_execute_yml(filepath)\n            elif filepath.endswith('.csv'):\n                self._parse_and_execute_csv(filepath)\n            else:\n                print(\"unexpected filetype: {0}\".format(filepath))\n\n    def _parse_and_execute_yml(self, filepath):\n        if not YAML_AVAILABLE:\n            print(\"pyyaml not available!\")\n            sys.exit(1)\n\n        with open(filepath, 'r') as stream:\n            try:\n                parsed = yaml.safe_load(stream)  # parse file\n\n                if parsed is None:\n                    print(\"empty file!\")\n                    return\n\n                for footprint in parsed:\n                    kwargs = parsed.get(footprint)\n\n                    # name is a reserved key\n                    if 'name' in kwargs:\n                        print(\"ERROR: name is already used for root name!\")\n                        continue\n                    kwargs['name'] = footprint\n\n                    self._execute_script(**kwargs)  # now we can execute the script\n\n            except yaml.YAMLError as exc:\n                print(exc)\n\n    def _create_example_data_required(self, **kwargs):\n        params = {}\n        for k, v in self._params.items():\n            if kwargs.get('include_name', False) is False and k == \"name\":\n                continue\n            if v.get('required', False):\n                params[k] = self._create_example_datapoint(v.get('type', str), v.get('default'))\n\n        return params\n\n    def _create_example_data_full(self, **kwargs):\n        params = {}\n        for k, v in self._params.items():\n            if kwargs.get('include_name', False) is False and k == \"name\":\n                continue\n            params[k] = self._create_example_datapoint(v.get('type', str), v.get('default'))\n\n        return params\n\n    def _create_example_datapoint(self, type, default):\n        if default:\n            return type(default)\n\n        if type is bool:\n            return False\n        elif type is int:\n            return 0\n        elif type is float:\n            return 0.0\n        elif type is str:\n            return \"some string\"\n        else:\n            return \"??\"\n\n    def _print_example_yml(self):\n        if not YAML_AVAILABLE:\n            print(\"pyyaml not available!\")\n            sys.exit(1)\n\n        data = {'footprint_required': self._create_example_data_required(),\n                'footprint_full': self._create_example_data_full()}\n        print(yaml.dump(data, default_flow_style=False))\n\n    def _parse_and_execute_csv(self, filepath):\n        with open(filepath, 'r') as stream:\n            # dialect = csv.Sniffer().sniff(stream.read(1024))  # check which type of formating the csv file likel has\n            # stream.seek(0)\n\n            reader = csv.DictReader(stream, dialect=csv.excel)  # parse file\n\n            for row in reader:\n                # we wan't to remove spaces before and after the fields\n                kwargs = {}\n                for k, v in row.items():\n                    kwargs[k.strip()] = v.strip()\n\n                self._execute_script(**kwargs)  # now we can execute the script\n\n    def _print_example_csv(self):\n        writer = csv.DictWriter(sys.stdout, fieldnames=self._params.keys())\n\n        writer.writeheader()\n        writer.writerow(self._create_example_data_required(include_name=True))\n        writer.writerow(self._create_example_data_full(include_name=True))\n\n    def _execute_script(self, **kwargs):\n        parsed_args = {}\n        error = False\n\n        for k, v in self._params.items():\n            try:\n                if kwargs.get(k) not in [None, '']:\n                    parsed_args[k] = v.get('type', str)(kwargs[k])\n                elif v.get('required', False):\n                    raise ParserException(\"parameter expected: {}\".format(k))\n                else:\n                    type = v.get('type', str)\n                    if type is bool:\n                        parsed_args[k] = type(v.get('default', False))\n                    elif type is int:\n                        parsed_args[k] = type(v.get('default', 0))\n                    elif type is float:\n                        parsed_args[k] = type(v.get('default', 0.0))\n                    elif type is str:\n                        parsed_args[k] = type(v.get('default', ''))\n                    else:\n                        parsed_args[k] = type(v.get('default'))\n            except (ValueError, ParserException) as e:\n                error = True\n                print(\"ERROR: {}\".format(e))\n\n        print(\"  - generate {name}.kicad_mod\".format(name=kwargs.get('name', '<anon>')))\n\n        if error:\n            return\n\n        self._footprint_function(parsed_args)\n"
  },
  {
    "path": "KicadModTree/Point.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016-2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport warnings\n\nfrom KicadModTree.util.kicad_util import formatFloat\nfrom KicadModTree.Vector import *\nfrom math import sqrt\n\n\nclass Point2D(Vector2D):\n    def __init__(self, coordinates=None, y=None):\n        Vector2D.__init__(self, coordinates, y)\n        warnings.warn(\n            \"Point2D is deprecated, use Vector2D instead\",\n            DeprecationWarning\n        )\n\n\nclass Point3D(Vector3D):\n    def __init__(self, coordinates=None, y=None, z=None):\n        Vector3D.__init__(self, coordinates, y, z)\n        warnings.warn(\n            \"Point3D is deprecated, use Vector3D instead\",\n            DeprecationWarning\n        )\n\n\nclass Point(Vector3D):\n    def __init__(self, coordinates=None, y=None, z=None):\n        Vector3D.__init__(self, coordinates, y, z)\n        warnings.warn(\n            \"Point is deprecated, use Vector2D or Vector3D instead\",\n            DeprecationWarning\n        )\n"
  },
  {
    "path": "KicadModTree/PolygonPoints.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016-2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n# (C) 2018 by Rene Poeschl, github @poeschlr\n\nimport warnings\n\nfrom KicadModTree.Vector import Vector2D\nfrom KicadModTree.nodes.Node import Node\n\n\nclass PolygonPoints(object):\n    r\"\"\"Representation of multiple points for creating polygons\n\n    :Keyword Arguments:\n        * *nodes* (``list(Point)``) --\n          2D points describing the \"polygon\"\n        * *polygone* (``list(Point)``) --\n          alternative naming for the nodes parameter for backwards compatibility.\n        * *x_mirror* (``[int, float](mirror offset)``) --\n          mirror x direction around offset \"point\"\n        * *y_mirror* (``[int, float](mirror offset)``) --\n          mirror y direction around offset \"point\"\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> PolyPoint([(0, 0),(1, 0)])\n    >>> PolyPoint([{'x': 0, 'y':0}, {'x': 1, 'y':0}])\n    \"\"\"\n    def __init__(self, **kwargs):\n        self._initMirror(**kwargs)\n        self._initNodes(**kwargs)\n\n    def _initNodes(self, **kwargs):\n        self.nodes = []\n        if 'nodes' in kwargs:\n            for n in kwargs['nodes']:\n                self.nodes.append(Vector2D(n))\n            if 'polygone' in kwargs:\n                raise KeyError('Use of \"nodes\" and \"polygone\" parameter at the same time is not supported.')\n        elif 'polygone' in kwargs:\n            warnings.warn(\n                \"polygone argument is deprecated, use nodes instead\",\n                DeprecationWarning\n            )\n            for n in kwargs['polygone']:\n                self.nodes.append(Vector2D(n))\n        else:\n            raise KeyError('Either \"nodes\" or \"polygone\" parameter is required for creating a PolyPoint instance.')\n\n        for point in self.nodes:\n            if self.mirror[0] is not None:\n                point.x = 2 * self.mirror[0] - point.x\n            if self.mirror[1] is not None:\n                point.y = 2 * self.mirror[1] - point.y\n\n    def _initMirror(self, **kwargs):\n        self.mirror = [None, None]\n        if 'x_mirror' in kwargs and type(kwargs['x_mirror']) in [float, int]:\n            self.mirror[0] = kwargs['x_mirror']\n        if 'y_mirror' in kwargs and type(kwargs['y_mirror']) in [float, int]:\n            self.mirror[1] = kwargs['y_mirror']\n\n    def calculateBoundingBox(self):\n        min = max = self.getRealPosition(self.nodes[0])\n\n        for n in self.nodes:\n            min.x = min([min.x, n.x])\n            min.y = min([min.y, n.y])\n            max.x = max([max.x, n.x])\n            max.y = max([max.y, n.y])\n\n        return Node.calculateBoundingBox({'min': min, 'max': max})\n\n    def findNearestPoints(self, other):\n        r\"\"\" Find the nearest points for two polygons\n\n        Find the two points for both polygons that are nearest to each other.\n\n\n        :param other: the polygon points of the other polygon\n        :return: a tuble with the indexes of the two points\n                 (pint in self, point in other)\n        \"\"\"\n\n        min_distance = self[0].distance_to(other[0])\n        pi = 0\n        pj = 0\n        for i in range(len(self)):\n            for j in range(len(other)):\n                d = self[i].distance_to(other[j])\n                if d < min_distance:\n                    pi = i\n                    pj = j\n                    min_distance = d\n\n        return (pi, pj)\n\n    def getPoints(self):\n        r\"\"\" get the points contained within self\n\n        :return: the array of points contained within this instance\n        \"\"\"\n        return self.nodes\n\n    def cut(self, other):\n        r\"\"\" Cut other polygon points from self\n\n        As kicad has no native support for cuting one polygon from the other,\n        the cut is done by connecting the nearest points of the two polygons\n        with two lines on top of each other.\n\n        This function assumes that the other polygon is fully within this one.\n        It also assumes that connecting the two nearest points creates a valid\n        polygon. (There are no geometry checks)\n\n        :param other: the polygon points that are cut from this polygon\n        \"\"\"\n\n        warnings.warn(\n            \"No geometry checks are implement for cutting polygons.\\n\"\n            \"Make sure the second polygon is fully inside the main polygon\\n\"\n            \"Check resulting polygon carefully.\",\n            Warning\n        )\n        idx_self, idx_other = self.findNearestPoints(other)\n\n        self.nodes.insert(idx_self+1, self[idx_self])\n        for i in range(len(other)):\n            self.nodes.insert(idx_self+1, other[(i+idx_other) % len(other)])\n\n        self.nodes.insert(idx_self+1, other[idx_other])\n\n    def rotate(self, angle, origin=(0, 0), use_degrees=True):\n        r\"\"\" Rotate points around given origin\n\n        :params:\n            * *angle* (``float``)\n                rotation angle\n            * *origin* (``Vector2D``)\n                origin point for the rotation. default: (0, 0)\n            * *use_degrees* (``boolean``)\n                rotation angle is given in degrees. default:True\n        \"\"\"\n\n        for p in self.nodes:\n            p.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        return self\n\n    def translate(self, distance_vector):\n        r\"\"\" Translate points\n\n        :params:\n            * *distance_vector* (``Vector2D``)\n                2D vector defining by how much and in what direction to translate.\n        \"\"\"\n\n        for p in self.nodes:\n            p += distance_vector\n        return self\n\n    def __copy__(self):\n        return PolygonPoints(nodes=self.nodes)\n\n    def __iter__(self):\n        for n in self.nodes:\n            yield n\n\n    def __getitem__(self, idx):\n        return self.nodes[idx]\n\n    def __len__(self):\n        return len(self.nodes)\n"
  },
  {
    "path": "KicadModTree/Vector.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016-2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom __future__ import division\nfrom builtins import round\n\nimport warnings\n\nfrom KicadModTree.util.kicad_util import formatFloat\nfrom math import sqrt, sin, cos, hypot, atan2, degrees, radians\n\n\nclass Vector2D(object):\n    r\"\"\"Representation of a 2D Vector in space\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> Vector2D(0, 0)\n    >>> Vector2D([0, 0])\n    >>> Vector2D((0, 0))\n    >>> Vector2D({'x': 0, 'y':0})\n    >>> Vector2D(Vector2D(0, 0))\n    \"\"\"\n    def __init__(self, coordinates=None, y=None):\n        # parse constructor\n        if coordinates is None:\n            coordinates = {}\n        elif type(coordinates) in [int, float]:\n            if y is not None:\n                coordinates = [coordinates, y]\n            else:\n                raise TypeError('you have to give x and y coordinate')\n        elif isinstance(coordinates, Vector2D):\n            # convert Vector2D as well as Vector3D to dict\n            coordinates = coordinates.to_dict()\n\n        # parse vectors with format: Vector2D({'x':0, 'y':0})\n        if type(coordinates) is dict:\n            self.x = float(coordinates.get('x', 0.))\n            self.y = float(coordinates.get('y', 0.))\n            return\n\n        # parse vectors with format: Vector2D([0, 0]) or Vector2D((0, 0))\n        if type(coordinates) in [list, tuple]:\n            if len(coordinates) == 2:\n                self.x = float(coordinates[0])\n                self.y = float(coordinates[1])\n                return\n            else:\n                raise TypeError('invalid list size (2 elements expected)')\n\n        raise TypeError('invalid parameters given')\n\n    def round_to(self, base):\n        r\"\"\"Round to a specific base (like it's required for a grid)\n\n        :param base: base we want to round to\n        :return: rounded point\n\n        >>> from KicadModTree import *\n        >>> Vector2D(0.1234, 0.5678).round_to(0.01)\n        \"\"\"\n        if base == 0 or base is None:\n            return self.__copy__()\n\n        return Vector2D([round(v / base) * base for v in self])\n\n    def distance_to(self, value):\n        r\"\"\"Distance between this and another point\n\n        :param value: the other point\n        :return: distance between self and other point\n        \"\"\"\n        other = Vector2D.__arithmetic_parse(value)\n        d = other - self\n        return hypot(d.x, d.y)\n\n    @staticmethod\n    def __arithmetic_parse(value):\n        if isinstance(value, Vector2D):\n            return value\n        elif type(value) in [int, float]:\n            return Vector2D([value, value])\n        else:\n            return Vector2D(value)\n\n    def __eq__(self, other):\n        if not isinstance(self, other.__class__):\n            return False\n        return self.x == other.x and self.y == other.y\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n    def __add__(self, value):\n        other = Vector2D.__arithmetic_parse(value)\n\n        return Vector2D({'x': self.x + other.x,\n                         'y': self.y + other.y})\n\n    def __iadd__(self, value):\n        other = Vector2D.__arithmetic_parse(value)\n        self.x += other.x\n        self.y += other.y\n\n        return self\n\n    def __neg__(self):\n        return Vector2D({'x': -self.x, 'y': -self.y})\n\n    def __sub__(self, value):\n        other = Vector2D.__arithmetic_parse(value)\n\n        return Vector2D({'x': self.x - other.x,\n                         'y': self.y - other.y})\n\n    def __isub__(self, value):\n        other = Vector2D.__arithmetic_parse(value)\n        self.x -= other.x\n        self.y -= other.y\n\n        return self\n\n    def __mul__(self, value):\n        other = Vector2D.__arithmetic_parse(value)\n\n        return Vector2D({'x': self.x * other.x,\n                         'y': self.y * other.y})\n\n    def __div__(self, value):\n        other = Vector2D.__arithmetic_parse(value)\n\n        return Vector2D({'x': self.x / other.x,\n                         'y': self.y / other.y})\n\n    def __truediv__(self, obj):\n        return self.__div__(obj)\n\n    def to_dict(self):\n        return {'x': self.x, 'y': self.y}\n\n    def render(self, formatcode):\n        warnings.warn(\n            \"render is deprecated, read values directly instead\",\n            DeprecationWarning\n        )\n        return formatcode.format(x=formatFloat(self.x),\n                                 y=formatFloat(self.y))\n\n    def __repr__(self):\n        return \"Vector2D (x={x}, y={y})\".format(**self.to_dict())\n\n    def __str__(self):\n        return \"(x={x}, y={y})\".format(**self.to_dict())\n\n    def __getitem__(self, key):\n        if key == 0 or key == 'x':\n            return self.x\n        if key == 1 or key == 'y':\n            return self.y\n\n        raise IndexError('Index {} is out of range'.format(key))\n\n    def __setitem__(self, key, item):\n        if key == 0 or key == 'x':\n            self.x = item\n        elif key == 1 or key == 'y':\n            self.y = item\n        else:\n            raise IndexError('Index {} is out of range'.format(key))\n\n    def __len__(self):\n        return 2\n\n    def __iter__(self):\n        yield self.x\n        yield self.y\n\n    def __copy__(self):\n        return Vector2D(self.x, self.y)\n\n    def rotate(self, angle, origin=(0, 0), use_degrees=True):\n        r\"\"\" Rotate vector around given origin\n\n        :params:\n            * *angle* (``float``)\n                rotation angle\n            * *origin* (``Vector2D``)\n                origin point for the rotation. default: (0, 0)\n            * *use_degrees* (``boolean``)\n                rotation angle is given in degrees. default:True\n        \"\"\"\n\n        op = Vector2D(origin)\n\n        if use_degrees:\n            angle = radians(angle)\n\n        temp = op.x + cos(angle) * (self.x - op.x) - sin(angle) * (self.y - op.y)\n        self.y = op.y + sin(angle) * (self.x - op.x) + cos(angle) * (self.y - op.y)\n        self.x = temp\n\n        return self\n\n    def to_polar(self, origin=(0, 0), use_degrees=True):\n        r\"\"\" Get polar representation of the vector\n\n        :params:\n            * *origin* (``Vector2D``)\n                origin point for polar conversion. default: (0, 0)\n            * *use_degrees* (``boolean``)\n                angle in degrees. default:True\n        \"\"\"\n\n        op = Vector2D(origin)\n\n        diff = self - op\n        radius = hypot(diff.x, diff.y)\n\n        angle = atan2(diff.y, diff.x)\n        if use_degrees:\n            angle = degrees(angle)\n\n        return (radius, angle)\n\n    @staticmethod\n    def from_polar(radius, angle, origin=(0, 0), use_degrees=True):\n        r\"\"\" Generate a vector from its polar representation\n\n        :params:\n            * *radius* (``float``)\n                lenght of the vector\n            * *angle* (``float``)\n                angle of the vector\n            * *origin* (``Vector2D``)\n                origin point for polar conversion. default: (0, 0)\n            * *use_degrees* (``boolean``)\n                angle in degrees. default:True\n        \"\"\"\n\n        if use_degrees:\n            angle = radians(angle)\n\n        x = radius * cos(angle)\n        y = radius * sin(angle)\n\n        return Vector2D({'x': x, 'y': y})+Vector2D(origin)\n\n    def to_homogeneous(self):\n        r\"\"\" Get homogeneous representation\n        \"\"\"\n\n        return Vector3D(self.x, self.y, 1)\n\n    @staticmethod\n    def from_homogeneous(source):\n        r\"\"\" Recover 2d vector from its homogeneous representation\n\n        :params:\n            * *source* (``Vector3D``)\n                3d homogeneous representation\n        \"\"\"\n\n        return Vector2D(source.x/source.z, source.y/source.z)\n\n\nclass Vector3D(Vector2D):\n    r\"\"\"Representation of a 3D Vector in space\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> Vector3D(0, 0, 0)\n    >>> Vector3D([0, 0, 0])\n    >>> Vector3D((0, 0, 0))\n    >>> Vector3D({'x': 0, 'y':0, 'z':0})\n    >>> Vector3D(Vector2D(0, 0))\n    >>> Vector3D(Vector3D(0, 0, 0))\n    \"\"\"\n\n    def __init__(self, coordinates=None, y=None, z=None):\n        # we don't need a super constructor here\n\n        # parse constructor\n        if coordinates is None:\n            coordinates = {}\n        elif type(coordinates) in [int, float]:\n            if y is not None:\n                if z is not None:\n                    coordinates = [coordinates, y, z]\n                else:\n                    coordinates = [coordinates, y]\n            else:\n                raise TypeError('you have to give at least x and y coordinate')\n        elif isinstance(coordinates, Vector2D):\n            # convert Vector2D as well as Vector3D to dict\n            coordinates = coordinates.to_dict()\n\n        # parse vectors with format: Vector2D({'x':0, 'y':0})\n        if type(coordinates) is dict:\n            self.x = float(coordinates.get('x', 0.))\n            self.y = float(coordinates.get('y', 0.))\n            self.z = float(coordinates.get('z', 0.))\n            return\n\n        # parse vectors with format: Vector3D([0, 0]), Vector3D([0, 0, 0]) or Vector3D((0, 0)), Vector3D((0, 0, 0))\n        if type(coordinates) in [list, tuple]:\n            if len(coordinates) >= 2:\n                self.x = float(coordinates[0])\n                self.y = float(coordinates[1])\n            else:\n                raise TypeError('invalid list size (to small)')\n\n            if len(coordinates) == 3:\n                self.z = float(coordinates[2])\n            else:\n                self.z = 0.\n\n            if len(coordinates) > 3:\n                raise TypeError('invalid list size (to big)')\n\n        else:\n            raise TypeError('dict or list type required')\n\n    def round_to(self, base):\n        r\"\"\"Round to a specific base (like it's required for a grid)\n\n        :param base: base we want to round to\n        :return: rounded point\n\n        >>> from KicadModTree import *\n        >>> Vector3D(0.123, 0.456, 0.789).round_to(0.01)\n        \"\"\"\n        if base == 0 or base is None:\n            return self.__copy__()\n\n        return Vector3D([round(v / base) * base for v in self])\n\n    def cross_product(self, other):\n        other = Vector3D.__arithmetic_parse(other)\n\n        return Vector3D({\n                    'x': self.y*other.z - self.z*other.y,\n                    'y': self.z*other.x - self.x*other.z,\n                    'z': self.x*other.y - self.y*other.x})\n\n    def dot_product(self, other):\n        other = Vector3D.__arithmetic_parse(other)\n\n        return self.x*other.x + self.y*other.y + self.z*other.z\n\n    @staticmethod\n    def __arithmetic_parse(value):\n        if isinstance(value, Vector3D):\n            return value\n        elif type(value) in [int, float]:\n            return Vector3D([value, value, value])\n        else:\n            return Vector3D(value)\n\n    def __eq__(self, other):\n        if not isinstance(self, other.__class__):\n            return False\n        return self.x == other.x and self.y == other.y and self.z == other.z\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n    def __add__(self, value):\n        other = Vector3D.__arithmetic_parse(value)\n\n        return Vector3D({'x': self.x + other.x,\n                         'y': self.y + other.y,\n                         'z': self.z + other.z})\n\n    def __iadd__(self, value):\n        other = Vector2D.__arithmetic_parse(value)\n        self.x += other.x\n        self.y += other.y\n        self.z += other.z\n\n        return self\n\n    def __neg__(self):\n        return Vector2D({'x': -self.x,\n                         'y': -self.y,\n                         'z': -self.z})\n\n    def __sub__(self, value):\n        other = Vector3D.__arithmetic_parse(value)\n\n        return Vector3D({'x': self.x - other.x,\n                         'y': self.y - other.y,\n                         'z': self.z - other.z})\n\n    def __isub__(self, value):\n        other = Vector2D.__arithmetic_parse(value)\n        self.x -= other.x\n        self.y -= other.y\n        self.z -= other.z\n\n        return self\n\n    def __mul__(self, value):\n        other = Vector3D.__arithmetic_parse(value)\n\n        return Vector3D({'x': self.x * other.x,\n                         'y': self.y * other.y,\n                         'z': self.z * other.z})\n\n    def __div__(self, value):\n        other = Vector3D.__arithmetic_parse(value)\n\n        return Vector3D({'x': self.x / other.x,\n                         'y': self.y / other.y,\n                         'z': self.z / other.z})\n\n    def __truediv__(self, obj):\n        return self.__div__(obj)\n\n    def to_dict(self):\n        return {'x': self.x, 'y': self.y, 'z': self.z}\n\n    def render(self, formatcode):\n        warnings.warn(\n            \"render is deprecated, read values directly instead\",\n            DeprecationWarning\n        )\n        return formatcode.format(x=formatFloat(self.x),\n                                 y=formatFloat(self.y),\n                                 z=formatFloat(self.z))\n\n    def __repr__(self):\n        return \"Vector3D (x={x}, y={y}, z={z})\".format(**self.to_dict())\n\n    def __str__(self):\n        return \"(x={x}, y={y}, z={z})\".format(**self.to_dict())\n\n    def __getitem__(self, key):\n        if key == 0 or key == 'x':\n            return self.x\n        if key == 1 or key == 'y':\n            return self.y\n        if key == 2 or key == 'z':\n            return self.z\n\n        raise IndexError('Index {} is out of range'.format(key))\n\n    def __setitem__(self, key, item):\n        if key == 0 or key == 'x':\n            self.x = item\n        elif key == 1 or key == 'y':\n            self.y = item\n        elif key == 2 or key == 'z':\n            self.z = item\n        else:\n            raise IndexError('Index {} is out of range'.format(key))\n\n    def __len__(self):\n        return 3\n\n    def __iter__(self):\n        yield self.x\n        yield self.y\n        yield self.z\n\n    def __copy__(self):\n        return Vector3D(self.x, self.y, self.z)\n"
  },
  {
    "path": "KicadModTree/__init__.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.Point import *  # backwards compatibility\n\n# all different types of nodes\nfrom KicadModTree.nodes import *\n\n# File Handlers\nfrom KicadModTree.KicadFileHandler import KicadFileHandler\n\n# Argparser\nfrom KicadModTree.ModArgparser import ModArgparser\n"
  },
  {
    "path": "KicadModTree/examples/__init__.py",
    "content": "'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n"
  },
  {
    "path": "KicadModTree/examples/argparse_example.py",
    "content": "#!/usr/bin/env python\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\n\nsys.path.append(os.path.join(sys.path[0], \"../..\"))  # enable package import from parent directory\n\nfrom KicadModTree import *  # NOQA\n\n\ndef example_footprint(args):\n    print(\"now we can create a footprint using the following parameters:\")\n    print(args)\n\n\nif __name__ == '__main__':\n    parser = ModArgparser(example_footprint)\n    parser.add_parameter(\"name\", type=str, required=True)  # the root node of .yml files is parsed as name\n    parser.add_parameter(\"datasheet\", type=str, required=False)\n    parser.add_parameter(\"courtyard\", type=float, required=False, default=0.25)\n    parser.add_parameter(\"diameter\", type=float, required=True)\n    parser.add_parameter(\"pad_length\", type=float, required=True)\n    parser.add_parameter(\"pad_width\", type=float, required=True)\n\n    parser.run()  # now run our script which handles the whole part of parsing the files\n"
  },
  {
    "path": "KicadModTree/examples/padArrayWithOutline.py",
    "content": "#!/usr/bin/env python\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2017 by @SchrodingersGat\n# (C) 2017 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nsys.path.append('../..')  # enable package import from parent directory\n\nfrom KicadModTree import *  # NOQA\n\nif __name__ == '__main__':\n    footprint_name = \"pad_array_footprint\"\n\n    # Init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"An example footprint\")\n    kicad_mod.setTags(\"example\")\n\n    # Set general values\n    kicad_mod.append(Text(type='reference', text='REF**', at=[0, -3], layer='F.SilkS'))\n    kicad_mod.append(Text(type='value', text=footprint_name, at=[1.5, 3], layer='F.Fab'))\n\n    # Add model\n    kicad_mod.append(Model(filename=\"example.3dshapes/example_footprint.wrl\",\n                           at=[0, 0, 0],\n                           scale=[1, 1, 1],\n                           rotate=[0, 0, 0]))\n\n    # Create a pad array with a large horizontal spacing, and a smaller vertical spacing\n    # centered at the origin\n    pa = PadArray(pincount=10,\n                  spacing=[2.54, -0.2],\n                  center=[0, 0],\n                  initial=5,\n                  increment=2,\n                  type=Pad.TYPE_SMT,\n                  shape=Pad.SHAPE_RECT,\n                  size=[1, 2],\n                  layers=Pad.LAYERS_SMT)\n\n    kicad_mod.append(pa)\n\n    # Calculate the border of the pad array\n    border = pa.calculateOutline()\n\n    # Create a courtyard around the pad array\n    kicad_mod.append(RectLine(start=border['min'], end=border['max'], layer='F.Fab', width=0.05, offset=0.5))\n\n    # Write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('example_footprint.kicad_mod')\n"
  },
  {
    "path": "KicadModTree/examples/params.csv",
    "content": "name,        diameter,    pad_length,      pad_width\n10x2x5,10,2,5\n15x2x5,15,2,5\n18x2x5,18,2,5\n\"Jsjdlfmlakefjsl , asldl\",13,5,2.5\n"
  },
  {
    "path": "KicadModTree/examples/params.yml",
    "content": "asdf:\n  diameter: 10\n  pad_length: 3\n  pad_width: 7"
  },
  {
    "path": "KicadModTree/examples/polygon.py",
    "content": "#!/usr/bin/env python\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\n\nsys.path.append(os.path.join(sys.path[0], \"../..\"))  # enable package import from parent directory\n\nfrom KicadModTree import *  # NOQA\n\n\nif __name__ == '__main__':\n    footprint_name = \"example_footprint\"\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"A example footprint\")\n    kicad_mod.setTags(\"example\")\n\n    # set general values\n    kicad_mod.append(Text(type='reference', text='REF**', at=[0, -3], layer='F.SilkS'))\n    kicad_mod.append(Text(type='value', text=footprint_name, at=[1.5, 3], layer='F.Fab'))\n\n    # create polygon\n    kicad_mod.append(Polygon(nodes=[[-2, 0], [0, -2], [4, 0], [0, 2], [-2, 0], [0, -2], [4, 0], [0, 2]],\n                             layer='F.SilkS'))\n\n    # print render tree\n    print(kicad_mod.getCompleteRenderTree())\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('example_footprint.kicad_mod')\n"
  },
  {
    "path": "KicadModTree/examples/simpleFootprint.py",
    "content": "#!/usr/bin/env python\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\n\nsys.path.append(os.path.join(sys.path[0], \"../..\"))  # enable package import from parent directory\n\nfrom KicadModTree import *  # NOQA\n\n\nif __name__ == '__main__':\n    footprint_name = \"example_footprint\"\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"A example footprint\")\n    kicad_mod.setTags(\"example\")\n\n    # set general values\n    kicad_mod.append(Text(type='reference', text='REF**', at=[0, -3], layer='F.SilkS'))\n    kicad_mod.append(Text(type='value', text=footprint_name, at=[1.5, 3], layer='F.Fab'))\n\n    # create silkscreen\n    kicad_mod.append(RectLine(start=[-2, -2], end=[5, 2], layer='F.SilkS'))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-2.25, -2.25], end=[5.25, 2.25], layer='F.CrtYd'))\n\n    # create pads\n    kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n                         at=[0, 0], size=[2, 2], drill=1.2, layers=Pad.LAYERS_THT))\n    kicad_mod.append(Pad(number=2, type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n                         at=[3, 0], size=[2, 2], drill=1.2, layers=Pad.LAYERS_THT))\n\n    # add model\n    kicad_mod.append(Model(filename=\"example.3dshapes/example_footprint.wrl\",\n                           at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n\n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    print(kicad_mod.getCompleteRenderTree())\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('example_footprint.kicad_mod')\n"
  },
  {
    "path": "KicadModTree/nodes/Footprint.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\n\n\n'''\nThis is my new approach, using a render tree for footprint generation.\n\nADVANTAGES:\n\n* simple point transformations\n* automatic calculation of courtjard,...\n* simple duplication of rendering structures\n\n'''\n\n# define in which order the general \"lisp\" operators are arranged\nrender_order = ['descr', 'tags', 'attr', 'solder_mask_margin',\n                'solder_paste_margin', 'solder_paste_ratio', 'fp_text',\n                'fp_circle', 'fp_line', 'pad', 'model']\n# TODO: sort Text by type\n\n\nclass Footprint(Node):\n    '''\n    Root Node to generate KicadMod\n    '''\n    def __init__(self, name):\n        Node.__init__(self)\n\n        self.name = name\n        self.description = None\n        self.tags = None\n        self.attribute = None\n        self.maskMargin = None\n        self.pasteMargin = None\n        self.pasteMarginRatio = None\n\n    def setName(self, name):\n        self.name = name\n\n    def setDescription(self, description):\n        self.description = description\n\n    def setTags(self, tags):\n        self.tags = tags\n\n    def setAttribute(self, value):\n        self.attribute = value\n\n    def setMaskMargin(self, value):\n        self.maskMargin = value\n\n    def setPasteMargin(self, value):\n        self.pasteMargin = value\n\n    def setPasteMarginRatio(self, value):\n        # paste_margin_ratio is unitless between 0 and 1 while GUI uses percentage\n        assert abs(value) <= 1, \"Solder paste margin must be between -1 and 1. {} is too large.\".format(value)\n\n        self.pasteMarginRatio = value\n"
  },
  {
    "path": "KicadModTree/nodes/Node.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom copy import copy, deepcopy\n\nfrom KicadModTree.Vector import *\n\n\nclass MultipleParentsError(RuntimeError):\n    def __init__(self, message):\n\n        # Call the base class constructor with the parameters it needs\n        super(MultipleParentsError, self).__init__(message)\n\n\nclass RecursionDetectedError(RuntimeError):\n    def __init__(self, message):\n\n        # Call the base class constructor with the parameters it needs\n        super(RecursionDetectedError, self).__init__(message)\n\n\nclass Node(object):\n    def __init__(self):\n        self._parent = None\n        self._childs = []\n\n    def append(self, node):\n        '''\n        add node to child\n        '''\n        if not isinstance(node, Node):\n            raise TypeError('invalid object, has to be based on Node')\n\n        if node._parent:\n            raise MultipleParentsError('muliple parents are not allowed!')\n\n        self._childs.append(node)\n\n        node._parent = self\n\n    def extend(self, nodes):\n        '''\n        add list of nodes to child\n        '''\n        new_nodes = []\n        for node in nodes:\n            if not isinstance(node, Node):\n                raise TypeError('invalid object, has to be based on Node')\n\n            if node._parent or node in new_nodes:\n                raise MultipleParentsError('muliple parents are not allowed!')\n\n            new_nodes.append(node)\n\n        # when all went smooth by now, we can set the parent nodes to ourself\n        for node in new_nodes:\n            node._parent = self\n\n        self._childs.extend(new_nodes)\n\n    def remove(self, node):\n        '''\n        remove child from node\n        '''\n        if not isinstance(node, Node):\n            raise TypeError('invalid object, has to be based on Node')\n\n        while node in self._childs:\n            self._childs.remove(node)\n\n        node._parent = None\n\n    def insert(self, node):\n        '''\n        moving all childs into the node, and using the node as new parent of those childs\n        '''\n        if not isinstance(node, Node):\n            raise TypeError('invalid object, has to be based on Node')\n\n        for child in copy(self._childs):\n            self.remove(child)\n            node.append(child)\n\n        self.append(node)\n\n    def copy(self):\n        copy = deepcopy(self)\n        copy._parent = None\n        return copy\n\n    def serialize(self):\n        nodes = [self]\n        for child in self.getAllChilds():\n            nodes += child.serialize()\n        return nodes\n\n    def getNormalChilds(self):\n        '''\n        Get all normal childs of this node\n        '''\n        return self._childs\n\n    def getVirtualChilds(self):\n        '''\n        Get virtual childs of this node\n        '''\n        return []\n\n    def getAllChilds(self):\n        '''\n        Get virtual and normal childs of this node\n        '''\n        return self.getNormalChilds() + self.getVirtualChilds()\n\n    def getParent(self):\n        '''\n        get Parent Node of this Node\n        '''\n        return self._parent\n\n    def getRootNode(self):\n        '''\n        get Root Node of this Node\n        '''\n\n        # TODO: recursion detection\n        if not self.getParent():\n            return self\n\n        return self.getParent().getRootNode()\n\n    def getRealPosition(self, coordinate, rotation=None):\n        '''\n        return position of point after applying all transformation and rotation operations\n        '''\n        if not self._parent:\n            if rotation is None:\n                # TODO: most of the points are 2D Nodes\n                return Vector3D(coordinate)\n            else:\n                return Vector3D(coordinate), rotation\n\n        return self._parent.getRealPosition(coordinate, rotation)\n\n    def calculateBoundingBox(self, outline=None):\n        min_x, min_y = 0, 0\n        max_x, max_y = 0, 0\n\n        if outline:\n            min_x = outline['min']['x']\n            min_y = outline['min']['y']\n            max_x = outline['max']['x']\n            max_y = outline['max']['y']\n\n        for child in self.getAllChilds():\n            child_outline = child.calculateBoundingBox()\n\n            min_x = min([min_x, child_outline['min']['x']])\n            min_y = min([min_y, child_outline['min']['y']])\n            max_x = max([max_x, child_outline['max']['x']])\n            max_y = max([max_y, child_outline['max']['y']])\n\n        return {'min': Vector2D(min_x, min_y), 'max': Vector2D(max_x, max_y)}\n\n    def _getRenderTreeText(self):\n        '''\n        Text which is displayed when generating a render tree\n        '''\n        return type(self).__name__\n\n    def _getRenderTreeSymbol(self):\n        '''\n        Symbol which is displayed when generating a render tree\n        '''\n        if self._parent is None:\n            return \"+\"\n\n        return \"*\"\n\n    def getRenderTree(self, rendered_nodes=None):\n        '''\n        print render tree\n        '''\n        if rendered_nodes is None:\n            rendered_nodes = set()\n\n        if self in rendered_nodes:\n            raise RecursionDetectedError('recursive definition of render tree!')\n\n        rendered_nodes.add(self)\n\n        tree_str = \"{0} {1}\".format(self._getRenderTreeSymbol(), self._getRenderTreeText())\n        for child in self.getNormalChilds():\n            tree_str += '\\n  '\n            tree_str += '  '.join(child.getRenderTree(rendered_nodes).splitlines(True))\n\n        return tree_str\n\n    def getCompleteRenderTree(self, rendered_nodes=None):\n        '''\n        print virtual render tree\n        '''\n        if rendered_nodes is None:\n            rendered_nodes = set()\n\n        if self in rendered_nodes:\n            raise RecursionDetectedError('recursive definition of render tree!')\n\n        rendered_nodes.add(self)\n\n        tree_str = \"{0} {1}\".format(self._getRenderTreeSymbol(), self._getRenderTreeText())\n        for child in self.getAllChilds():\n            tree_str += '\\n  '\n            tree_str += '  '.join(child.getCompleteRenderTree(rendered_nodes).splitlines(True))\n\n        return tree_str\n"
  },
  {
    "path": "KicadModTree/nodes/__init__.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\n# generic node\nfrom .Node import Node, MultipleParentsError, RecursionDetectedError\n\n# root node\nfrom .Footprint import Footprint\n\nfrom .base import *\nfrom .specialized import *\n"
  },
  {
    "path": "KicadModTree/nodes/base/Arc.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\nimport math\nfrom KicadModTree.util.geometric_util import geometricArc, BaseNodeIntersection\n\n\nclass Arc(Node, geometricArc):\n    r\"\"\"Add an Arc to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *geometry* (``geometricArc``)\n          alternative to using geometric parameters\n        * *center* (``Vector2D``) --\n          center of arc\n        * *start* (``Vector2D``) --\n          start point of arc\n        * *midpoint* (``Vector2D``) --\n          alternative to start point\n          point is on arc and defines point of equal distance to both arc ends\n          arcs of this form are given as midpoint, center plus angle\n        * *end* (``Vector2D``) --\n          alternative to angle\n          arcs of this form are given as start, end and center\n        * *angle* (``float``) --\n          angle of arc\n        * *layer* (``str``) --\n          layer on which the arc is drawn (default: 'F.SilkS')\n        * *width* (``float``) --\n          width of the arc line (default: None, which means auto detection)\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> Arc(center=[0, 0], start=[-1, 0], angle=180, layer='F.SilkS')\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        geometricArc.__init__(self, **kwargs)\n\n        self.layer = kwargs.get('layer', 'F.SilkS')\n        self.width = kwargs.get('width')\n\n    def copyReplaceGeometry(self, geometry):\n        return Arc(geometry=geometry, layer=self.layer, width=self.width)\n\n    def copy(self):\n        return Arc(\n            center=self.center_pos, start=self.start_pos, angle=self.angle,\n            layer=self.layer, width=self.width\n            )\n\n    def cut(self, *other):\n        r\"\"\" cut line with given other element\n\n        :params:\n            * *other* (``Line``, ``Circle``, ``Arc``)\n                cut the element on any intersection with the given geometric element\n        \"\"\"\n        result = []\n        garcs = geometricArc.cut(self, *other)\n        for g in garcs:\n            result.append(self.copyReplaceGeometry(g))\n\n        return result\n\n    def calculateBoundingBox(self):\n        # TODO: finish implementation\n        min_x = min(self.start_pos.x, self._calulateEndPos().x)\n        min_y = min(self.start_pos.x, self._calulateEndPos().y)\n        max_x = max(self.start_pos.x, self._calulateEndPos().x)\n        max_y = max(self.start_pos.x, self._calulateEndPos().y)\n\n        '''\n        for angle in range(4):\n            float_angle = angle * math.pi/2.\n\n            start_angle = _calculateStartAngle(self)\n            end_angle = start_angle + math.radians(self.angle)\n\n            # TODO: +- pi border\n            if float_angle < start_angle:\n                continue\n            if float_angle > end_angle:\n                continue\n\n            print(\"TODO: add angle side: {1}\".format(float_angle))\n        '''\n\n        return Node.calculateBoundingBox({'min': Vector2D((min_x, min_y)), 'max': Vector2D((max_x, max_y))})\n\n    def _getRenderTreeText(self):\n        render_strings = ['fp_arc']\n        render_strings.append(self.center_pos.render('(center {x} {y})'))\n        render_strings.append(self.start_pos.render('(start {x} {y})'))\n        render_strings.append('(angle {angle})'.format(angle=self.angle))\n        render_strings.append('(layer {layer})'.format(layer=self.layer))\n        render_strings.append('(width {width})'.format(width=self.width))\n\n        render_text = Node._getRenderTreeText(self)\n        render_text += ' ({})'.format(' '.join(render_strings))\n\n        return render_text\n"
  },
  {
    "path": "KicadModTree/nodes/base/Circle.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\nfrom KicadModTree.util.geometric_util import geometricCircle, BaseNodeIntersection\n\n\nclass Circle(Node, geometricCircle):\n    r\"\"\"Add a Circle to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *center* (``Vector2D``) --\n          center of the circle\n        * *radius* (``float``) --\n          radius of the circle\n        * *layer* (``str``) --\n          layer on which the circle is drawn (default: 'F.SilkS')\n        * *width* (``float``) --\n          width of the circle line (default: None, which means auto detection)\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> Circle(center=[0, 0], radius=1.5, layer='F.SilkS')\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        geometricCircle.__init__(self, Vector2D(kwargs['center']), float(kwargs['radius']))\n\n        self.layer = kwargs.get('layer', 'F.SilkS')\n        self.width = kwargs.get('width')\n\n    def rotate(self, angle, origin=(0, 0), use_degrees=True):\n        r\"\"\" Rotate circle around given origin\n\n        :params:\n            * *angle* (``float``)\n                rotation angle\n            * *origin* (``Vector2D``)\n                origin point for the rotation. default: (0, 0)\n            * *use_degrees* (``boolean``)\n                rotation angle is given in degrees. default:True\n        \"\"\"\n\n        self.center_pos.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        return self\n\n    def translate(self, distance_vector):\n        r\"\"\" Translate circle\n\n        :params:\n            * *distance_vector* (``Vector2D``)\n                2D vector defining by how much and in what direction to translate.\n        \"\"\"\n\n        self.center_pos += distance_vector\n        return self\n\n    def cut(self, *other):\n        raise NotImplemented(\"cut for circles not yet implemented\")\n\n    def getRadius(self):\n        return self.radius\n\n    def calculateBoundingBox(self):\n        min_x = self.center_pos.x-self.radius\n        min_y = self.center_pos.y-self.radius\n        max_x = self.center_pos.x+self.radius\n        max_y = self.center_pos.y+self.radius\n\n        return Node.calculateBoundingBox({'min': ParseXY(min_x, min_y), 'max': ParseXY(max_x, max_y)})\n\n    def _getRenderTreeText(self):\n        render_strings = ['fp_circle']\n        render_strings.append(self.center_pos.render('(center {x} {y})'))\n        render_strings.append(self.end_pos.render('(end {x} {y})'))\n        render_strings.append('(layer {layer})'.format(layer=self.layer))\n        render_strings.append('(width {width})'.format(width=self.width))\n\n        render_text = Node._getRenderTreeText(self)\n        render_text += ' ({})'.format(' '.join(render_strings))\n\n        return render_text\n"
  },
  {
    "path": "KicadModTree/nodes/base/Line.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\nfrom KicadModTree.util.geometric_util import geometricLine, BaseNodeIntersection\n\n\nclass Line(Node, geometricLine):\n    r\"\"\"Add a Line to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *start* (``Vector2D``) --\n          start point of the line\n        * *end* (``Vector2D``) --\n          end point of the line\n        * *layer* (``str``) --\n          layer on which the line is drawn (default: 'F.SilkS')\n        * *width* (``float``) --\n          width of the line (default: None, which means auto detection)\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> Line(start=[1, 0], end=[-1, 0], layer='F.SilkS')\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        if 'geometry' in kwargs:\n            geometry = kwargs['geometry']\n            geometricLine.__init__(self, geometry.start_pos, geometry.end_pos)\n        else:\n            geometricLine.__init__(\n                self,\n                start=Vector2D(kwargs['start']),\n                end=Vector2D(kwargs['end'])\n                )\n\n        self.layer = kwargs.get('layer', 'F.SilkS')\n        self.width = kwargs.get('width')\n\n    def copyReplaceGeometry(self, geometry):\n        return Line(\n            start=geometry.start_pos, end=geometry.end_pos,\n            layer=self.layer, width=self.width\n            )\n\n    def copy(self):\n        return Line(\n            start=self.start_pos, end=self.end_pos,\n            layer=self.layer, width=self.width\n            )\n\n    def cut(self, *other):\n        r\"\"\" cut line with given other element\n\n        :params:\n            * *other* (``Line``, ``Circle``, ``Arc``)\n                cut the element on any intersection with the given geometric element\n        \"\"\"\n        result = []\n        glines = geometricLine.cut(self, *other)\n        for g in glines:\n            result.append(self.copyReplaceGeometry(g))\n\n        return result\n\n    def _getRenderTreeText(self):\n        render_strings = ['fp_line']\n        render_strings.append(self.start_pos.render('(start {x} {y})'))\n        render_strings.append(self.end_pos.render('(end {x} {y})'))\n        render_strings.append('(layer {layer})'.format(layer=self.layer))\n        render_strings.append('(width {width})'.format(width=self.width))\n\n        render_text = Node._getRenderTreeText(self)\n        render_text += ' ({})'.format(' '.join(render_strings))\n\n        return render_text\n\n    def calculateBoundingBox(self):\n        render_start_pos = self.getRealPosition(self.start_pos)\n        render_end_pos = self.getRealPosition(self.end_pos)\n\n        min_x = min([render_start_pos.x, render_end_pos.x])\n        min_y = min([render_start_pos.y, render_end_pos.y])\n        max_x = max([render_start_pos.x, render_end_pos.x])\n        max_y = max([render_start_pos.y, render_end_pos.y])\n\n        return Node.calculateBoundingBox({'min': Vector2D(min_x, min_y), 'max': Vector2D(max_x, max_y)})\n"
  },
  {
    "path": "KicadModTree/nodes/base/Model.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\n\n\nclass Model(Node):\n    r\"\"\"Add a 3D-Model to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *filename* (``str``) --\n          name of the 3d-model file\n        * *at* (``Vector3D``) --\n          position of the model (default: [0, 0, 0])\n        * *scale* (``Vector3D``) --\n          scale of the model (default: [1, 1, 1])\n        * *rotate* (``Vector3D``) --\n          rotation of the model (default: [0, 0, 0])\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> Model(filename=\"example.3dshapes/example_footprint.wrl\",\n    ...       at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0])\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        self.filename = kwargs['filename']\n        self.at = Vector3D(kwargs.get('at', [0, 0, 0]))\n        self.scale = Vector3D(kwargs.get('scale', [1, 1, 1]))\n        self.rotate = Vector3D(kwargs.get('rotate', [0, 0, 0]))\n\n    def _getRenderTreeText(self):\n        render_text = Node._getRenderTreeText(self)\n\n        render_string = ['filename: {filename}'.format(filename=self.filename),\n                         'at: {at}'.format(at=self.at.render('(xyz {x} {y} {z})')),\n                         'scale: {scale}'.format(scale=self.scale.render('(xyz {x} {y} {z})')),\n                         'rotate: {rotate}'.format(rotate=self.rotate.render('(xyz {x} {y} {z})'))]\n\n        render_text += \" [{}]\".format(\", \".join(render_string))\n\n        return render_text\n"
  },
  {
    "path": "KicadModTree/nodes/base/Pad.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n# (C) 2018 by Rene Poeschl, github @poeschlr\n\nfrom KicadModTree.util.paramUtil import *\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\nfrom KicadModTree.util.kicad_util import lispString\nfrom KicadModTree.nodes.base.Arc import Arc\nfrom KicadModTree.nodes.base.Circle import Circle\nfrom KicadModTree.nodes.base.Line import Line\nfrom KicadModTree.nodes.base.Polygon import Polygon\n\n\nclass RoundRadiusHandler(object):\n    r\"\"\"Handles round radius setting of a pad\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n    * *radius_ratio* (``float [0 <= r <= 0.5]``) --\n      The radius ratio of the rounded rectangle. (default set by default_radius_ratio)\n    * *maximum_radius* (``float``) --\n      The maximum radius for the rounded rectangle.\n      If the radius produced by the radius_ratio parameter for the pad would\n      exceed the maximum radius, the ratio is reduced to limit the radius.\n      (This is useful for IPC-7351C compliance as it suggests 25% ratio with limit 0.25mm)\n    * *round_radius_exact* (``float``) --\n      Set an exact round radius for a pad.\n    * *default_radius_ratio* (``float [0 <= r <= 0.5]``) --\n      This parameter allows to set the default radius ratio\n      (backwards compatibility option for chamfered pads)\n    \"\"\"\n    def __init__(self, **kwargs):\n        default_radius_ratio = getOptionalNumberTypeParam(\n                            kwargs, 'default_radius_ratio', default_value=0.25,\n                            low_limit=0, high_limit=0.5)\n        self.radius_ratio = getOptionalNumberTypeParam(\n                            kwargs, 'radius_ratio', default_value=default_radius_ratio,\n                            low_limit=0, high_limit=0.5)\n\n        self.maximum_radius = getOptionalNumberTypeParam(kwargs, 'maximum_radius')\n        self.round_radius_exact = getOptionalNumberTypeParam(kwargs, 'round_radius_exact')\n\n        self.kicad4_compatible = kwargs.get('kicad4_compatible', False)\n\n    def getRadiusRatio(self, shortest_sidelength):\n        r\"\"\"get the resulting round radius ratio\n\n        :param shortest_sidelength: shortest sidelength of a pad\n        :return: the resulting round radius ratio to be used for the pad\n        \"\"\"\n        if self.kicad4_compatible:\n            return 0\n\n        if self.round_radius_exact is not None:\n            if self.round_radius_exact > shortest_sidelength/2:\n                raise ValueError(\n                    \"requested round radius of {} is too large for pad size of {}\"\n                    .format(self.round_radius_exact, pad_size)\n                    )\n            if self.maximum_radius is not None:\n                return min(self.round_radius_exact, self.maximum_radius)/shortest_sidelength\n            else:\n                return self.round_radius_exact/shortest_sidelength\n        if self.maximum_radius is not None:\n            if self.radius_ratio*shortest_sidelength > self.maximum_radius:\n                return self.maximum_radius/shortest_sidelength\n\n        return self.radius_ratio\n\n    def getRoundRadius(self, shortest_sidelength):\n        r\"\"\"get the resulting round radius\n\n        :param shortest_sidelength: shortest sidelength of a pad\n        :return: the resulting round radius to be used for the pad\n        \"\"\"\n        return self.getRadiusRatio(shortest_sidelength)*shortest_sidelength\n\n    def roundingRequested(self):\n        r\"\"\"Check if the pad has a rounded corner\n\n        :return: True if rounded corners are required\n        \"\"\"\n        if self.kicad4_compatible:\n            return False\n\n        if self.maximum_radius == 0:\n            return False\n\n        if self.round_radius_exact == 0:\n            return False\n\n        if self.radius_ratio == 0:\n            return False\n\n        return True\n\n    def limitMaxRadius(self, limit):\n        r\"\"\"Set a new maximum limit\n\n        :param limit: the new limit.\n        \"\"\"\n\n        if not self.roundingRequested():\n            return\n        if self.maximum_radius is not None:\n            self.maximum_radius = min(self.maximum_radius, limit)\n        else:\n            self.maximum_radius = limit\n\n    def __str__(self):\n        return \"ratio {}, max {}, exact {}, v4 compatible {}\".format(\n                    self.radius_ratio, self.maximum_radius,\n                    self.round_radius_exact, self.kicad4_compatible\n                    )\n\n\nclass Pad(Node):\n    r\"\"\"Add a Pad to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *number* (``int``, ``str``) --\n          number/name of the pad (default: \\\"\\\")\n        * *type* (``Pad.TYPE_THT``, ``Pad.TYPE_SMT``, ``Pad.TYPE_CONNECT``, ``Pad.TYPE_NPTH``) --\n          type of the pad\n        * *shape* (``Pad.SHAPE_CIRCLE``, ``Pad.SHAPE_OVAL``, ``Pad.SHAPE_RECT``, ``SHAPE_ROUNDRECT``,\n        ``Pad.SHAPE_TRAPEZE``, ``SHAPE_CUSTOM``) --\n          shape of the pad\n        * *layers* (``Pad.LAYERS_SMT``, ``Pad.LAYERS_THT``, ``Pad.LAYERS_NPTH``) --\n          layers on which are used for the pad\n\n        * *at* (``Vector2D``) --\n          center position of the pad\n        * *rotation* (``float``) --\n          rotation of the pad\n        * *size* (``float``, ``Vector2D``) --\n          size of the pad\n        * *offset* (``Vector2D``) --\n          offset of the pad\n        * *drill* (``float``, ``Vector2D``) --\n          drill-size of the pad\n\n        * *radius_ratio* (``float``) --\n          The radius ratio of the rounded rectangle.\n          Ignored for every shape except round rect.\n        * *maximum_radius* (``float``) --\n          The maximum radius for the rounded rectangle.\n          If the radius produced by the radius_ratio parameter for the pad would\n          exceed the maximum radius, the ratio is reduced to limit the radius.\n          (This is useful for IPC-7351C compliance as it suggests 25% ratio with limit 0.25mm)\n          Ignored for every shape except round rect.\n        * *round_radius_exact* (``float``) --\n          Set an exact round radius for a pad.\n          Ignored for every shape except round rect\n        * *round_radius_handler* (``RoundRadiusHandler``) --\n          An instance of the RoundRadiusHandler class\n          If this is given then all other round radius specifiers are ignored\n          Ignored for every shape except round rect\n\n        * *solder_paste_margin_ratio* (``float``) --\n          solder paste margin ratio of the pad (default: 0)\n        * *solder_paste_margin* (``float``) --\n          solder paste margin of the pad (default: 0)\n        * *solder_mask_margin* (``float``) --\n          solder mask margin of the pad (default: 0)\n\n        * *x_mirror* (``[int, float](mirror offset)``) --\n          mirror x direction around offset \"point\"\n        * *y_mirror* (``[int, float](mirror offset)``) --\n          mirror y direction around offset \"point\"\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n    ...     at=[0, 0], size=[2, 2], drill=1.2, layers=Pad.LAYERS_THT)\n    \"\"\"\n\n    TYPE_THT = 'thru_hole'\n    TYPE_SMT = 'smd'\n    TYPE_CONNECT = 'connect'\n    TYPE_NPTH = 'np_thru_hole'\n    _TYPES = [TYPE_THT, TYPE_SMT, TYPE_CONNECT, TYPE_NPTH]\n\n    SHAPE_CIRCLE = 'circle'\n    SHAPE_OVAL = 'oval'\n    SHAPE_RECT = 'rect'\n    SHAPE_ROUNDRECT = 'roundrect'\n    SHAPE_TRAPEZE = 'trapezoid'\n    SHAPE_CUSTOM = 'custom'\n    _SHAPES = [SHAPE_CIRCLE, SHAPE_OVAL, SHAPE_RECT, SHAPE_ROUNDRECT, SHAPE_TRAPEZE, SHAPE_CUSTOM]\n\n    LAYERS_SMT = ['F.Cu', 'F.Mask', 'F.Paste']\n    LAYERS_THT = ['*.Cu', '*.Mask']\n    LAYERS_NPTH = ['*.Cu', '*.Mask']\n\n    ANCHOR_CIRCLE = 'circle'\n    ANCHOR_RECT = 'rect'\n    _ANCHOR_SHAPE = [ANCHOR_CIRCLE, ANCHOR_RECT]\n\n    SHAPE_IN_ZONE_CONVEX = 'convexhull'\n    SHAPE_IN_ZONE_OUTLINE = 'outline'\n    _SHAPE_IN_ZONE = [SHAPE_IN_ZONE_CONVEX, SHAPE_IN_ZONE_OUTLINE]\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        self.radius_ratio = 0\n\n        self._initNumber(**kwargs)\n        self._initType(**kwargs)\n        self._initShape(**kwargs)\n        self._initPosition(**kwargs)\n        self._initSize(**kwargs)\n        self._initOffset(**kwargs)\n        self._initDrill(**kwargs)  # requires pad type and offset\n        self._initSolderPasteMargin(**kwargs)\n        self._initSolderPasteMarginRatio(**kwargs)\n        self._initSolderMaskMargin(**kwargs)\n        self._initLayers(**kwargs)\n        self._initMirror(**kwargs)\n\n        if self.shape == self.SHAPE_OVAL and self.size[0] == self.size[1]:\n            self.shape = self.SHAPE_CIRCLE\n\n        if self.shape == Pad.SHAPE_OVAL or self.shape == Pad.SHAPE_CIRCLE:\n            self.radius_ratio = 0.5\n        if self.shape == Pad.SHAPE_ROUNDRECT:\n            self._initRadiusRatio(**kwargs)\n\n        if self.shape == Pad.SHAPE_CUSTOM:\n            self._initAnchorShape(**kwargs)\n            self._initShapeInZone(**kwargs)\n\n            self.primitives = []\n            if 'primitives' not in kwargs:\n                raise KeyError('primitives must be declared for custom pads')\n\n            for p in kwargs['primitives']:\n                self.addPrimitive(p)\n\n    def _initMirror(self, **kwargs):\n        self.mirror = [None, None]\n        if 'x_mirror' in kwargs and type(kwargs['x_mirror']) in [float, int]:\n            self.mirror[0] = kwargs['x_mirror']\n        if 'y_mirror' in kwargs and type(kwargs['y_mirror']) in [float, int]:\n            self.mirror[1] = kwargs['y_mirror']\n\n        if self.mirror[0] is not None:\n            self.at.x = 2 * self.mirror[0] - self.at.x\n            self.offset.x *= -1\n        if self.mirror[1] is not None:\n            self.at.y = 2 * self.mirror[1] - self.at.y\n            self.offset.y *= -1\n\n    def _initNumber(self, **kwargs):\n        self.number = kwargs.get('number', \"\")  # default to an un-numbered pad\n\n    def _initType(self, **kwargs):\n        if not kwargs.get('type'):\n            raise KeyError('type not declared (like \"type=Pad.TYPE_THT\")')\n        self.type = kwargs.get('type')\n        if self.type not in Pad._TYPES:\n            raise ValueError('{type} is an invalid type for pads'.format(type=self.type))\n\n    def _initShape(self, **kwargs):\n        if not kwargs.get('shape'):\n            raise KeyError('shape not declared (like \"shape=Pad.SHAPE_CIRCLE\")')\n        self.shape = kwargs.get('shape')\n        if self.shape not in Pad._SHAPES:\n            raise ValueError('{shape} is an invalid shape for pads'.format(shape=self.shape))\n\n    def _initPosition(self, **kwargs):\n        if not kwargs.get('at'):\n            raise KeyError('center position not declared (like \"at=[0,0]\")')\n        self.at = Vector2D(kwargs.get('at'))\n\n        self.rotation = kwargs.get('rotation', 0)\n\n    def _initSize(self, **kwargs):\n        if not kwargs.get('size'):\n            raise KeyError('pad size not declared (like \"size=[1,1]\")')\n        self.size = toVectorUseCopyIfNumber(kwargs.get('size'), low_limit=0)\n\n    def _initOffset(self, **kwargs):\n        self.offset = Vector2D(kwargs.get('offset', [0, 0]))\n\n    def _initDrill(self, **kwargs):\n        if self.type in [Pad.TYPE_THT, Pad.TYPE_NPTH]:\n            if not kwargs.get('drill'):\n                raise KeyError('drill size required (like \"drill=1\")')\n            self.drill = toVectorUseCopyIfNumber(kwargs.get('drill'), low_limit=0)\n        else:\n            self.drill = None\n            if kwargs.get('drill'):\n                pass  # TODO: throw warning because drill is not supported\n\n    def _initSolderPasteMarginRatio(self, **kwargs):\n        self.solder_paste_margin_ratio = kwargs.get('solder_paste_margin_ratio', 0)\n\n    def _initSolderPasteMargin(self, **kwargs):\n        self.solder_paste_margin = kwargs.get('solder_paste_margin', 0)\n\n    def _initSolderMaskMargin(self, **kwargs):\n        self.solder_mask_margin = kwargs.get('solder_mask_margin', 0)\n\n    def _initLayers(self, **kwargs):\n        if not kwargs.get('layers'):\n            raise KeyError('layers not declared (like \"layers=[\\'*.Cu\\', \\'*.Mask\\', \\'F.SilkS\\']\")')\n        self.layers = kwargs.get('layers')\n\n    def _initRadiusRatio(self, **kwargs):\n        if('round_radius_handler' in kwargs):\n            self.round_radius_handler = kwargs['round_radius_handler']\n        else:\n            self.round_radius_handler = RoundRadiusHandler(**kwargs)\n\n        self.radius_ratio = self.round_radius_handler.getRadiusRatio(min(self.size))\n\n        if self.radius_ratio == 0:\n            self.shape = Pad.SHAPE_RECT\n\n    def _initAnchorShape(self, **kwargs):\n        self.anchor_shape = kwargs.get('anchor_shape', Pad.ANCHOR_CIRCLE)\n        if self.anchor_shape not in Pad._ANCHOR_SHAPE:\n            raise ValueError('{shape} is an illegal anchor shape'.format(shape=self.anchor_shape))\n\n    def _initShapeInZone(self, **kwargs):\n        self.shape_in_zone = kwargs.get('shape_in_zone', Pad.SHAPE_IN_ZONE_OUTLINE)\n        if self.shape_in_zone not in Pad._SHAPE_IN_ZONE:\n            raise ValueError('{shape} is an illegal specifier for the shape in zone option'\n                             .format(shape=self.shape_in_zone))\n\n    def rotate(self, angle, origin=(0, 0), use_degrees=True):\n        r\"\"\" Rotate pad around given origin\n\n        :params:\n            * *angle* (``float``)\n                rotation angle\n            * *origin* (``Vector2D``)\n                origin point for the rotation. default: (0, 0)\n            * *use_degrees* (``boolean``)\n                rotation angle is given in degrees. default:True\n        \"\"\"\n\n        self.at.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        a = angle if use_degrees else math.degrees(angle)\n\n        # subtraction because kicad text field rotation is the wrong way round\n        self.rotation -= a\n        return self\n\n    def translate(self, distance_vector):\n        r\"\"\" Translate pad\n\n        :params:\n            * *distance_vector* (``Vector2D``)\n                2D vector defining by how much and in what direction to translate.\n        \"\"\"\n\n        self.at += distance_vector\n        return self\n\n    # calculate the outline of a pad\n    def calculateBoundingBox(self):\n        return Node.calculateBoundingBox(self)\n\n    def _getRenderTreeText(self):\n        render_strings = ['pad']\n        render_strings.append(lispString(self.number))\n        render_strings.append(lispString(self.type))\n        render_strings.append(lispString(self.shape))\n        render_strings.append(self.at.render('(at {x} {y})'))\n        render_strings.append(self.size.render('(size {x} {y})'))\n        render_strings.append('(drill {})'.format(self.drill))\n        render_strings.append('(layers {})'.format(' '.join(self.layers)))\n\n        render_text = Node._getRenderTreeText(self)\n        render_text += '({})'.format(' '.join(render_strings))\n\n        return render_text\n\n    def addPrimitive(self, p):\n        r\"\"\" add a primitve to a custom pad\n\n        :param p: the primitive to add\n        \"\"\"\n        self.primitives.append(p)\n\n    def getRoundRadius(self):\n        if self.shape == Pad.SHAPE_CUSTOM:\n            r_max = 0\n            for p in self.primitives:\n                r = p.width/2\n                if r > r_max:\n                    r_max = r\n            return r_max\n        return self.round_radius_handler.getRoundRadius(min(self.size))\n"
  },
  {
    "path": "KicadModTree/nodes/base/Polygon.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.PolygonPoints import *\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\n\n\nclass Polygon(Node):\n    r\"\"\"Add a Polygon to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *polygon* (``list(Point)``) --\n          outer nodes of the polygon\n        * *layer* (``str``) --\n          layer on which the line is drawn (default: 'F.SilkS')\n        * *width* (``float``) --\n          width of the line (default: None, which means auto detection)\n        * *x_mirror* (``[int, float](mirror offset)``) --\n          mirror x direction around offset \"point\"\n        * *y_mirror* (``[int, float](mirror offset)``) --\n          mirror y direction around offset \"point\"\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> Polygon(nodes=[[-2, 0], [0, -2], [4, 0], [0, 2]], layer='F.SilkS')\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        self.nodes = PolygonPoints(**kwargs)\n\n        self.layer = kwargs.get('layer', 'F.SilkS')\n        self.width = kwargs.get('width')\n\n    def rotate(self, angle, origin=(0, 0), use_degrees=True):\n        r\"\"\" Rotate polygon around given origin\n\n        :params:\n            * *angle* (``float``)\n                rotation angle\n            * *origin* (``Vector2D``)\n                origin point for the rotation. default: (0, 0)\n            * *use_degrees* (``boolean``)\n                rotation angle is given in degrees. default:True\n        \"\"\"\n\n        self.nodes.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        return self\n\n    def translate(self, distance_vector):\n        r\"\"\" Translate polygon\n\n        :params:\n            * *distance_vector* (``Vector2D``)\n                2D vector defining by how much and in what direction to translate.\n        \"\"\"\n\n        self.nodes.translate(distance_vector)\n        return self\n\n    def calculateBoundingBox(self):\n        return nodes.calculateBoundingBox()\n\n    def _getRenderTreeText(self):\n        render_text = Node._getRenderTreeText(self)\n        render_text += \" [nodes: [\"\n\n        node_strings = []\n        for n in self.nodes:\n            node_strings.append(\"[x: {x}, y: {y}]\".format(x=n.x, y=n.y))\n\n        if len(node_strings) <= 6:\n            render_text += \", \".join(node_strings)\n        else:\n            # display only a few nodes of the beginning and the end of the polygone line\n            render_text += \", \".join(node_strings[:3])\n            render_text += \",... , \"\n            render_text += \", \".join(node_strings[-3:])\n\n        render_text += \"]\"\n\n        return render_text\n\n    def cut(self, other):\n        r\"\"\" Cut other polygon from this polygon\n\n        More details see PolygonPoints.cut docstring.\n\n        :param other: the other polygon\n        \"\"\"\n        self.nodes.cut(other.nodes)\n"
  },
  {
    "path": "KicadModTree/nodes/base/Text.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\n\n\nclass Text(Node):\n    r\"\"\"Add a Line to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *type* (``str``) --\n          type of text\n        * *text* (``str``) --\n          text which is been visualized\n        * *at* (``Vector2D``) --\n          position of text\n        * *rotation* (``float``) --\n          rotation of text (default: 0)\n        * *mirror* (``bool``) --\n          mirror text (default: False)\n        * *layer* (``str``) --\n          layer on which the text is drawn (default: 'F.SilkS')\n        * *size* (``Vector2D``) --\n          size of the text (default: [1, 1])\n        * *thickness* (``float``) --\n          thickness of the text (default: 0.15)\n        * *hide* (``bool``) --\n          hide text (default: False)\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> Text(type='reference', text='REF**', at=[0, -3], layer='F.SilkS')\n    >>> Text(type='value', text=\"footprint name\", at=[0, 3], layer='F.Fab')\n    >>> Text(type='user', text='test', at=[0, 0], layer='Cmts.User')\n    \"\"\"\n\n    TYPE_REFERENCE = 'reference'\n    TYPE_VALUE = 'value'\n    TYPE_USER = 'user'\n    _TYPES = [TYPE_REFERENCE, TYPE_VALUE, TYPE_USER]\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        self._initType(**kwargs)\n\n        self.text = kwargs['text']\n        self.at = Vector2D(kwargs['at'])\n        self.rotation = kwargs.get('rotation', 0)\n        self.mirror = kwargs.get('mirror', False)\n\n        self.layer = kwargs.get('layer', 'F.SilkS')\n        self.size = Vector2D(kwargs.get('size', [1, 1]))\n        self.thickness = kwargs.get('thickness', 0.15)\n\n        self.hide = kwargs.get('hide', False)\n\n    def _initType(self, **kwargs):\n        self.type = kwargs['type']\n        if self.type not in Text._TYPES:\n            raise ValueError('Illegal type selected for text field.')\n\n    def rotate(self, angle, origin=(0, 0), use_degrees=True):\n        r\"\"\" Rotate text around given origin\n\n        :params:\n            * *angle* (``float``)\n                rotation angle\n            * *origin* (``Vector2D``)\n                origin point for the rotation. default: (0, 0)\n            * *use_degrees* (``boolean``)\n                rotation angle is given in degrees. default:True\n        \"\"\"\n\n        self.at.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        a = angle if use_degrees else math.degrees(angle)\n\n        # subtraction because kicad text field rotation is the wrong way round\n        self.rotation -= a\n        return self\n\n    def translate(self, distance_vector):\n        r\"\"\" Translate text\n\n        :params:\n            * *distance_vector* (``Vector2D``)\n                2D vector defining by how much and in what direction to translate.\n        \"\"\"\n\n        self.at += distance_vector\n        return self\n\n    def calculateBoundingBox(self):\n        width = len(self.text)*self.size['x']\n        height = self.size['y']\n\n        min_x = self.at['x']-width/2.\n        min_y = self.at['y']-height/2.\n        max_x = self.at['x']+width/2.\n        max_y = self.at['y']+height/2.\n\n        return Node.calculateBoundingBox({'min': Vector2D(min_x, min_y), 'max': Vector2D(max_x, max_y)})\n\n    def _getRenderTreeText(self):\n        render_text = Node._getRenderTreeText(self)\n\n        render_string = ['type: \"{}\"'.format(self.type),\n                         'text: \"{}\"'.format(self.text),\n                         'at: {}'.format(self.at.render('(at {x} {y})')),\n                         'layer: {}'.format(self.layer),\n                         'size: {}'.format(self.size.render('(size {x} {y})')),\n                         'thickness: {}'.format(self.thickness)]\n\n        render_text += \" [{}]\".format(\", \".join(render_string))\n\n        return render_text\n"
  },
  {
    "path": "KicadModTree/nodes/base/__init__.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016-2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom .Arc import Arc\n\nfrom .Circle import Circle\n\nfrom .Line import Line\n\nfrom .Model import Model\n\nfrom .Pad import Pad\n\nfrom .Polygon import Polygon\n\nfrom .Text import Text\n"
  },
  {
    "path": "KicadModTree/nodes/specialized/ChamferedPad.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n# (C) 2018 by Rene Poeschl, github @poeschlr\nfrom __future__ import division\n\nfrom copy import copy\nfrom KicadModTree.util.paramUtil import *\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.base.Polygon import *\nfrom KicadModTree.nodes.base.Pad import Pad, RoundRadiusHandler\nfrom math import sqrt\n\n\nclass CornerSelection():\n    r\"\"\"Class for handling chamfer selection\n        :param chamfer_select:\n            * A list of bools do directly set the corners\n              (top left, top right, bottom right, bottom left)\n            * A dict with keys (constands see below)\n            * The integer 1 means all corners\n            * The integer 0 means no corners\n\n        :constants:\n            * CornerSelection.TOP_LEFT\n            * CornerSelection.TOP_RIGHT\n            * CornerSelection.BOTTOM_RIGHT\n            * CornerSelection.BOTTOM_LEFT\n    \"\"\"\n\n    TOP_LEFT = 'tl'\n    TOP_RIGHT = 'tr'\n    BOTTOM_RIGHT = 'br'\n    BOTTOM_LEFT = 'bl'\n\n    def __init__(self, chamfer_select):\n        self.top_left = False\n        self.top_right = False\n        self.bottom_right = False\n        self.bottom_left = False\n\n        if chamfer_select == 1:\n            self.selectAll()\n            return\n\n        if chamfer_select == 0:\n            return\n\n        if type(chamfer_select) is dict:\n            for key in chamfer_select:\n                self[key] = bool(chamfer_select[key])\n        else:\n            for i, value in enumerate(chamfer_select):\n                self[i] = bool(value)\n\n    def selectAll(self):\n        for i in range(len(self)):\n            self[i] = True\n\n    def clearAll(self):\n        for i in range(len(self)):\n            self[i] = False\n\n    def setLeft(self, value=1):\n        self.top_left = bool(value)\n        self.bottom_left = bool(value)\n\n    def setTop(self, value=1):\n        self.top_left = bool(value)\n        self.top_right = bool(value)\n\n    def setRight(self, value=1):\n        self.top_right = bool(value)\n        self.bottom_right = bool(value)\n\n    def setBottom(self, value=1):\n        self.bottom_left = bool(value)\n        self.bottom_right = bool(value)\n\n    def isAnySelected(self):\n        for v in self:\n            if v:\n                return True\n        return False\n\n    def rotateCW(self):\n        top_left_old = self.top_left\n\n        self.top_left = self.bottom_left\n        self.bottom_left = self.bottom_right\n        self.bottom_right = self.top_right\n        self.top_right = top_left_old\n        return self\n\n    def rotateCCW(self):\n        top_left_old = self.top_left\n\n        self.top_left = self.top_right\n        self.top_right = self.bottom_right\n        self.bottom_right = self.bottom_left\n        self.bottom_left = top_left_old\n        return self\n\n    def __or__(self, other):\n        return CornerSelection([s or o for s, o in zip(self, other)])\n\n    def __ior__(self, other):\n        for i in range(len(self)):\n            self[i] |= other[i]\n        return self\n\n    def __and__(self, other):\n        return CornerSelection([s and o for s, o in zip(self, other)])\n\n    def __iand__(self, other):\n        for i in range(len(self)):\n            self[i] &= other[i]\n        return self\n\n    def __len__(self):\n        return 4\n\n    def __iter__(self):\n        yield self.top_left\n        yield self.top_right\n        yield self.bottom_right\n        yield self.bottom_left\n\n    def __getitem__(self, item):\n        if item in [0, CornerSelection.TOP_LEFT]:\n            return self.top_left\n        if item in [1, CornerSelection.TOP_RIGHT]:\n            return self.top_right\n        if item in [2, CornerSelection.BOTTOM_RIGHT]:\n            return self.bottom_right\n        if item in [3, CornerSelection.BOTTOM_LEFT]:\n            return self.bottom_left\n\n        raise IndexError('Index {} is out of range'.format(item))\n\n    def __setitem__(self, item, value):\n        if item in [0, CornerSelection.TOP_LEFT]:\n            self.top_left = bool(value)\n        elif item in [1, CornerSelection.TOP_RIGHT]:\n            self.top_right = bool(value)\n        elif item in [2, CornerSelection.BOTTOM_RIGHT]:\n            self.bottom_right = bool(value)\n        elif item in [3, CornerSelection.BOTTOM_LEFT]:\n            self.bottom_left = bool(value)\n        else:\n            raise IndexError('Index {} is out of range'.format(item))\n\n    def to_dict(self):\n        return {\n            CornerSelection.TOP_LEFT: self.top_left,\n            CornerSelection.TOP_RIGHT: self.top_right,\n            CornerSelection.BOTTOM_RIGHT: self.bottom_right,\n            CornerSelection.BOTTOM_LEFT: self.bottom_left\n            }\n\n    def __str__(self):\n        return str(self.to_dict())\n\n\nclass ChamferedPad(Node):\n    r\"\"\"Add a ChamferedPad to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *number* (``int``, ``str``) --\n          number/name of the pad (default: \\\"\\\")\n        * *type* (``Pad.TYPE_THT``, ``Pad.TYPE_SMT``, ``Pad.TYPE_CONNECT``, ``Pad.TYPE_NPTH``) --\n          type of the pad\n        * *at* (``Vector2D``) --\n          center position of the pad\n        * *rotation* (``float``) --\n          rotation of the pad\n        * *size* (``float``, ``Vector2D``) --\n          size of the pad\n        * *offset* (``Vector2D``) --\n          offset of the pad\n        * *drill* (``float``, ``Vector2D``) --\n          drill-size of the pad\n        * *solder_paste_margin_ratio* (``float``) --\n          solder paste margin ratio of the pad (default: 0)\n        * *solder_paste_margin* (``float``) --\n          solder paste margin of the pad (default: 0)\n        * *solder_mask_margin* (``float``) --\n          solder mask margin of the pad (default: 0)\n        * *layers* (``Pad.LAYERS_SMT``, ``Pad.LAYERS_THT``, ``Pad.LAYERS_NPTH``) --\n          layers on which are used for the pad\n        * *corner_selection* (``CornerSelection``) --\n          Select which corner(s) to chamfer. (top left, top right, bottom right, bottom left)\n        * *chamfer_size* (``float``, ``Vector2D``) --\n          Size of the chamfer.\n        * *x_mirror* (``[int, float](mirror offset)``) --\n          mirror x direction around offset \"point\"\n        * *y_mirror* (``[int, float](mirror offset)``) --\n          mirror y direction around offset \"point\"\n\n        * *radius_ratio* (``float``) --\n          The radius ratio of the rounded rectangle.\n          (default 0 for backwards compatibility)\n        * *maximum_radius* (``float``) --\n          The maximum radius for the rounded rectangle.\n          If the radius produced by the radius_ratio parameter for the pad would\n          exceed the maximum radius, the ratio is reduced to limit the radius.\n          (This is useful for IPC-7351C compliance as it suggests 25% ratio with limit 0.25mm)\n        * *round_radius_exact* (``float``) --\n          Set an exact round radius for a pad.\n        * *round_radius_handler* (``RoundRadiusHandler``) --\n          An instance of the RoundRadiusHandler class\n          If this is given then all other round radius specifiers are ignored\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        self._initPosition(**kwargs)\n        self._initSize(**kwargs)\n        self._initMirror(**kwargs)\n        self._initPadSettings(**kwargs)\n\n        self.pad = self._generatePad()\n\n    def _initSize(self, **kwargs):\n        if not kwargs.get('size'):\n            raise KeyError('pad size not declared (like \"size=[1,1]\")')\n        self.size = toVectorUseCopyIfNumber(kwargs.get('size'), low_limit=0)\n\n    def _initPosition(self, **kwargs):\n        if 'at' not in kwargs:\n            raise KeyError('center position not declared (like \"at=[0,0]\")')\n        self.at = Vector2D(kwargs.get('at'))\n\n    def _initMirror(self, **kwargs):\n        self.mirror = {}\n        if 'x_mirror' in kwargs and type(kwargs['x_mirror']) in [float, int]:\n            self.mirror['x_mirror'] = kwargs['x_mirror']\n        if 'y_mirror' in kwargs and type(kwargs['y_mirror']) in [float, int]:\n            self.mirror['y_mirror'] = kwargs['y_mirror']\n\n    def _initPadSettings(self, **kwargs):\n        if 'corner_selection' not in kwargs:\n            raise KeyError('corner selection is required for chamfered pads (like \"corner_selection=[1,0,0,0]\")')\n\n        self.corner_selection = CornerSelection(kwargs.get('corner_selection'))\n\n        if 'chamfer_size' not in kwargs:\n            self.chamfer_size = Vector2D(0, 0)\n        else:\n            self.chamfer_size = toVectorUseCopyIfNumber(\n                kwargs.get('chamfer_size'), low_limit=0, must_be_larger=False)\n\n        if('round_radius_handler' in kwargs):\n            self.round_radius_handler = kwargs['round_radius_handler']\n        else:\n            # default radius ration 0 for backwards compatibility\n            self.round_radius_handler = RoundRadiusHandler(default_radius_ratio=0, **kwargs)\n\n        self.padargs = copy(kwargs)\n        self.padargs.pop('size', None)\n        self.padargs.pop('shape', None)\n        self.padargs.pop('at', None)\n        self.padargs.pop('round_radius_handler', None)\n\n    def _generatePad(self):\n        if self.chamfer_size[0] >= self.size[0] or self.chamfer_size[1] >= self.size[1]:\n            raise ValueError('Chamfer size ({}) too large for given pad size ({})'.format(self.chamfer_size, self.size))\n\n        is_chamfered = False\n        if self.corner_selection.isAnySelected() and self.chamfer_size[0] > 0 and self.chamfer_size[1] > 0:\n            is_chamfered = True\n\n        radius = self.round_radius_handler.getRoundRadius(min(self.size))\n\n        if is_chamfered:\n            outside = Vector2D(self.size.x/2, self.size.y/2)\n\n            inside = [Vector2D(outside.x, outside.y-self.chamfer_size.y),\n                      Vector2D(outside.x-self.chamfer_size.x, outside.y)\n                      ]\n\n            polygon_width = 0\n            if self.round_radius_handler.roundingRequested():\n                if self.chamfer_size[0] != self.chamfer_size[1]:\n                    raise NotImplementedError(\n                            'Rounded chamfered pads are only supported for 45 degree chamfers.'\n                            ' Chamfer {}'.format(self.chamfer_size)\n                            )\n                # We prefer the use of rounded rectangle over chamfered pads.\n                r_chamfer = self.chamfer_size[0] + sqrt(2)*self.chamfer_size[0]/2\n                if radius >= r_chamfer:\n                    is_chamfered = False\n                elif radius > 0:\n                    shortest_sidlength = min(min(self.size-self.chamfer_size), self.chamfer_size[0]*sqrt(2))\n                    if radius > shortest_sidlength/2:\n                        radius = shortest_sidlength/2\n                    polygon_width = radius*2\n                    outside -= radius\n                    inside[0].y -= radius*(2/sqrt(2)-1)\n                    inside[0].x -= radius\n                    inside[1].x -= radius*(2/sqrt(2)-1)\n                    inside[1].y -= radius\n\n        if is_chamfered:\n            points = []\n            corner_vectors = [\n                Vector2D(-1, -1), Vector2D(1, -1), Vector2D(1, 1), Vector2D(-1, 1)\n                ]\n            for i in range(4):\n                if self.corner_selection[i]:\n                    points.append(corner_vectors[i]*inside[i % 2])\n                    points.append(corner_vectors[i]*inside[(i+1) % 2])\n                else:\n                    points.append(corner_vectors[i]*outside)\n\n            primitives = [Polygon(nodes=points, width=polygon_width, **self.mirror)]\n            # TODO make size calculation more resilient\n            size = min(self.size.x, self.size.y)-max(self.chamfer_size[0], self.chamfer_size[1])/sqrt(2)\n            if size <= 0:\n                raise ValueError('Anchor pad size calculation failed.'\n                                 'Chamfer size ({}) to large for given pad size ({})'\n                                 .format(self.size, self.chamfer_size))\n            return Pad(primitives=primitives, at=self.at,\n                       shape=Pad.SHAPE_CUSTOM, size=size, **self.padargs)\n        else:\n            return Pad(\n                    at=self.at, shape=Pad.SHAPE_ROUNDRECT, size=self.size,\n                    round_radius_handler=self.round_radius_handler, **self.padargs\n                )\n\n    def chamferAvoidCircle(self, center, diameter, clearance=0):\n        r\"\"\" set the chamfer such that the pad avoids a cricle located at near corner.\n\n        :param center: (``Vector2D``) --\n           The center of the circle ot avoid\n        :param diameter: (``float``, ``Vector2D``) --\n           The diameter of the circle. If Vector2D given only x direction is used.\n        :param clearance: (``float``) --\n           Additional clearance around circle. default:0\n        \"\"\"\n\n        relative_center = Vector2D(center) - self.at\n        # pad and circle are symetric so we do not care which corner the\n        # reference circle is located at.\n        #  -> move it to bottom right to get only positive relative coordinates.\n        relative_center = Vector2D([abs(v) for v in relative_center])\n        d = diameter if type(diameter) in [float, int] else diameter.x\n\n        # Where should the chamfer be if the center of the reference circle\n        # would be in line with the pad edges\n        # (meaning exactly at the bottome right corner)\n        reference_point = relative_center - sqrt(2)*(clearance+d/2)\n        self.chamfer_size = self.size/2 - reference_point\n\n        # compensate for reference circles not placed exactly at the corner\n        edge_to_center = relative_center - self.size/2\n        self.chamfer_size -= [edge_to_center.y, edge_to_center.x]\n        self.chamfer_size = Vector2D([x if x > 0 else 0 for x in self.chamfer_size])\n\n        self.pad = self._generatePad()\n        return self.chamfer_size\n\n    def getVirtualChilds(self):\n        return [self.pad]\n\n    def getRoundRadius(self):\n        return self.pad.getRoundRadius()\n"
  },
  {
    "path": "KicadModTree/nodes/specialized/ChamferedPadGrid.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n# (C) 2018 by Rene Poeschl, github @poeschlr\n\nfrom __future__ import division\n\nfrom KicadModTree.util.paramUtil import *\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.base.Polygon import *\nfrom KicadModTree.nodes.specialized.ChamferedPad import *\n\n\nclass ChamferSelPadGrid(CornerSelection):\n    r\"\"\"Class for handling chamfer selection\n        :param chamfer_select:\n            * A list of bools do directly set the corners\n              (top left, top right, bottom right, bottom left)\n            * A dict with keys (Constands see below)\n            * The integer 1 means all corners and edges\n            * The integer 0 means no corners, no edges\n\n        :constants:\n            * ChamferSelPadGrid.TOP_EDGE\n            * ChamferSelPadGrid.RIGHT_EDGE\n            * ChamferSelPadGrid.BOTTOM_EDGE\n            * ChamferSelPadGrid.LEFT_EDGE\n            * Plus all constands inherited from CornerSelection\n\n    \"\"\"\n\n    TOP_EDGE = \"t\"\n    RIGHT_EDGE = \"r\"\n    BOTTOM_EDGE = \"b\"\n    LEFT_EDGE = \"l\"\n\n    def __init__(self, chamfer_select):\n        self.top_edge = False\n        self.right_edge = False\n        self.bottom_edge = False\n        self.left_edge = False\n\n        if chamfer_select == 1:\n            self.selectAll()\n            CornerSelection.__init__(self, 1)\n            return\n\n        if chamfer_select == 0:\n            CornerSelection.__init__(self, 0)\n            return\n\n        if type(chamfer_select) is dict:\n            CornerSelection.__init__(self, chamfer_select)\n            for key in chamfer_select:\n                self[key] = bool(chamfer_select[key])\n        else:\n            for i, value in enumerate(chamfer_select):\n                self[i] = bool(value)\n\n    def setLeft(self, value=1):\n        CornerSelection.setLeft(self, value)\n        self.left_edge = bool(value)\n\n    def setTop(self, value=1):\n        CornerSelection.setTop(self, value)\n        self.top_edge = bool(value)\n\n    def setRight(self, value=1):\n        CornerSelection.setRight(self, value)\n        self.right_edge = bool(value)\n\n    def setBottom(self, value=1):\n        CornerSelection.setBottom(self, value)\n        self.bottom_edge = bool(value)\n\n    def setCorners(self, value=1):\n        self.top_left = bool(value)\n        self.top_right = bool(value)\n        self.bottom_right = bool(value)\n        self.bottom_left = bool(value)\n\n    def setEdges(self, value=1):\n        self.top_edge = bool(value)\n        self.right_edge = bool(value)\n        self.bottom_edge = bool(value)\n        self.left_edge = bool(value)\n\n    def __len__(self):\n        return 8\n\n    def __iter__(self):\n        for v in CornerSelection.__iter__(self):\n            yield v\n        yield self.top_edge\n        yield self.right_edge\n        yield self.bottom_edge\n        yield self.left_edge\n\n    def __getitem__(self, item):\n        if item in [4, ChamferSelPadGrid.TOP_EDGE]:\n            return self.top_edge\n        if item in [5, ChamferSelPadGrid.RIGHT_EDGE]:\n            return self.right_edge\n        if item in [6, ChamferSelPadGrid.BOTTOM_EDGE]:\n            return self.bottom_edge\n        if item in [7, ChamferSelPadGrid.LEFT_EDGE]:\n            return self.left_edge\n        return CornerSelection.__getitem__(self, item)\n\n    def __setitem__(self, item, value):\n        if item in [4, ChamferSelPadGrid.TOP_EDGE]:\n            self.top_edge = bool(value)\n        elif item in [5, ChamferSelPadGrid.RIGHT_EDGE]:\n            self.right_edge = bool(value)\n        elif item in [6, ChamferSelPadGrid.BOTTOM_EDGE]:\n            self.bottom_edge = bool(value)\n        elif item in [7, ChamferSelPadGrid.LEFT_EDGE]:\n            self.left_edge = bool(value)\n        else:\n            CornerSelection.__setitem__(self, item, value)\n\n    def to_dict(self):\n        result = CornerSelection.to_dict(self)\n        result.update({\n            ChamferSelPadGrid.TOP_EDGE: self.top_edge,\n            ChamferSelPadGrid.RIGHT_EDGE: self.right_edge,\n            ChamferSelPadGrid.BOTTOM_EDGE: self.bottom_edge,\n            ChamferSelPadGrid.LEFT_EDGE: self.left_edge\n            })\n        return result\n\n\nclass ChamferedPadGrid(Node):\n    r\"\"\"Add a ChamferedPad to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *number* (``int``, ``str``) --\n          number/name of the pad (default: \\\"\\\")\n        * *center* (``Vector2D``) --\n          center position of the pad grid\n        * *size* (``float``, ``Vector2D``) --\n          size of the pads\n        * *pincount* (``int``, ``[int, int]``)\n          Pad count in x and y direction.\n          If only one integer is given, it will be used for both directions.\n        * *grid* (``float``, ``Vector2D``)\n          Pad grid in x and y direction.\n          If only one float is given, it will be used for both directions.\n\n        * *solder_paste_margin_ratio* (``float``) --\n          solder paste margin ratio of the pad (default: 0)\n        * *solder_paste_margin* (``float``) --\n          solder paste margin of the pad (default: 0)\n        * *solder_mask_margin* (``float``) --\n          solder mask margin of the pad (default: 0)\n\n        * *layers* (``Pad.LAYERS_SMT``, ``Pad.LAYERS_THT``, ``Pad.LAYERS_NPTH``) --\n          layers on which are used for the pad\n        * *chamfer_selection* (``ChamferSelPadGrid``) --\n          Select which corner and edge pads to chamfer.\n        * *chamfer_size* (``float``, ``Vector2D``) --\n          Size of the chamfer.\n        * *x_mirror* (``[int, float](mirror offset)``) --\n          mirror x direction around offset \"point\"\n        * *y_mirror* (``[int, float](mirror offset)``) --\n          mirror y direction around offset \"point\"\n\n        * *radius_ratio* (``float``) --\n          The radius ratio of the rounded rectangle.\n          (default 0 for backwards compatibility)\n        * *maximum_radius* (``float``) --\n          The maximum radius for the rounded rectangle.\n          If the radius produced by the radius_ratio parameter for the pad would\n          exceed the maximum radius, the ratio is reduced to limit the radius.\n          (This is useful for IPC-7351C compliance as it suggests 25% ratio with limit 0.25mm)\n        * *round_radius_exact* (``float``) --\n          Set an exact round radius for a pad.\n        * *round_radius_handler* (``RoundRadiusHandler``) --\n          An instance of the RoundRadiusHandler class\n          If this is given then all other round radius specifiers are ignored\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        if len(kwargs) == 0:\n            return\n\n        self.number = kwargs.get('number', \"\")\n        self.center = Vector2D(kwargs.get('center', [0, 0]))\n\n        self._initSize(**kwargs)\n        self._initCount(**kwargs)\n        self._initGrid(**kwargs)\n        self._initPadSettings(**kwargs)\n\n    def _initCount(self, **kwargs):\n        if 'pincount' not in kwargs:\n            raise KeyError('pincount not declared (like \"pincount=10\")')\n\n        self.pincount = toIntArray(kwargs['pincount'])\n\n    def _initSize(self, **kwargs):\n        if 'size' not in kwargs:\n            raise KeyError('size not declared (like \"size=[1, 2]\")')\n\n        self.size = toVectorUseCopyIfNumber(kwargs['size'], low_limit=0)\n\n    def _initGrid(self, **kwargs):\n        if 'grid' not in kwargs:\n            raise KeyError('grid not declared (like \"grid=[1, 2]\")')\n\n        self.grid = toVectorUseCopyIfNumber(kwargs['grid'], low_limit=self.size)\n\n    def _initPadSettings(self, **kwargs):\n        if 'chamfer_selection' not in kwargs:\n            raise KeyError('chamfer selection is required for chamfered pads (like \"chamfer_selection=[1,0,0,0]\")')\n\n        self.chamfer_selection = ChamferSelPadGrid(kwargs.get('chamfer_selection'))\n\n        if 'chamfer_size' not in kwargs:\n            self.chamfer_size = Vector2D(0, 0)\n        else:\n            self.chamfer_size = toVectorUseCopyIfNumber(\n                kwargs.get('chamfer_size'), low_limit=0, must_be_larger=False)\n\n        if('round_radius_handler' in kwargs):\n            self.round_radius_handler = kwargs['round_radius_handler']\n        else:\n            # default radius ration 0 for backwards compatibility\n            self.round_radius_handler = RoundRadiusHandler(default_radius_ratio=0, **kwargs)\n\n        self.padargs = copy(kwargs)\n        self.padargs.pop('size', None)\n        self.padargs.pop('number', None)\n        self.padargs.pop('at', None)\n        self.padargs.pop('chamfer_size', None)\n        self.padargs.pop('round_radius_handler', None)\n\n    def chamferAvoidCircle(self, center, diameter, clearance=0):\n        r\"\"\" set the chamfer such that the pad avoids a cricle located at near corner.\n\n        :param center: (``Vector2D``) --\n           The center of the circle ot avoid\n        :param diameter: (``float``, ``Vector2D``) --\n           The diameter of the circle. If Vector2D given only x direction is used.\n        :param clearance: (``float``) --\n           Additional clearance around circle. default:0\n        \"\"\"\n        relative_center = Vector2D(center) - self.center\n\n        left = -self.grid['x']*(self.pincount[0]-1)/2\n        top = -self.grid['y']*(self.pincount[1]-1)/2\n\n        nearest_x = left\n        nearest_y = top\n\n        min_dist_x = abs(relative_center['x']-nearest_x)\n        min_dist_y = abs(relative_center['y']-nearest_y)\n\n        for i in range(self.pincount[0]):\n            x = left+i*self.grid['x']\n            dx = abs(x-relative_center['x'])\n            if dx < min_dist_x:\n                min_dist_x = dx\n                nearest_x = x\n\n        for i in range(self.pincount[1]):\n            y = top+i*self.grid['y']\n            dy = abs(y-relative_center['y'])\n            if dy < min_dist_y:\n                min_dist_y = dy\n                nearest_y = y\n\n        temp_pad = ChamferedPad(\n            at=[nearest_x, nearest_y], size=self.size,\n            type=Pad.TYPE_SMT, layers=['F.Cu'], corner_selection=1\n        )\n        self.chamfer_size = temp_pad.chamferAvoidCircle(\n            center=relative_center, diameter=diameter, clearance=clearance)\n        return self.chamfer_size\n\n    def __padCornerSelection(self, idx_x, idx_y):\n        corner = CornerSelection(0)\n        if idx_x == 0:\n            if idx_y == 0:\n                if self.chamfer_selection[ChamferSelPadGrid.TOP_LEFT]:\n                    corner[CornerSelection.TOP_LEFT] = True\n                if self.chamfer_selection[ChamferSelPadGrid.LEFT_EDGE]:\n                    corner[CornerSelection.BOTTOM_LEFT] = True\n            if idx_y == self.pincount[1]-1:\n                if self.chamfer_selection[ChamferSelPadGrid.BOTTOM_LEFT]:\n                    corner[CornerSelection.BOTTOM_LEFT] = True\n                if self.chamfer_selection[ChamferSelPadGrid.LEFT_EDGE]:\n                    corner[CornerSelection.TOP_LEFT] = True\n            if idx_y != 0 and idx_y != self.pincount[1]-1:\n                if self.chamfer_selection[ChamferSelPadGrid.LEFT_EDGE]:\n                    corner.setLeft()\n        if idx_x == self.pincount[0]-1:\n            if idx_y == 0:\n                if self.chamfer_selection[ChamferSelPadGrid.TOP_RIGHT]:\n                    corner[CornerSelection.TOP_RIGHT] = True\n                if self.chamfer_selection[ChamferSelPadGrid.RIGHT_EDGE]:\n                    corner[CornerSelection.BOTTOM_RIGHT] = True\n            if idx_y == self.pincount[1]-1:\n                if self.chamfer_selection[ChamferSelPadGrid.BOTTOM_RIGHT]:\n                    corner[CornerSelection.BOTTOM_RIGHT] = True\n                if self.chamfer_selection[ChamferSelPadGrid.RIGHT_EDGE]:\n                    corner[CornerSelection.TOP_RIGHT] = True\n            if idx_y != 0 and idx_y != self.pincount[1]-1:\n                if self.chamfer_selection[ChamferSelPadGrid.RIGHT_EDGE]:\n                    corner.setRight()\n        if idx_x != 0 and idx_x != self.pincount[0]-1:\n            if idx_y == 0:\n                if self.chamfer_selection[ChamferSelPadGrid.TOP_EDGE]:\n                    corner.setTop()\n            if idx_y == self.pincount[1]-1:\n                if self.chamfer_selection[ChamferSelPadGrid.BOTTOM_EDGE]:\n                    corner.setBottom()\n        return corner\n\n    def _generatePads(self):\n        left = -self.grid['x']*(self.pincount[0]-1)/2+self.center['x']\n        top = -self.grid['y']*(self.pincount[1]-1)/2+self.center['y']\n\n        pads = []\n        for idx_x in range(self.pincount[0]):\n            x = left+idx_x*self.grid['x']\n            for idx_y in range(self.pincount[1]):\n                y = top+idx_y*self.grid['y']\n                corner = self.__padCornerSelection(idx_x, idx_y)\n                pads.append(ChamferedPad(\n                    at=[x, y], number=self.number, size=self.size,\n                    chamfer_size=self.chamfer_size,\n                    corner_selection=corner,\n                    round_radius_handler=self.round_radius_handler,\n                    **self.padargs\n                    ))\n        return pads\n\n    def getVirtualChilds(self):\n        return self._generatePads()\n\n    def __copy__(self):\n        newone = type(self)()\n        newone.__dict__.update(self.__dict__)\n        return newone\n"
  },
  {
    "path": "KicadModTree/nodes/specialized/ExposedPad.py",
    "content": "#!/usr/bin/env python\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2017 by @SchrodingersGat\n# (C) 2017 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n# (C) 2018 by Rene Poeschl, github @poeschlr\n\nfrom __future__ import division\n\nfrom KicadModTree.util.paramUtil import *\nfrom KicadModTree.nodes.base.Pad import *\nfrom KicadModTree.nodes.specialized.ChamferedPadGrid import *\nfrom KicadModTree.nodes.specialized.PadArray import *\nfrom KicadModTree.nodes.Node import Node\nfrom math import sqrt, floor\nfrom copy import copy\nimport traceback\n\n\nclass ExposedPad(Node):\n    r\"\"\"Add an exposed pad\n\n    Complete with correct paste, mask and via handling\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *number* (``int``, ``str``) --\n          number/name of the pad\n        * *at* (``Vector2D``) --\n          center the exposed pad around this point (default: 0,0)\n        * *size* (``float``, ``Vector2D``) --\n          size of the pad\n        * *solder_mask_margin* (``float``) --\n          solder mask margin of the pad (default: 0)\n          Only used if mask_size is not specified.\n        * *mask_size* (``float``, ``Vector2D``) --\n          size of the mask cutout (If not given, mask will be part of the main pad)\n\n        * *paste_layout* (``int``, ``[int, int]``) --\n          paste layout specification.\n          How many pads in x and y direction.\n          If only a single integer given, x and y direction use the same count.\n        * *paste_between_vias* (``int``, ``[int, int]``)\n          Alternative for paste_layout with more controll.\n          This defines how many pads will be between 4 vias in x and y direction.\n          If only a single integer given, x and y direction use the same count.\n        * *paste_rings_outside* (``int``, ``[int, int]``)\n          Alternative for paste_layout with more controll.\n          Defines the number of rings outside of the vias in x and y direction.\n          If only a single integer given, x and y direction use the same count.\n        * *paste_coverage* (``float``) --\n          how much of the mask free area is covered with paste. (default: 0.65)\n\n        * *via_layout* (``int``, ``[int, int]``) --\n          thermal via layout specification.\n          How many vias in x and y direction.\n          If only a single integer given, x and y direction use the same count.\n          default: no vias added\n        * *via_grid* (``int``, ``Vector2D``) --\n          thermal via grid specification.\n          Grid used for thermal vias in x and y direction.\n          If only a single integer given, x and y direction use the same count.\n          If none is given then the via grid will be automatically calculated\n          to have them distributed across the main pad.\n        * *via_drill* (``float``) --\n          via drill diameter (default: 0.3)\n        * *via_tented* (VIA_TENTED, VIA_TENTED_TOP_ONLY, VIA_TENTED_BOTTOM_ONLY, VIA_NOT_TENTED) --\n          Determines which side of the thermal vias is covered in soldermask.\n          On the top only vias outside the defined mask area can be covered in soldermask.\n          default: VIA_TENTED\n        * *min_annular_ring* (``float``) --\n          Anullar ring for thermal vias. (default: 0.15)\n        * *bottom_pad_Layers* (``[layer string]``) --\n          Select layers for the bottom pad (default: [B.Cu]) --\n          Ignored if no thermal vias are added.\n          If None or empty no pad is added.\n        * *bottom_pad_min_size* (``float``, ``Vector2D``) --\n          Minimum size for bottom pad. default: (0,0)\n          Ignored if no bottom pad given.\n        * *paste_avoid_via* (``bool``) --\n          Paste automatically generated to avoid vias (default: false)\n        * *via_paste_clarance* (``float``)\n          Clearance between paste and via drills (default: 0.05)\n          Only used if paste_avoid_via is set.\n\n        * *grid_round_base* (``float``) --\n          Base used for rounding calculated grids (default: 0.01)\n          0 means no rounding\n        * *size_round_base* (``float``) --\n          Base used for rounding calculated sizes (default: 0.01)\n          0 means no rounding\n\n        * *radius_ratio* (``float``) --\n          The radius ratio of the main pads.\n        * *maximum_radius* (``float``) --\n          The maximum radius for the main pads.\n          If the radius produced by the radius_ratio parameter for the pad would\n          exceed the maximum radius, the ratio is reduced to limit the radius.\n        * *round_radius_exact* (``float``) --\n          Set an exact round radius for the main pads.\n\n        * *paste_radius_ratio* (``float``) --\n          The radius ratio of the paste pads.\n        * *paste_maximum_radius* (``float``) --\n          The maximum radius for the paste pads.\n          If the radius produced by the paste_radius_ratio parameter for the paste pad would\n          exceed the maximum radius, the ratio is reduced to limit the radius.\n        * *paste_round_radius_exact* (``float``) --\n          Set an exact round radius for the paste pads.\n\n        * *kicad4_compatible* (``bool``) --\n          Makes sure the resulting pad is compatible with kicad 4. default False\n    \"\"\"\n\n    VIA_TENTED = 'all'\n    VIA_TENTED_TOP_ONLY = 'top'\n    VIA_TENTED_BOTTOM_ONLY = 'bottom'\n    VIA_NOT_TENTED = 'none'\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        self.at = Vector2D(kwargs.get('at', [0, 0]))\n        self.size_round_base = kwargs.get('size_round_base', 0.01)\n        self.grid_round_base = kwargs.get('grid_round_base', 0.01)\n\n        self.round_radius_handler = RoundRadiusHandler(default_radius_ratio=0, **kwargs)\n\n        self.kicad4_compatible = kwargs.get('kicad4_compatible', False)\n        self.paste_round_radius_handler = RoundRadiusHandler(\n                radius_ratio=kwargs.get('paste_radius_ratio', 0),\n                maximum_radius=kwargs.get('paste_maximum_radius', None),\n                round_radius_exact=kwargs.get('paste_round_radius_exact', None),\n                kicad4_compatible=self.kicad4_compatible\n            )\n\n        self._initNumber(**kwargs)\n        self._initSize(**kwargs)\n        self._initThermalVias(**kwargs)\n        self._initPaste(**kwargs)\n\n    def _initNumber(self, **kwargs):\n        if not kwargs.get('number'):\n            raise KeyError('pad number for exposed pad not declared (like \"number=9\")')\n        self.number = kwargs.get('number')\n\n    def _initSize(self, **kwargs):\n        if not kwargs.get('size'):\n            raise KeyError('pad size not declared (like \"size=[1,1]\")')\n        self.size = toVectorUseCopyIfNumber(kwargs.get('size'))\n\n        if not kwargs.get('mask_size'):\n            self.mask_size = self.size\n        else:\n            self.mask_size = toVectorUseCopyIfNumber(kwargs.get('mask_size'))\n\n    def setViaLayout(self, layout):\n        self.has_vias = True\n        self.via_layout = toIntArray(layout, min_value=0)\n        if self.via_layout[0] == 0 or self.via_layout[1] == 0:\n            self.has_vias = False\n        return self.has_vias\n\n    def __initViaGrid(self, **kwargs):\n        nx = self.via_layout[0]-1\n        ny = self.via_layout[1]-1\n\n        self.via_grid = kwargs.get('via_grid')\n        if self.via_grid is not None:\n            self.via_grid = toVectorUseCopyIfNumber(self.via_grid, low_limit=self.via_size)\n        else:\n            self.via_grid = Vector2D([\n                    (self.size.x-self.via_size)/(nx if nx > 0 else 1),\n                    (self.size.y-self.via_size)/(ny if ny > 0 else 1)\n                ])\n\n        self.via_grid = self.via_grid.round_to(kwargs.get('grid_round_base', 0))\n\n    def _initThermalVias(self, **kwargs):\n        if not self.setViaLayout(kwargs.get('via_layout', [0, 0])):\n            return\n\n        self.via_drill = kwargs.get('via_drill', 0.3)\n        self.via_size = self.via_drill + 2*kwargs.get('min_annular_ring', 0.15)\n        self.__initViaGrid(**kwargs)\n        self.via_tented = kwargs.get('via_tented', ExposedPad.VIA_TENTED)\n\n        self.bottom_pad_Layers = kwargs.get('bottom_pad_Layers', ['B.Cu'])\n\n        self.add_bottom_pad = True\n        if self.bottom_pad_Layers is None or len(self.bottom_pad_Layers) == 0:\n            self.add_bottom_pad = False\n        else:\n            bottom_pad_min_size = toVectorUseCopyIfNumber(kwargs.get('bottom_pad_min_size', [0, 0]))\n            self.bottom_size = Vector2D([\n                    max((self.via_layout[0]-1)*self.via_grid[0]+self.via_size, bottom_pad_min_size[0]),\n                    max((self.via_layout[1]-1)*self.via_grid[1]+self.via_size, bottom_pad_min_size[1])\n                ])\n\n    def __viasInMaskCount(self, idx):\n        r\"\"\" Determine the number of vias within the soldermask area\n\n        :param idx: (``int``) --\n           determines if the x or y direction is used.\n        \"\"\"\n        if (self.via_layout[idx]-1)*self.via_grid[idx] <= self.paste_area_size[idx]:\n            return self.via_layout[idx]\n        else:\n            return int(self.paste_area_size[idx]//(self.via_grid[idx]))\n\n    def _initPasteForAvoidingVias(self, **kwargs):\n        self.via_clarance = kwargs.get('via_paste_clarance', 0.05)\n\n        # check get against none to allow the caller to use None as the sign to ignore these.\n        if kwargs.get('paste_between_vias') is not None\\\n                or kwargs.get('paste_rings_outside')is not None:\n            self.paste_between_vias = toIntArray(kwargs.get('paste_between_vias', [0, 0]), min_value=0)\n            self.paste_rings_outside = toIntArray(kwargs.get('paste_rings_outside', [0, 0]), min_value=0)\n        else:\n            default = [l-1 for l in self.via_layout]\n            layout = kwargs.get('paste_layout')\n            if layout is None:\n                # alows initializing with 'paste_layout=None' to force default value\n                layout = default\n            self.paste_layout = toIntArray(layout)\n\n            # int(floor(paste_count/(vias_in_mask-1)))\n            self.paste_between_vias = [p//(v-1) if v > 1 else p//v\n                                       for p, v in zip(self.paste_layout, self.vias_in_mask)]\n            inner_count = [(v-1)*p for v, p in zip(self.vias_in_mask, self.paste_between_vias)]\n            self.paste_rings_outside = [(p-i)//2 for p, i in zip(self.paste_layout, inner_count)]\n\n    def _initPaste(self, **kwargs):\n        self.paste_avoid_via = kwargs.get('paste_avoid_via', False)\n        self.paste_reduction = sqrt(kwargs.get('paste_coverage', 0.65))\n\n        self.paste_area_size = Vector2D([min(m, c) for m, c in zip(self.mask_size, self.size)])\n        if self.has_vias:\n            self.vias_in_mask = [self.__viasInMaskCount(i) for i in range(2)]\n\n        if not self.has_vias or not all(self.vias_in_mask):\n            self.paste_avoid_via = False\n\n        if self.has_vias and self.paste_avoid_via:\n            self._initPasteForAvoidingVias(**kwargs)\n        else:\n            self.paste_layout = toIntArray(kwargs.get('paste_layout', [1, 1]))\n\n    def __createPasteIgnoreVia(self):\n        nx = self.paste_layout[0]\n        ny = self.paste_layout[1]\n\n        sx = self.paste_area_size.x\n        sy = self.paste_area_size.y\n\n        paste_size = Vector2D([sx*self.paste_reduction/nx, sy*self.paste_reduction/ny])\\\n            .round_to(self.size_round_base)\n\n        dx = (sx - paste_size[0]*nx)/(nx)\n        dy = (sy - paste_size[1]*ny)/(ny)\n\n        paste_grid = Vector2D(\n                    [paste_size[0]+dx, paste_size[1]+dy]\n                ).round_to(self.grid_round_base)\n\n        return [ChamferedPadGrid(\n                    number=\"\", type=Pad.TYPE_SMT,\n                    center=self.at, size=paste_size, layers=['F.Paste'],\n                    chamfer_size=0, chamfer_selection=0,\n                    pincount=self.paste_layout, grid=paste_grid,\n                    round_radius_handler=self.paste_round_radius_handler\n                    )]\n\n    @staticmethod\n    def __createPasteGrids(original, grid, count, center):\n        r\"\"\" Helper function for creating grids of ChamferedPadGrid sections\n\n        :param original: (``ChamferedPadGrid``) --\n           This instance will be shallow copied to create a grid.\n        :param grid: (``float``, ``Vector2D``) --\n           The spacing between instances\n        :param count: (``int``, ``[int, int]``) --\n           Determines how many copies will be created in x and y direction.\n           If only one number is given, both directions use the same count.\n        :parma center: (``float``, ``Vector2D``) --\n           Center of the resulting grid of grids.\n        \"\"\"\n        pads = []\n        top_left = Vector2D(center)-Vector2D(grid)*(Vector2D(count)-1)/2\n        for idx_x in range(count[0]):\n            x = top_left[0]+idx_x*grid[0]\n            for idx_y in range(count[1]):\n                y = top_left[1]+idx_y*grid[1]\n                pads.append(copy(original))\n                pads[-1].center = Vector2D(x, y)\n        return pads\n\n    def __createPasteAvoidViasInside(self):\n        top_left_area = self.top_left_via+self.via_grid/2\n        self.inner_grid = self.via_grid/Vector2D(self.paste_between_vias)\n\n        if any(self.paste_rings_outside):\n            self.inner_size = self.via_grid/Vector2D(self.paste_between_vias)*self.paste_reduction\n        else:\n            # inner_grid = mask_size/(inner_count)\n            self.inner_size = self.paste_area_size/(self.inner_count)*self.paste_reduction\n\n        corner = ChamferSelPadGrid(0)\n        corner.setCorners()\n        pad = ChamferedPadGrid(\n                number=\"\", type=Pad.TYPE_SMT,\n                center=[0, 0], size=self.inner_size, layers=['F.Paste'],\n                chamfer_size=0, chamfer_selection=corner,\n                pincount=self.paste_between_vias, grid=self.inner_grid,\n                round_radius_handler=self.paste_round_radius_handler\n                )\n\n        if not self.kicad4_compatible:\n            pad.chamferAvoidCircle(\n                        center=self.via_grid/2, diameter=self.via_drill,\n                        clearance=self.via_clarance)\n\n        count = [self.vias_in_mask[0]-1, self.vias_in_mask[1]-1]\n        return ExposedPad.__createPasteGrids(\n                    original=pad, grid=self.via_grid, count=count, center=self.at\n                    )\n\n    def __createPasteOutsideX(self):\n        pads = []\n        corner = ChamferSelPadGrid(\n                    {ChamferSelPadGrid.TOP_RIGHT: 1,\n                     ChamferSelPadGrid.BOTTOM_RIGHT: 1\n                     })\n        x = self.top_left_via[0]-self.ring_size[0]/2\n        y = self.at[1]-(self.via_layout[1]-2)/2*self.via_grid[1]\n\n        pad_side = ChamferedPadGrid(\n            number=\"\", type=Pad.TYPE_SMT,\n            center=[x, y],\n            size=[self.outer_size[0], self.inner_size[1]],\n            layers=['F.Paste'],\n            chamfer_size=0, chamfer_selection=corner,\n            pincount=[self.paste_rings_outside[0], self.paste_between_vias[1]],\n            grid=[self.outer_paste_grid[0], self.inner_grid[1]],\n            round_radius_handler=self.paste_round_radius_handler\n            )\n\n        if not self.kicad4_compatible:\n            pad_side.chamferAvoidCircle(\n                    center=self.top_left_via, diameter=self.via_drill,\n                    clearance=self.via_clarance)\n\n        pads.extend(ExposedPad.__createPasteGrids(\n                    original=pad_side, grid=self.via_grid,\n                    count=[1, self.via_layout[1]-1],\n                    center=[x, self.at['y']]\n                    ))\n\n        corner = ChamferSelPadGrid(\n                    {ChamferSelPadGrid.TOP_LEFT: 1,\n                     ChamferSelPadGrid.BOTTOM_LEFT: 1\n                     })\n        pad_side.chamfer_selection = corner\n\n        x = 2*self.at[0]-x\n        pads.extend(ExposedPad.__createPasteGrids(\n                    original=pad_side, grid=self.via_grid,\n                    count=[1, self.via_layout[1]-1],\n                    center=[x, self.at['y']]\n                    ))\n        return pads\n\n    def __createPasteOutsideY(self):\n        pads = []\n        corner = ChamferSelPadGrid(\n                    {ChamferSelPadGrid.BOTTOM_LEFT: 1,\n                     ChamferSelPadGrid.BOTTOM_RIGHT: 1\n                     })\n\n        x = self.at[0]-(self.via_layout[0]-2)/2*self.via_grid[0]\n        y = self.top_left_via[1]-self.ring_size[1]/2\n\n        pad_side = ChamferedPadGrid(\n            number=\"\", type=Pad.TYPE_SMT,\n            center=[x, y],\n            size=[self.inner_size[0], self.outer_size[1]],\n            layers=['F.Paste'],\n            chamfer_size=0, chamfer_selection=corner,\n            pincount=[self.paste_between_vias[0], self.paste_rings_outside[1]],\n            grid=[self.inner_grid[0], self.outer_paste_grid[1]],\n            round_radius_handler=self.paste_round_radius_handler\n            )\n\n        if not self.kicad4_compatible:\n            pad_side.chamferAvoidCircle(\n                    center=self.top_left_via, diameter=self.via_drill,\n                    clearance=self.via_clarance)\n\n        pads.extend(ExposedPad.__createPasteGrids(\n                    original=pad_side, grid=self.via_grid,\n                    count=[self.via_layout[0]-1, 1],\n                    center=[self.at['x'], y]\n                    ))\n\n        corner = ChamferSelPadGrid(\n                    {ChamferSelPadGrid.TOP_LEFT: 1,\n                     ChamferSelPadGrid.TOP_RIGHT: 1\n                     })\n        pad_side.chamfer_selection = corner\n\n        y = 2*self.at[1]-y\n        pads.extend(ExposedPad.__createPasteGrids(\n                    original=pad_side, grid=self.via_grid,\n                    count=[self.via_layout[0]-1, 1],\n                    center=[self.at['x'], y]\n                    ))\n        return pads\n\n    def __createPasteOutsideCorners(self):\n        pads = []\n        left = self.top_left_via[0]-self.ring_size[0]/2\n        top = self.top_left_via[1]-self.ring_size[1]/2\n        corner = [\n            [\n                {ChamferSelPadGrid.BOTTOM_RIGHT: 1},\n                {ChamferSelPadGrid.TOP_RIGHT: 1}\n                ],\n            [\n                {ChamferSelPadGrid.BOTTOM_LEFT: 1},\n                {ChamferSelPadGrid.TOP_LEFT: 1}\n                ]\n            ]\n        pad_side = ChamferedPadGrid(\n            number=\"\", type=Pad.TYPE_SMT,\n            center=[left, top], size=self.outer_size, layers=['F.Paste'],\n            chamfer_size=0, chamfer_selection=0,\n            pincount=self.paste_rings_outside,\n            grid=self.outer_paste_grid,\n            round_radius_handler=self.paste_round_radius_handler\n            )\n\n        if not self.kicad4_compatible:\n            pad_side.chamferAvoidCircle(\n                    center=self.top_left_via, diameter=self.via_drill,\n                    clearance=self.via_clarance)\n\n        for idx_x in range(2):\n            for idx_y in range(2):\n                x = left if idx_x == 0 else 2*self.at[0]-left\n                y = top if idx_y == 0 else 2*self.at[1]-top\n                pad_side.center = Vector2D(x, y)\n                pad_side.chamfer_selection = ChamferSelPadGrid(corner[idx_x][idx_y])\n                pads.append(copy(pad_side))\n\n        return pads\n\n    def __createPasteAvoidViasOutside(self):\n        self.ring_size = (self.paste_area_size-(Vector2D(self.vias_in_mask)-1)*self.via_grid)/2\n        self.outer_paste_grid = Vector2D([s/p if p != 0 else s\n                                          for s, p in zip(self.ring_size, self.paste_rings_outside)])\n        self.outer_size = self.outer_paste_grid*self.paste_reduction\n\n        pads = []\n        if self.paste_rings_outside[0] and self.inner_count[1] > 0:\n            pads.extend(self.__createPasteOutsideX())\n\n        if self.paste_rings_outside[1] and self.inner_count[0]:\n            pads.extend(self.__createPasteOutsideY())\n\n        if all(self.paste_rings_outside):\n            pads.extend(self.__createPasteOutsideCorners())\n\n        return pads\n\n    def __createPaste(self):\n        pads = []\n        if self.has_vias:\n            self.top_left_via = -(Vector2D(self.vias_in_mask)-1)*self.via_grid/2+self.at\n\n        if self.has_vias and self.paste_avoid_via:\n            self.inner_count = (Vector2D(self.vias_in_mask)-1)*Vector2D(self.paste_between_vias)\n\n            if all(self.vias_in_mask) and all(self.paste_between_vias):\n                pads += self.__createPasteAvoidViasInside()\n            if any(self.paste_rings_outside):\n                pads += self.__createPasteAvoidViasOutside()\n        else:\n            pads += self.__createPasteIgnoreVia()\n\n        return pads\n\n    def __createMainPad(self):\n        pads = []\n        if self.size == self.mask_size:\n            layers_main = ['F.Cu', 'F.Mask']\n        else:\n            layers_main = ['F.Cu']\n            pads.append(Pad(\n                number=\"\", at=self.at, size=self.mask_size,\n                shape=Pad.SHAPE_ROUNDRECT, type=Pad.TYPE_SMT, layers=['F.Mask'],\n                round_radius_handler=self.round_radius_handler\n            ))\n\n        pads.append(Pad(\n            number=self.number, at=self.at, size=self.size,\n            shape=Pad.SHAPE_ROUNDRECT, type=Pad.TYPE_SMT, layers=layers_main,\n            round_radius_handler=self.round_radius_handler\n        ))\n\n        return pads\n\n    def __createVias(self):\n        via_layers = ['*.Cu']\n        if self.via_tented == ExposedPad.VIA_NOT_TENTED or self.via_tented == ExposedPad.VIA_TENTED_BOTTOM_ONLY:\n            via_layers.append('F.Mask')\n        if self.via_tented == ExposedPad.VIA_NOT_TENTED or self.via_tented == ExposedPad.VIA_TENTED_TOP_ONLY:\n            via_layers.append('B.Mask')\n\n        pads = []\n        cy = -((self.via_layout[1]-1)*self.via_grid[1])/2 + self.at.y\n        for i in range(self.via_layout[1]):\n            pads.append(\n                PadArray(center=[self.at.x, cy], initial=self.number,\n                         increment=0, pincount=self.via_layout[0],\n                         x_spacing=self.via_grid[0], size=self.via_size,\n                         type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n                         drill=self.via_drill, layers=via_layers\n                         ))\n            cy += self.via_grid[1]\n\n        if self.add_bottom_pad:\n            pads.append(Pad(\n                number=self.number, at=self.at, size=self.bottom_size,\n                shape=Pad.SHAPE_ROUNDRECT, type=Pad.TYPE_SMT,\n                layers=self.bottom_pad_Layers,\n                round_radius_handler=self.round_radius_handler\n            ))\n\n        return pads\n\n    def getVirtualChilds(self):\n        # traceback.print_stack()\n        if self.has_vias:\n            self.round_radius_handler.limitMaxRadius(self.via_size/2)\n\n        pads = []\n        pads += self.__createMainPad()\n        if self.has_vias:\n            pads += self.__createVias()\n        pads += self.__createPaste()\n        return pads\n\n    def getRoundRadius(self):\n        return self.round_radius_handler.getRoundRadius(min(self.size))\n"
  },
  {
    "path": "KicadModTree/nodes/specialized/FilledRect.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\nfrom KicadModTree.nodes.specialized import RectLine\nfrom KicadModTree.nodes.specialized import RectFill\n\n\nclass FilledRect(Node):\n    r\"\"\"Add a Filled Rect to the render tree\n\n    Combines ``RectLine`` and ``RectFill`` into one class for simpler handling\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *start* (``Vector2D``) --\n          start edge of the rect\n        * *end* (``Vector2D``) --\n          end edge of the rect\n        * *layer* (``str``) --\n          layer on which the rect is drawn (default: 'F.SilkS')\n        * *width* (``float``) --\n          width of the outer line (default: 0.15)\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> FilledRect(start=[-3, -2], end=[3, 2], layer='F.SilkS')\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        self.start_pos = Vector2D(kwargs['start'])\n        self.end_pos = Vector2D(kwargs['end'])\n\n        self.layer = kwargs.get('layer', 'F.SilkS')\n        self.width = kwargs.get('width', 0.12)  # TODO: better variation to get line width\n\n        rect_line = RectLine(**kwargs)\n        rect_line._parent = self\n\n        rect_fill = RectFill(**kwargs)\n        rect_fill._parent = self\n\n        self.virtual_childs = [rect_line, rect_fill]\n\n    def getVirtualChilds(self):\n        return self.virtual_childs\n\n    def _getRenderTreeText(self):\n        render_text = Node._getRenderTreeText(self)\n\n        render_string = ['start: [x: {sx}, y: {sy}]'.format(sx=self.start_pos.x, sy=self.start_pos.y),\n                         'end: [x: {ex}, y: {ey}]'.format(ex=self.end_pos.x, ey=self.end_pos.y)]\n\n        render_text += \" [{}]\".format(\", \".join(render_string))\n\n        return render_text\n"
  },
  {
    "path": "KicadModTree/nodes/specialized/PadArray.py",
    "content": "#!/usr/bin/env python\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2017 by @SchrodingersGat\n# (C) 2017 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom types import GeneratorType\nfrom KicadModTree.nodes.base.Pad import *\nfrom KicadModTree.nodes.specialized.ChamferedPad import *\nfrom KicadModTree.nodes.Node import Node\n\nfrom KicadModTree.util.paramUtil import *\n\n\nclass PadArray(Node):\n    r\"\"\"Add a row of Pads\n\n    Simplifies the handling of pads which are rendered in a specific form\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *start* (``Vector2D``) --\n          start edge of the pad array\n        * *center* (``Vector2D``) --\n          center pad array around specific point\n        * *pincount* (``int``) --\n          number of pads to render\n        * *spacing* (``Vector2D``, ``float``) --\n          offset between rendered pads\n        * *x_spacing* (``float``) --\n          x offset between rendered pads\n        * *y_spacing* (``float``) --\n          y offset between rendered pads\n        * *initial* (``int``) --\n          name of the first pad\n        * *increment* (``int, function(previous_number)``) --\n          declare how the name of the follow up is calculated\n        * *type* (``Pad.TYPE_THT``, ``Pad.TYPE_SMT``, ``Pad.TYPE_CONNECT``, ``Pad.TYPE_NPTH``) --\n          type of the pad\n        * *shape* (``Pad.SHAPE_CIRCLE``, ``Pad.SHAPE_OVAL``, ``Pad.SHAPE_RECT``, ``Pad.SHAPE_TRAPEZE``, ...) --\n          shape of the pad\n        * *rotation* (``float``) --\n          rotation of the pad\n        * *size* (``float``, ``Vector2D``) --\n          size of the pad\n        * *offset* (``Vector2D``) --\n          offset of the pad\n        * *drill* (``float``, ``Vector2D``) --\n          drill-size of the pad\n        * *solder_paste_margin_ratio* (``float``) --\n          solder paste margin ratio of the pad\n        * *layers* (``Pad.LAYERS_SMT``, ``Pad.LAYERS_THT``, ``Pad.LAYERS_NPTH``) --\n          layers on which are used for the pad\n        * *chamfer_corner_selection_first* (``[bool, bool, bool, bool]``)\n          Select which corner should be chamfered for the first pad. (default: None)\n        * *chamfer_corner_selection_last* (``[bool, bool, bool, bool]``)\n          Select which corner should be chamfered for the last pad. (default: None)\n        * *chamfer_size* (``float``, ``Vector2D``) --\n          size for the chamfer used for the end pads. (default: None)\n\n        * *end_pads_size_reduction* (``dict with keys x-,x+,y-,y+``) --\n          size is reduced on the given side. (size reduced plus center moved.)\n        * *tht_pad1_shape* (``Pad.SHAPE_RECT``, ``Pad.SHAPE_ROUNDRECT``, ...) --\n          shape for marking pad 1 for through hole components. (deafult: ``Pad.SHAPE_ROUNDRECT``)\n        * *tht_pad1_id* (``int, string``) --\n          pad number used for \"pin 1\" (default: 1)\n        * *hidden_pins* (``int, Vector1D``) --\n          pin number(s) to be skipped; a footprint with hidden pins has missing pads and matching pin numbers\n        * *deleted_pins* (``int, Vector1D``) --\n          pin locations(s) to be skipped; a footprint with deleted pins has pads missing but no missing pin numbers\"\n\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> PadArray(pincount=10, spacing=[1,-1], center=[0,0], initial=5, increment=2,\n    ...          type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[1,2], layers=Pad.LAYERS_SMT)\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        self._initPincount(**kwargs)\n        self._initIncrement(**kwargs)\n        self._initInitialNumber(**kwargs)\n        self._initSpacing(**kwargs)\n        self._initStartingPosition(**kwargs)\n        self.virtual_childs = self._createPads(**kwargs)\n\n    # How many pads in the array\n    def _initPincount(self, **kwargs):\n        if not kwargs.get('pincount'):\n            raise KeyError('pincount not declared (like \"pincount=10\")')\n        self.pincount = kwargs.get('pincount')\n        if type(self.pincount) is not int or self.pincount <= 0:\n            raise ValueError('{pc} is an invalid value for pincount'.format(pc=self.pincount))\n\n        if kwargs.get('hidden_pins') and kwargs.get('deleted_pins'):\n            raise KeyError('hidden pins and deleted pins cannot be used together')\n\n        self.exclude_pin_list = []\n        if kwargs.get('hidden_pins'):\n            # exclude_pin_list is for pads being removed based on pad number\n            # deleted pins are filtered out later by pad location (not number)\n            self.exclude_pin_list = kwargs.get('hidden_pins')\n\n            if type(self.exclude_pin_list) not in [list, tuple]:\n                raise TypeError('exclude pin list must be specified like \"exclude_pin_list=[0,1]\"')\n            elif any([type(i) not in [int] for i in self.exclude_pin_list]):\n                raise ValueError('exclude pin list must be integer value')\n\n    # Where to start the aray\n    def _initStartingPosition(self, **kwargs):\n        \"\"\"\n        can use the 'start' argument to start a pad array at a given position\n        OR\n        can use the 'center' argument to center the array around the given position\n        \"\"\"\n        self.startingPosition = [0, 0]\n\n        # Start takes priority\n        if kwargs.get('start'):\n            self.startingPosition = kwargs.get('start')\n            if type(self.startingPosition) not in [list, tuple] or not len(self.startingPosition) == 2:\n                raise ValueError('array starting position \"start\" must be given as an list of length two')\n            if any([type(i) not in [int, float] for i in self.startingPosition]):\n                raise ValueError('array starting coordinates must be numerical')\n        elif kwargs.get('center'):\n            center = kwargs.get('center')\n\n            if type(center) not in [list, tuple] or not len(center) == 2:\n                raise ValueError('array center position \"center\" must be given as a list of length two')\n            if any([type(i) not in [int, float] for i in center]):\n                raise ValueError('array center coordinates must be numerical')\n\n            # Now calculate the desired starting position of the array\n            self.startingPosition[0] = center[0] - (self.pincount - 1) * self.spacing[0] / 2.\n            self.startingPosition[1] = center[1] - (self.pincount - 1) * self.spacing[1] / 2.\n\n    # What number to start with?\n    def _initInitialNumber(self, **kwargs):\n        self.initialPin = kwargs.get('initial', 1)\n        if self.initialPin == \"\":\n            self.increment = 0\n        elif type(self.initialPin) is not int or self.initialPin < 1:\n            if not callable(self.increment):\n                raise ValueError('{pn} is not a valid starting pin number if increment is not a function'\n                                 .format(pn=self.initialPin))\n\n    # Pin incrementing\n    def _initIncrement(self, **kwargs):\n        self.increment = kwargs.get('increment', 1)\n\n    # Pad spacing\n    def _initSpacing(self, **kwargs):\n        \"\"\"\n        spacing can be given as:\n        spacing = [1,2] # high priority\n        x_spacing = 1\n        y_spacing = 2\n        \"\"\"\n\n        self.spacing = [0, 0]  # [x, y]\n\n        if kwargs.get('spacing'):\n            self.spacing = kwargs.get('spacing')\n            if type(self.spacing) not in [list, tuple]:\n                raise TypeError('spacing must be specified like \"spacing=[0,1]\"')\n            elif len(self.spacing) is not 2:\n                raise ValueError('spacing must be supplied as x,y pair')\n            elif any([type(i) not in [int, float] for i in self.spacing]):\n                raise ValueError('spacing must be numerical value')\n            # if 'spacing' is specified, ignore x_spacing and y_spacing\n            return\n\n        if kwargs.get('x_spacing'):\n            self.spacing[0] = kwargs.get('x_spacing')\n            if type(self.spacing[0]) not in [int, float]:\n                raise ValueError('x_spacing must be supplied as numerical value')\n\n        if kwargs.get('y_spacing'):\n            self.spacing[1] = kwargs.get('y_spacing')\n            if type(self.spacing[1]) not in [int, float]:\n                raise ValueError('y_spacing must be supplied as numerical value')\n\n        if all([i == 0 for i in self.spacing]):\n            raise ValueError('pad spacing ({sp}) must be non-zero'.format(sp=self.spacing))\n\n    def _createPads(self, **kwargs):\n\n        pads = []\n\n        x_start, y_start = self.startingPosition\n        x_spacing, y_spacing = self.spacing\n\n        padShape = kwargs.get('shape')\n\n        # Special case, increment = 0\n        # this can be used for creating an array with all the same pad number\n        if self.increment == 0:\n            pad_numbers = [self.initialPin] * self.pincount\n        elif type(self.increment) == int:\n            pad_numbers = range(self.initialPin, self.initialPin + (self.pincount * self.increment), self.increment)\n        elif callable(self.increment):\n            pad_numbers = [self.initialPin]\n            for idx in range(1, self.pincount):\n                pad_numbers.append(self.increment(pad_numbers[-1]))\n        elif type(self.increment) == GeneratorType:\n            pad_numbers = [next(self.increment) for i in range(self.pincount)]\n        else:\n            raise TypeError(\"Wrong type for increment. It must be either a int, callable or generator.\")\n\n        end_pad_params = copy(kwargs)\n        if kwargs.get('end_pads_size_reduction'):\n            size_reduction = kwargs['end_pads_size_reduction']\n            end_pad_params['size'] = toVectorUseCopyIfNumber(kwargs.get('size'), low_limit=0)\n\n            delta_size = Vector2D(\n                size_reduction.get('x+', 0) + size_reduction.get('x-', 0),\n                size_reduction.get('y+', 0) + size_reduction.get('y-', 0)\n                )\n\n            end_pad_params['size'] -= delta_size\n\n            delta_pos = Vector2D(\n                -size_reduction.get('x+', 0) + size_reduction.get('x-', 0),\n                -size_reduction.get('y+', 0) + size_reduction.get('y-', 0)\n                )/2\n        else:\n            delta_pos = Vector2D(0, 0)\n\n        for i, number in enumerate(pad_numbers):\n            includePad = True\n\n            # deleted pins are filtered by pad/pin position (they are 'None' in pad_numbers list)\n            if type(number) not in [int, str]:\n                includePad = False\n\n            # hidden pins are filtered out by pad number (index of pad_numbers list)\n            if not kwargs.get('deleted_pins'):\n                if type(self.initialPin) == 'int':\n                    includePad = (self.initialPin + i) not in self.exclude_pin_list\n                else:\n                    includePad = number not in self.exclude_pin_list\n\n            if includePad:\n                current_pad_pos = Vector2D(\n                    x_start + i * x_spacing,\n                    y_start + i * y_spacing\n                    )\n                current_pad_params = copy(kwargs)\n                if i == 0 or i == len(pad_numbers)-1:\n                    current_pad_pos += delta_pos\n                    current_pad_params = end_pad_params\n                if kwargs.get('type') == Pad.TYPE_THT and number == kwargs.get('tht_pad1_id', 1):\n                    current_pad_params['shape'] = kwargs.get('tht_pad1_shape', Pad.SHAPE_ROUNDRECT)\n                    if 'radius_ratio' not in current_pad_params:\n                        current_pad_params['radius_ratio'] = 0.25\n                    if 'maximum_radius' not in current_pad_params:\n                        current_pad_params['maximum_radius'] = 0.25\n                else:\n                    current_pad_params['shape'] = padShape\n                if kwargs.get('chamfer_size'):\n                    if i == 0 and 'chamfer_corner_selection_first' in kwargs:\n                        pads.append(\n                            ChamferedPad(\n                                number=number, at=current_pad_pos,\n                                corner_selection=kwargs.get('chamfer_corner_selection_first'),\n                                **current_pad_params\n                                ))\n                        continue\n                    if i == len(pad_numbers)-1 and 'chamfer_corner_selection_last' in kwargs:\n                        pads.append(\n                            ChamferedPad(\n                                number=number, at=current_pad_pos,\n                                corner_selection=kwargs.get('chamfer_corner_selection_last'),\n                                **current_pad_params\n                                ))\n                        continue\n                pads.append(Pad(number=number, at=current_pad_pos, **current_pad_params))\n\n        return pads\n\n    def getVirtualChilds(self):\n        return self.virtual_childs\n"
  },
  {
    "path": "KicadModTree/nodes/specialized/PolygoneLine.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.PolygonPoints import *\nfrom KicadModTree.nodes.Node import Node\nfrom KicadModTree.nodes.base.Line import Line\n\n\nclass PolygoneLine(Node):\n    r\"\"\"Add a Polygone Line to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *polygone* (``list(Point)``) --\n          edges of the polygone\n        * *layer* (``str``) --\n          layer on which the polygone is drawn (default: 'F.SilkS')\n        * *width* (``float``) --\n          width of the line (default: None, which means auto detection)\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> PolygoneLine(polygone=[[0, 0], [0, 1], [1, 1], [0, 0]], layer='F.SilkS')\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n\n        self.layer = kwargs.get('layer', 'F.SilkS')\n        self.width = kwargs.get('width')\n\n        self._initPolyPoint(**kwargs)\n\n        self.virtual_childs = self._createChildNodes(self.nodes)\n\n    def _initPolyPoint(self, **kwargs):\n        self.nodes = PolygonPoints(**kwargs)\n\n    def _createChildNodes(self, polygone_line):\n        nodes = []\n\n        for line_start, line_end in zip(polygone_line, polygone_line[1:]):\n            new_node = Line(start=line_start, end=line_end, layer=self.layer, width=self.width)\n            new_node._parent = self\n            nodes.append(new_node)\n\n        return nodes\n\n    def getVirtualChilds(self):\n        return self.virtual_childs\n\n    def _getRenderTreeText(self):\n        render_text = Node._getRenderTreeText(self)\n        render_text += \" [\"\n\n        node_strings = []\n        for node in self.nodes:\n            node_position = Vector2D(node)\n            node_strings.append(\"[x: {x}, y: {y}]\".format(x=node_position.x,\n                                                          y=node_position.y))\n\n        if len(node_strings) <= 6:\n            render_text += \" ,\".join(node_strings)\n        else:\n            # display only a few nodes of the beginning and the end of the polygone line\n            render_text += \" ,\".join(node_strings[:3])\n            render_text += \" ,... ,\"\n            render_text += \" ,\".join(node_strings[-3:])\n\n        render_text += \"]\"\n\n        return render_text\n"
  },
  {
    "path": "KicadModTree/nodes/specialized/RectFill.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\nfrom KicadModTree.nodes.base import Line\n\n\nclass RectFill(Node):\n    r\"\"\"Add the filling of a Rect to the render tree\n\n    Normally, this class isn't needed, because ``FilledRect`` combines ``RectLine`` with ``RectFill``\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *start* (``Vector2D``) --\n          start edge of the rect fill\n        * *end* (``Vector2D``) --\n          end edge of the rect fill\n        * *layer* (``str``) --\n          layer on which the rect fill is drawn (default: 'F.SilkS')\n        * *width* (``float``) --\n          width of the filling lines (default: 0.12)\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> RectFill(start=[-3, -2], end=[3, 2], layer='F.SilkS')\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        self.start_pos = Vector2D(kwargs['start'])\n        self.end_pos = Vector2D(kwargs['end'])\n\n        self.layer = kwargs.get('layer', 'F.SilkS')\n        self.width = kwargs.get('width', 0.12)  # TODO: auto detection\n\n        self.virtual_childs = self._createChildNodes(self.start_pos, self.end_pos, self.layer, self.width)\n\n    def _createChildNodes(self, start_pos, end_pos, layer, width):\n        nodes = []\n\n        cur_y_pos = min([start_pos.y, end_pos.y])\n        max_y_pos = max([start_pos.y, end_pos.y])\n\n        while (cur_y_pos + width) < max_y_pos:\n            cur_y_pos += width\n            new_node = Line(start=Vector2D(start_pos.x, cur_y_pos),\n                            end=Vector2D(end_pos.x, cur_y_pos),\n                            layer=layer,\n                            width=width)\n            new_node._parent = self\n            nodes.append(new_node)\n\n        return nodes\n\n    def getVirtualChilds(self):\n        return self.virtual_childs\n\n    def _getRenderTreeText(self):\n        render_text = Node._getRenderTreeText(self)\n\n        render_string = ['start: [x: {sx}, y: {sy}]'.format(sx=self.start_pos.x, sy=self.start_pos.y),\n                         'end: [x: {ex}, y: {ey}]'.format(ex=self.end_pos.x, ey=self.end_pos.y)]\n\n        render_text += \" [{}]\".format(\", \".join(render_string))\n\n        return render_text\n"
  },
  {
    "path": "KicadModTree/nodes/specialized/RectLine.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\nfrom .PolygoneLine import PolygoneLine\n\n\nclass RectLine(PolygoneLine):\n    r\"\"\"Add a Rect to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *start* (``Vector2D``) --\n          start edge of the rect\n        * *end* (``Vector2D``) --\n          end edge of the rect\n        * *layer* (``str``) --\n          layer on which the rect is drawn\n        * *width* (``float``) --\n          width of the outer line (default: None, which means auto detection)\n        * *offset* (``Vector2D``, ``float``) --\n          offset of the rect line to the specified one\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> RectLine(start=[-3, -2], end=[3, 2], layer='F.SilkS')\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        self.start_pos = Vector2D(kwargs['start'])\n        self.end_pos = Vector2D(kwargs['end'])\n\n        # If specifed, an 'offset' can be applied to the RectLine.\n        # For example, creating a border around a given Rect of a specified size\n        if kwargs.get('offset'):\n            # offset for the rect line\n            # e.g. for creating a rectLine 0.5mm LARGER than the given rect, or similar\n            offset = [0, 0]\n\n            # Has an offset / inset been specified?\n            if type(kwargs['offset']) in [int, float]:\n                offset[0] = offset[1] = kwargs['offset']\n            elif type(kwargs['offset']) in [list, tuple] and len(kwargs['offset']) == 2:\n                # Ensure that all offset params are numerical\n                if all([type(i) in [int, float] for i in kwargs['offset']]):\n                    offset = kwargs['offset']\n\n            # For the offset to work properly, start-pos must be top-left, and end-pos must be bottom-right\n            x1 = min(self.start_pos.x, self.end_pos.x)\n            x2 = max(self.start_pos.x, self.end_pos.x)\n\n            y1 = min(self.start_pos.y, self.end_pos.y)\n            y2 = max(self.start_pos.y, self.end_pos.y)\n\n            # Put the offset back in\n            self.start_pos.x = x1 - offset[0]\n            self.start_pos.y = y1 - offset[1]\n\n            self.end_pos.x = x2 + offset[0]\n            self.end_pos.y = y2 + offset[1]\n\n        polygone_line = [{'x': self.start_pos.x, 'y': self.start_pos.y},\n                         {'x': self.start_pos.x, 'y': self.end_pos.y},\n                         {'x': self.end_pos.x, 'y': self.end_pos.y},\n                         {'x': self.end_pos.x, 'y': self.start_pos.y},\n                         {'x': self.start_pos.x, 'y': self.start_pos.y}]\n\n        PolygoneLine.__init__(self, polygone=polygone_line, layer=kwargs['layer'], width=kwargs.get('width'))\n\n    def _getRenderTreeText(self):\n        render_text = Node._getRenderTreeText(self)\n        render_text += \" [start: [x: {sx}, y: {sy}] end: [x: {ex}, y: {ey}]]\".format(sx=self.start_pos.x,\n                                                                                     sy=self.start_pos.y,\n                                                                                     ex=self.end_pos.x,\n                                                                                     ey=self.end_pos.y)\n\n        return render_text\n"
  },
  {
    "path": "KicadModTree/nodes/specialized/RingPad.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n# (C) 2018 by Rene Poeschl, github @poeschlr\nfrom __future__ import division\n\nfrom copy import copy\nfrom KicadModTree.nodes.Node import Node\nfrom KicadModTree.util.paramUtil import *\nfrom KicadModTree.util.geometric_util import geometricArc, geometricLine, BaseNodeIntersection\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.base.Pad import Pad\nfrom KicadModTree.nodes.base.Circle import Circle\nfrom KicadModTree.nodes.base.Arc import Arc\nfrom KicadModTree.nodes.base.Line import Line\nfrom math import sqrt, sin, cos, pi, ceil\n\n\nclass RingPadPrimitive(Node):\n    r\"\"\"Add a RingPad to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n      * *radius*: (``float``) --\n        middle radius of the ring\n      * *width*: (``float``) --\n        width of the ring (outer radius - inner radius)\n      * *at*: (``Vector2D``) --\n        position of the center\n      * *layers*: (``Pad.Layers``) --\n        layers used for creating the pad\n      * *number* (``int``, ``str``) --\n        number/name of the pad (default: \\\"\\\")\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        self.at = Vector2D(kwargs.get('at', (0, 0)))\n        self.radius = float(kwargs['radius'])\n        self.width = float(kwargs['width'])\n        self.layers = kwargs['layers']\n        self.number = kwargs.get('number', \"\")\n\n    def copy(self):\n        return RingPadPrimitive(\n                    at=self.at, radius=self.radius,\n                    width=self.width, layers=self.layers,\n                    number=self.number\n                    )\n\n    def getVirtualChilds(self):\n        return [Pad(number=self.number,\n                    type=Pad.TYPE_SMT, shape=Pad.SHAPE_CUSTOM,\n                    at=(self.at+Vector2D(self.radius, 0)),\n                    size=self.width, layers=self.layers,\n                    primitives=[Circle(\n                        center=(-self.radius, 0),\n                        radius=self.radius,\n                        width=self.width\n                        )]\n                    )]\n\n\nclass ArcPadPrimitive(Node):\n    r\"\"\"Add a RingPad to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *number* (``int``, ``str``) --\n          number/name of the pad (default: \\\"\\\")\n        * *width* (``float``) --\n          width of the pad\n        * *layers* (``Pad.Layers``) --\n          layers on which are used for the pad\n        * *round_radius_ratio* (``float``) --\n          round radius.\n          default: 25\\% of ring width\n        * *max_round_radius* (``float``) --\n          maximum round radius, default: 0.25\n          Use none to ignore\n        * *reference_arc* (``geometricArc``) --\n          the reference arc used for this pad\n        * *start_line* (``geometricLine``) --\n          line confining the side near the reference points start point\n        * *end_line* (``geometricLine``) --\n          line confining the side near the reference points end point\n        * *minimum_overlap* (``float``)\n          minimum overlap. default 0.1\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        self.reference_arc = geometricArc(geometry=kwargs['reference_arc'])\n        self.width = float(kwargs['width'])\n\n        self.number = kwargs.get('number', \"\")\n        self.layers = kwargs['layers']\n        self.minimum_overlap = kwargs.get('minimum_overlap', 0.1)\n\n        self.setRoundRadius(**kwargs)\n        self.setLimitingLines(**kwargs)\n\n    def setRoundRadius(self, **kwargs):\n        if 'round_radius' in kwargs:\n            self.round_radius = kwargs['round_radius']\n            return\n\n        round_radius_ratio = kwargs.get('round_radius_ratio', 0.25)\n        max_round_radius = kwargs.get('max_round_radius', 0.25)\n        r = self.width*round_radius_ratio\n        if max_round_radius is not None and max_round_radius > 0:\n            self.round_radius = min(r, max_round_radius)\n\n    def setLimitingLines(self, **kwargs):\n        if kwargs.get('start_line') is not None:\n            self.start_line = geometricLine(geometry=kwargs.get('start_line'))\n        else:\n            self.start_line = None\n        if kwargs.get('end_line') is not None:\n            self.end_line = geometricLine(geometry=kwargs.get('end_line'))\n        else:\n            self.end_line = None\n\n    def copy(self):\n        return ArcPadPrimitive(\n                    reference_arc=self.reference_arc,\n                    width=self.width,\n                    round_radius=self.round_radius,\n                    number=self.number,\n                    layers=self.layers,\n                    start_line=self.start_line,\n                    end_line=self.end_line,\n                    minimum_overlap=self.minimum_overlap\n                    )\n\n    def rotate(self, angle, origin=(0, 0), use_degrees=True):\n        r\"\"\" Rotate around given origin\n\n        :params:\n            * *angle* (``float``)\n                rotation angle\n            * *origin* (``Vector2D``)\n                origin point for the rotation. default: (0, 0)\n            * *use_degrees* (``boolean``)\n                rotation angle is given in degrees. default:True\n        \"\"\"\n\n        self.reference_arc.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        if self.start_line is not None:\n            self.start_line.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        if self.end_line is not None:\n            self.end_line.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        return self\n\n    def translate(self, distance_vector):\n        r\"\"\" Translate\n\n        :params:\n            * *distance_vector* (``Vector2D``)\n                2D vector defining by how much and in what direction to translate.\n        \"\"\"\n\n        self.reference_arc.translate(distance_vector)\n        if self.start_line is not None:\n            self.start_line.translate(distance_vector)\n        if self.end_line is not None:\n            self.end_line.translate(distance_vector)\n        return self\n\n    def _getStep(self):\n        line_width = self.round_radius*2\n        if self.minimum_overlap >= line_width:\n            raise ValueError('arc line width (round radius) too small for requested overlap')\n\n        required_arcs = ceil((self.width-self.minimum_overlap) / (line_width-self.minimum_overlap))\n        return (self.width-line_width)/(required_arcs-1)\n\n    def _getArcPrimitives(self):\n        line_width = self.round_radius*2\n        step = self._getStep()\n\n        r_inner = self.reference_arc.getRadius()-self.width/2+line_width/2\n        r_outer = self.reference_arc.getRadius()+self.width/2-line_width/2\n\n        ref_arc = Arc(geometry=self.reference_arc, width=line_width).setRadius(r_outer)\n\n        nodes = []\n        r = r_inner\n        while r < r_outer:\n            nodes.append(ref_arc.copy().setRadius(r))\n            r += step\n        nodes.append(ref_arc)\n\n        if self.start_line is not None:\n            nodes = self.__cutArcs(nodes, self.start_line, 1)\n        if self.end_line is not None:\n            nodes = self.__cutArcs(nodes, self.end_line, 0)\n        nodes.append(Line(start=nodes[0].getEndPoint(), end=nodes[-1].getEndPoint(), width=line_width))\n        nodes.append(Line(start=nodes[0].getStartPoint(), end=nodes[-2].getStartPoint(), width=line_width))\n\n        return nodes\n\n    def __cutArcs(self, arcs, line, index_to_keep):\n        if line is None:\n            return arcs\n        result = []\n        for current_arc in arcs:\n            try:\n                result.append(current_arc.cut(line)[index_to_keep])\n            except IndexError as e:\n                raise ValueError(\"Cutting the arc primitive with one of its endlines \" +\n                                 \"did not result in the expected number of arcs.\")\n        return result\n\n    def getVirtualChilds(self):\n        at = self.reference_arc.getMidPoint()\n        primitives = self._getArcPrimitives()\n        for p in primitives:\n            p.translate(-at)\n        return [Pad(\n                    number=self.number,\n                    type=Pad.TYPE_SMT, shape=Pad.SHAPE_CUSTOM,\n                    at=at, size=self.width/2, layers=self.layers,\n                    primitives=primitives\n                    )]\n\n\nclass RingPad(Node):\n    r\"\"\"Add a RingPad to the render tree\n\n    :param \\**kwargs:\n        See below\n\n    :Keyword Arguments:\n        * *number* (``int``, ``str``) --\n          number/name of the pad (default: \\\"\\\")\n        * *at* (``Vector2D``) --\n          center position of the pad\n        * *rotation* (``float``) --\n          rotation of the pad\n        * *inner_diameter* (``float``) --\n          diameter of the copper free inner zone\n        * *size* (``float``) --\n          outside diameter of the pad\n        * *num_anchors* (``int``) --\n          number of anchor pads around the circle\n        * *num_paste_zones* (``int``) --\n          number of paste zones\n        * *paste_to_paste_clearance* (``float``) --\n          clearance between two paste zones,\n          needed only if number of paste zones > 1\n          default: 2*abs(solder_paste_margin)\n        * *paste_round_radius_radio* (``float``) --\n          round over radius ratio. default 0.25\n          resulting radius must be larger than minimum overlap\n        * *paste_max_round_radius* (``float``) --\n          maximum round radius.\n          Only used if number of paste zones > 1\n          default: 0.25\n          set to None to ignore\n        * *solder_paste_margin* (``float``) --\n          solder paste margin of the pad (default: 0)\n        * *paste_outer_diameter* (``float``) --\n          together with paste inner diameter an alternative for defining the paste area\n        * *paste_inner_diameter* (``float``) --\n          together with paste outer diameter an alternative for defining the paste area\n        * *solder_mask_margin* (``float``) --\n          solder mask margin of the pad (default: 0)\n        * *minimum_overlap* (``float``) --\n          minimum arc overlap. default 0.1\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        Node.__init__(self)\n        self.solder_mask_margin = kwargs.get('solder_mask_margin', 0)\n        self.minimum_overlap = kwargs.get('minimum_overlap', 0.1)\n        self._initPosition(**kwargs)\n        self._initSize(**kwargs)\n        self._initNumber(**kwargs)\n        self._initPasteSettings(**kwargs)\n        self._initNumAnchor(**kwargs)\n        self._generatePads()\n\n    def _initSize(self, **kwargs):\n        _id = kwargs.get('inner_diameter')\n        _od = kwargs.get('size')\n        if _od is None or _id is None:\n            raise KeyError('pad size or inside diameter not declared (like \"size=1, inner_diameter=0.5\")')\n        if type(_id) not in [int, float] or type(_od) not in [int, float]:\n            raise ValueError('ring pad size and inner_diameter only support int or float')\n        if _id >= _od:\n            raise ValueError('inner diameter must be larger than size')\n\n        self.radius = (_id+_od)/4\n        self.width = (_od-_id)/2\n        self.size = _od\n        self.is_circle = _id == 0\n\n    def _initNumber(self, **kwargs):\n        self.number = kwargs.get('number', \"\")  # default to an un-numbered pad\n\n    def _initNumAnchor(self, **kwargs):\n        self.num_anchor = int(kwargs.get('num_anchor', 1))\n        if self.num_anchor < 1:\n            raise ValueError('num_anchor must be a positive integer')\n\n    def _initPosition(self, **kwargs):\n        if 'at' not in kwargs:\n            raise KeyError('center position not declared (like \"at=[0,0]\")')\n        self.at = Vector2D(kwargs.get('at'))\n\n    def _initPasteSettings(self, **kwargs):\n        self.solder_paste_margin = kwargs.get('solder_paste_margin', 0)\n        if 'paste_outer_diameter' in kwargs and 'paste_inner_diameter' in kwargs:\n            self.paste_width = (kwargs['paste_outer_diameter'] - kwargs['paste_inner_diameter'])/2\n            self.paste_center = (kwargs['paste_outer_diameter'] + kwargs['paste_inner_diameter'])/4\n        else:\n            self.paste_width = self.width + 2*self.solder_paste_margin\n            self.paste_center = self.radius\n\n        self.num_paste_zones = int(kwargs.get('num_paste_zones', 1))\n        if self.num_paste_zones < 1:\n            raise ValueError('num_paste_zones must be a positive integer')\n\n        if self.num_paste_zones > 1:\n            self.paste_max_round_radius = float(kwargs.get('paste_max_round_radius', 0.25))\n            self.paste_round_radius_radio = float(\n                kwargs.get('paste_round_radius_radio', 0.25))\n\n            self.paste_to_paste_clearance = kwargs.get('paste_to_paste_clearance')\n            if self.paste_to_paste_clearance is None:\n                self.paste_to_paste_clearance = -self.solder_paste_margin\n\n            if self.paste_round_radius_radio <= 0:\n                raise ValueError('paste_round_radius_radio must be > 0')\n            if self.paste_max_round_radius is not None and self.paste_max_round_radius <= 0:\n                raise ValueError('paste_max_round_radius must be > 0')\n\n            if self.paste_to_paste_clearance <= 0:\n                raise ValueError('paste_to_paste_clearance must be > 0')\n\n    def _generatePads(self):\n        self.pads = []\n        if self.num_paste_zones > 1:\n            layers = ['F.Cu', 'F.Mask']\n            self._generatePastePads()\n        else:\n            layers = ['F.Cu', 'F.Mask', 'F.Paste']\n\n        if not self.is_circle:\n            self._generateCopperPads()\n        else:\n            self.pads.append(\n                Pad(number=self.number,\n                    type=Pad.TYPE_SMT, shape=Pad.SHAPE_CIRCLE,\n                    at=(self.at), size=self.size,\n                    layers=layers\n                    ))\n\n    def _generatePastePads(self):\n        ref_angle = 360/self.num_paste_zones\n\n        ref_arc = geometricArc(\n                    center=self.at,\n                    start=self.at+(self.paste_center, 0),\n                    angle=ref_angle)\n\n        pad = ArcPadPrimitive(\n                            number=\"\", width=self.paste_width,\n                            round_radius_ratio=self.paste_round_radius_radio,\n                            max_round_radius=self.paste_max_round_radius,\n                            layers=['F.Paste'], reference_arc=ref_arc,\n                            minimum_overlap=self.minimum_overlap\n                            )\n\n        w = pad.round_radius*2\n        y = (self.paste_to_paste_clearance + w)/2\n\n        start_line = geometricLine(start=self.at+(0, y), end=self.at+(1, y))\n        end_line = geometricLine(start=self.at+(0, -y), end=self.at+(1, -y)).rotate(ref_angle, origin=self.at)\n\n        if self.num_paste_zones == 2:\n            end_line = None\n\n        pad.setLimitingLines(start_line=start_line, end_line=end_line)\n\n        self.pads.append(pad)\n        for i in range(1, self.num_paste_zones):\n            self.pads.append(pad.copy().rotate(i*ref_angle, origin=self.at))\n\n    def _generateMaskPads(self):\n        w = self.width+2*self.solder_mask_margin\n        self.pads.append(\n            RingPadPrimitive(\n                number=\"\",\n                at=self.at,\n                width=self.width+2*self.solder_mask_margin,\n                layers=['F.Mask'],\n                radius=self.radius\n                ))\n\n    def _generateCopperPads(self):\n        # kicad_mod.append(c)\n        layers = ['F.Cu']\n        if self.num_paste_zones == 1:\n            if self.solder_paste_margin == 0:\n                layers.append('F.Paste')\n            else:\n                self.pads.append(\n                    RingPadPrimitive(\n                        number=\"\",\n                        at=self.at,\n                        width=self.width+2*self.solder_paste_margin,\n                        layers=['F.Paste'],\n                        radius=self.radius\n                        ))\n\n        if self.solder_mask_margin == 0:\n            # bug in kicad so any clearance other than 0 needs a workaround\n            layers.append('F.Mask')\n        else:\n            self._generateMaskPads()\n        self.pads.append(\n            RingPadPrimitive(\n                number=self.number,\n                at=self.at,\n                width=self.width,\n                layers=layers,\n                radius=self.radius\n                ))\n\n        a = 360/self.num_anchor\n        pos = Vector2D(self.radius, 0)\n        for i in range(1, self.num_anchor):\n            pos.rotate(a)\n            self.pads.append(Pad(number=self.number,\n                                 type=Pad.TYPE_SMT, shape=Pad.SHAPE_CIRCLE,\n                                 at=(self.at+pos), size=self.width-0.0001,\n                                 layers=['F.Cu'],\n                                 ))\n\n    def getVirtualChilds(self):\n        return self.pads\n"
  },
  {
    "path": "KicadModTree/nodes/specialized/Rotation.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport math\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\n\n\nclass Rotation(Node):\n    \"\"\"Apply rotation to the child tree\n\n    :param r: angle which the child should rotate\n    :type r: ``float``\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> Rotation(90)\n    \"\"\"\n\n    def __init__(self, r):\n        Node.__init__(self)\n        self.rotation = r  # in degree\n\n    def getRealPosition(self, coordinate, rotation=None):\n        if rotation is None:\n            rotation = 0\n\n        parsed_coordinate = Vector2D(coordinate)\n\n        phi = self.rotation*math.pi/180\n        rotation_coordinate = {'x': parsed_coordinate.x*math.cos(phi) + parsed_coordinate.y*math.sin(phi),\n                               'y': -parsed_coordinate.x*math.sin(phi) + parsed_coordinate.y*math.cos(phi)}\n\n        if not self._parent:\n            if rotation is None:\n                return rotation_coordinate\n            else:\n                return rotation_coordinate, rotation + self.rotation\n        else:\n            if rotation is None:\n                rotation = 0\n            return self._parent.getRealPosition(rotation_coordinate, rotation + self.rotation)\n\n    def _getRenderTreeText(self):\n        render_text = Node._getRenderTreeText(self)\n        render_text += \" [r: {r}]\".format(r=self.rotation)\n\n        return render_text\n"
  },
  {
    "path": "KicadModTree/nodes/specialized/Translation.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom KicadModTree.Vector import *\nfrom KicadModTree.nodes.Node import Node\n\n\nclass Translation(Node):\n    \"\"\"Apply translation to the child tree\n\n    :param x: change of x coordinate\n    :type x: ``float``\n    :param y: change of y coordinate\n    :type y: ``float``\n\n    :Example:\n\n    >>> from KicadModTree import *\n    >>> Translation(1, 2)\n    \"\"\"\n    def __init__(self, x, y):\n        Node.__init__(self)\n\n        # translation information\n        self.offset_x = x\n        self.offset_y = y\n\n    def getRealPosition(self, coordinate, rotation=None):\n        parsed_coordinate = Vector2D(coordinate)\n\n        # calculate translation\n        translation_coordinate = {'x': parsed_coordinate.x + self.offset_x,\n                                  'y': parsed_coordinate.y + self.offset_y}\n\n        if not self._parent:\n            if rotation is None:\n                return translation_coordinate\n            else:\n                return translation_coordinate, rotation\n        else:\n            return self._parent.getRealPosition(translation_coordinate, rotation)\n\n    def _getRenderTreeText(self):\n        render_text = Node._getRenderTreeText(self)\n        render_text += \" [x: {x}, y: {y}]\".format(x=self.offset_x,\n                                                  y=self.offset_y)\n\n        return render_text\n"
  },
  {
    "path": "KicadModTree/nodes/specialized/__init__.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom .Translation import Translation\nfrom .Rotation import Rotation\n\nfrom .PolygoneLine import PolygoneLine\nfrom .RectLine import RectLine\nfrom .RectFill import RectFill\nfrom .FilledRect import FilledRect\n\nfrom .PadArray import PadArray\nfrom .ExposedPad import ExposedPad\nfrom .ChamferedPad import ChamferedPad, CornerSelection\nfrom .ChamferedPadGrid import *\nfrom .RingPad import RingPad\n"
  },
  {
    "path": "KicadModTree/tests/__init__.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n"
  },
  {
    "path": "KicadModTree/tests/datatypes/__init__.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016-2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom .test_Vector2D import Vector2DTests\nfrom .test_Vector3D import Vector3DTests\n"
  },
  {
    "path": "KicadModTree/tests/datatypes/test_Vector2D.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport unittest\nimport math\nfrom KicadModTree.Vector import *\n\n\nclass Vector2DTests(unittest.TestCase):\n\n    def test_init(self):\n        p1 = Vector2D([1, 2])\n        self.assertEqual(p1.x, 1)\n        self.assertEqual(p1.y, 2)\n\n        p2 = Vector2D((4, 5))\n        self.assertEqual(p2.x, 4)\n        self.assertEqual(p2.y, 5)\n\n        p3 = Vector2D({'x': 7, 'y': 8})\n        self.assertEqual(p3.x, 7)\n        self.assertEqual(p3.y, 8)\n\n        p3_empty = Vector2D({})\n        self.assertEqual(p3_empty.x, 0)\n        self.assertEqual(p3_empty.y, 0)\n\n        p4 = Vector2D(p1)\n        self.assertEqual(p4.x, 1)\n        self.assertEqual(p4.y, 2)\n\n        p5 = Vector2D(1, 2)\n        self.assertEqual(p5.x, 1)\n        self.assertEqual(p5.y, 2)\n\n        # TODO: test float datatype\n        # TODO: invalid type tests\n        # TODO: tests if int is always converted to float\n\n    def test_round_to(self):\n        p1 = Vector2D([1.234, 5.678]).round_to(0)\n        self.assertAlmostEqual(p1.x, 1.234)\n        self.assertAlmostEqual(p1.y, 5.678)\n\n        p2 = Vector2D([1.234, 5.678]).round_to(0.1)\n        self.assertAlmostEqual(p2.x, 1.2)\n        self.assertAlmostEqual(p2.y, 5.7)\n\n        p3 = Vector2D([1.234, 5.678]).round_to(0.01)\n        self.assertAlmostEqual(p3.x, 1.23)\n        self.assertAlmostEqual(p3.y, 5.68)\n\n        p4 = Vector2D([1.234, 5.678]).round_to(0.001)\n        self.assertAlmostEqual(p4.x, 1.234)\n        self.assertAlmostEqual(p4.y, 5.678)\n\n        p5 = Vector2D([1.234, 5.678]).round_to(0.0001)\n        self.assertAlmostEqual(p5.x, 1.234)\n        self.assertAlmostEqual(p5.y, 5.678)\n\n    def test_add(self):\n        p1 = Vector2D([1, 2])\n        self.assertEqual(p1.x, 1)\n        self.assertEqual(p1.y, 2)\n\n        p2 = p1 + 5\n        self.assertEqual(p2.x, 6)\n        self.assertEqual(p2.y, 7)\n\n        p3 = p1 + (-5)\n        self.assertEqual(p3.x, -4)\n        self.assertEqual(p3.y, -3)\n\n        p4 = p1 + [4, 2]\n        self.assertEqual(p4.x, 5)\n        self.assertEqual(p4.y, 4)\n\n        p5 = p1 + [-5, -3]\n        self.assertEqual(p5.x, -4)\n        self.assertEqual(p5.y, -1)\n\n        # TODO: invalid type tests\n\n    def test_sub(self):\n        p1 = Vector2D([1, 2])\n        self.assertEqual(p1.x, 1)\n        self.assertEqual(p1.y, 2)\n\n        p2 = p1 - 5\n        self.assertEqual(p2.x, -4)\n        self.assertEqual(p2.y, -3)\n\n        p3 = p1 - (-5)\n        self.assertEqual(p3.x, 6)\n        self.assertEqual(p3.y, 7)\n\n        p4 = p1 - [4, 2]\n        self.assertEqual(p4.x, -3)\n        self.assertEqual(p4.y, 0)\n\n        p5 = p1 - [-5, -3]\n        self.assertEqual(p5.x, 6)\n        self.assertEqual(p5.y, 5)\n\n        # TODO: invalid type tests\n\n    def test_mul(self):\n        p1 = Vector2D([1, 2])\n        self.assertEqual(p1.x, 1)\n        self.assertEqual(p1.y, 2)\n\n        p2 = p1 * 5\n        self.assertEqual(p2.x, 5)\n        self.assertEqual(p2.y, 10)\n\n        p3 = p1 * (-5)\n        self.assertEqual(p3.x, -5)\n        self.assertEqual(p3.y, -10)\n\n        p4 = p1 * [4, 5]\n        self.assertEqual(p4.x, 4)\n        self.assertEqual(p4.y, 10)\n\n        p5 = p1 * [-5, -3]\n        self.assertEqual(p5.x, -5)\n        self.assertEqual(p5.y, -6)\n\n        # TODO: invalid type tests\n\n    def test_div(self):\n        p1 = Vector2D([1, 2])\n        self.assertEqual(p1.x, 1)\n        self.assertEqual(p1.y, 2)\n\n        p2 = p1 / 5\n        self.assertEqual(p2.x, 0.2)\n        self.assertEqual(p2.y, 0.4)\n\n        p3 = p1 / (-5)\n        self.assertEqual(p3.x, -0.2)\n        self.assertEqual(p3.y, -0.4)\n\n        p4 = p1 / [4, 5]\n        self.assertEqual(p4.x, 0.25)\n        self.assertEqual(p4.y, 0.4)\n\n        p5 = p1 / [-5, -2]\n        self.assertEqual(p5.x, -0.2)\n        self.assertEqual(p5.y, -1)\n\n        # TODO: division by zero tests\n        # TODO: invalid type tests\n\n    def test_polar(self):\n        p1 = Vector2D.from_polar(math.sqrt(2), 45, use_degrees=True)\n        self.assertAlmostEqual(p1.x, 1)\n        self.assertAlmostEqual(p1.y, 1)\n\n        p1 = Vector2D.from_polar(2, -90, use_degrees=True, origin=(6, 1))\n        self.assertAlmostEqual(p1.x, 6)\n        self.assertAlmostEqual(p1.y, -1)\n\n        r, a = p1.to_polar(use_degrees=True, origin=(6, 1))\n        self.assertAlmostEqual(r, 2)\n        self.assertAlmostEqual(a, -90)\n\n        p1.rotate(90, use_degrees=True, origin=(6, 1))\n        self.assertAlmostEqual(p1.x, 8)\n        self.assertAlmostEqual(p1.y, 1)\n\n        p1 = Vector2D.from_polar(math.sqrt(2), 135, use_degrees=True)\n        self.assertAlmostEqual(p1.x, -1)\n        self.assertAlmostEqual(p1.y, 1)\n\n        p1.rotate(90, use_degrees=True)\n        self.assertAlmostEqual(p1.x, -1)\n        self.assertAlmostEqual(p1.y, -1)\n\n        r, a = p1.to_polar(use_degrees=True)\n        self.assertAlmostEqual(r, math.sqrt(2))\n        self.assertAlmostEqual(a, -135)\n"
  },
  {
    "path": "KicadModTree/tests/datatypes/test_Vector3D.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016-2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport unittest\n\nfrom KicadModTree.Vector import *\n\n\nclass Vector3DTests(unittest.TestCase):\n\n    def test_init(self):\n        p1 = Vector3D([1, 2, 3])\n        self.assertEqual(p1.x, 1)\n        self.assertEqual(p1.y, 2)\n        self.assertEqual(p1.z, 3)\n\n        p1_xy = Vector3D([1, 2])\n        self.assertEqual(p1_xy.x, 1)\n        self.assertEqual(p1_xy.y, 2)\n        self.assertEqual(p1_xy.z, 0)\n\n        p2 = Vector3D((4, 5, 6))\n        self.assertEqual(p2.x, 4)\n        self.assertEqual(p2.y, 5)\n        self.assertEqual(p2.z, 6)\n\n        p2_xy = Vector3D((4, 5))\n        self.assertEqual(p2_xy.x, 4)\n        self.assertEqual(p2_xy.y, 5)\n        self.assertEqual(p2_xy.z, 0)\n\n        p3 = Vector3D({'x': 7, 'y': 8, 'z': 9})\n        self.assertEqual(p3.x, 7)\n        self.assertEqual(p3.y, 8)\n        self.assertEqual(p3.z, 9)\n\n        p3_xy = Vector3D({'x': 7, 'y': 8})\n        self.assertEqual(p3_xy.x, 7)\n        self.assertEqual(p3_xy.y, 8)\n        self.assertEqual(p3_xy.z, 0)\n\n        p3_empty = Vector3D({})\n        self.assertEqual(p3_empty.x, 0)\n        self.assertEqual(p3_empty.y, 0)\n        self.assertEqual(p3_empty.z, 0)\n\n        p4 = Vector3D(p1)\n        self.assertEqual(p4.x, 1)\n        self.assertEqual(p4.y, 2)\n        self.assertEqual(p4.z, 3)\n\n        p5 = Vector3D(1, 2, 3)\n        self.assertEqual(p5.x, 1)\n        self.assertEqual(p5.y, 2)\n        self.assertEqual(p5.z, 3)\n\n        p5_xy = Vector3D(1, 2)\n        self.assertEqual(p5_xy.x, 1)\n        self.assertEqual(p5_xy.y, 2)\n        self.assertEqual(p5_xy.z, 0)\n\n        # TODO: test float datatype\n        # TODO: invalid type tests\n        # TODO: tests if int is always converted to float\n\n    def test_round_to(self):\n        p1 = Vector3D([1.234, 5.678, 9.012]).round_to(0)\n        self.assertAlmostEqual(p1.x, 1.234)\n        self.assertAlmostEqual(p1.y, 5.678)\n        self.assertAlmostEqual(p1.z, 9.012)\n\n        p2 = Vector3D([1.234, 5.678, 9.012]).round_to(0.1)\n        self.assertAlmostEqual(p2.x, 1.2)\n        self.assertAlmostEqual(p2.y, 5.7)\n        self.assertAlmostEqual(p2.z, 9)\n\n        p3 = Vector3D([1.234, 5.678, 9.012]).round_to(0.01)\n        self.assertAlmostEqual(p3.x, 1.23)\n        self.assertAlmostEqual(p3.y, 5.68)\n        self.assertAlmostEqual(p3.z, 9.01)\n\n        p4 = Vector3D([1.234, 5.678, 9.012]).round_to(0.001)\n        self.assertAlmostEqual(p4.x, 1.234)\n        self.assertAlmostEqual(p4.y, 5.678)\n        self.assertAlmostEqual(p4.z, 9.012)\n\n        p5 = Vector3D([1.234, 5.678, 9.012]).round_to(0.0001)\n        self.assertAlmostEqual(p5.x, 1.234)\n        self.assertAlmostEqual(p5.y, 5.678)\n        self.assertAlmostEqual(p5.z, 9.012)\n\n    def test_add(self):\n        p1 = Vector3D([1, 2, 3])\n        self.assertEqual(p1.x, 1)\n        self.assertEqual(p1.y, 2)\n        self.assertEqual(p1.z, 3)\n\n        p2 = p1 + 5\n        self.assertEqual(p2.x, 6)\n        self.assertEqual(p2.y, 7)\n        self.assertEqual(p2.z, 8)\n\n        p3 = p1 + (-5)\n        self.assertEqual(p3.x, -4)\n        self.assertEqual(p3.y, -3)\n        self.assertEqual(p3.z, -2)\n\n        p4 = p1 + [4, 2, -2]\n        self.assertEqual(p4.x, 5)\n        self.assertEqual(p4.y, 4)\n        self.assertEqual(p4.z, 1)\n\n        p5 = p1 + [-5, -3]\n        self.assertEqual(p5.x, -4)\n        self.assertEqual(p5.y, -1)\n        self.assertEqual(p5.z, 3)\n\n        # TODO: invalid type tests\n\n    def test_sub(self):\n        p1 = Vector3D([1, 2, 3])\n        self.assertEqual(p1.x, 1)\n        self.assertEqual(p1.y, 2)\n        self.assertEqual(p1.z, 3)\n\n        p2 = p1 - 5\n        self.assertEqual(p2.x, -4)\n        self.assertEqual(p2.y, -3)\n        self.assertEqual(p2.z, -2)\n\n        p3 = p1 - (-5)\n        self.assertEqual(p3.x, 6)\n        self.assertEqual(p3.y, 7)\n        self.assertEqual(p3.z, 8)\n\n        p4 = p1 - [4, 2, -2]\n        self.assertEqual(p4.x, -3)\n        self.assertEqual(p4.y, 0)\n        self.assertEqual(p4.z, 5)\n\n        p5 = p1 - [-5, -3]\n        self.assertEqual(p5.x, 6)\n        self.assertEqual(p5.y, 5)\n        self.assertEqual(p5.z, 3)\n\n        # TODO: invalid type tests\n\n    def test_mul(self):\n        p1 = Vector3D([1, 2, 3])\n        self.assertEqual(p1.x, 1)\n        self.assertEqual(p1.y, 2)\n        self.assertEqual(p1.z, 3)\n\n        p2 = p1 * 5\n        self.assertEqual(p2.x, 5)\n        self.assertEqual(p2.y, 10)\n        self.assertEqual(p2.z, 15)\n\n        p3 = p1 * (-5)\n        self.assertEqual(p3.x, -5)\n        self.assertEqual(p3.y, -10)\n        self.assertEqual(p3.z, -15)\n\n        p4 = p1 * [4, 5, -2]\n        self.assertEqual(p4.x, 4)\n        self.assertEqual(p4.y, 10)\n        self.assertEqual(p4.z, -6)\n\n        p5 = p1 * [-5, -3]\n        self.assertEqual(p5.x, -5)\n        self.assertEqual(p5.y, -6)\n        self.assertEqual(p5.z, 0)\n\n        # TODO: invalid type tests\n\n    def test_div(self):\n        p1 = Vector3D([1, 2, 3])\n        self.assertEqual(p1.x, 1)\n        self.assertEqual(p1.y, 2)\n        self.assertEqual(p1.z, 3)\n\n        p2 = p1 / 5\n        self.assertEqual(p2.x, 0.2)\n        self.assertEqual(p2.y, 0.4)\n        self.assertEqual(p2.z, 0.6)\n\n        p3 = p1 / (-5)\n        self.assertEqual(p3.x, -0.2)\n        self.assertEqual(p3.y, -0.4)\n        self.assertEqual(p3.z, -0.6)\n\n        p4 = p1 / [4, 5, -2]\n        self.assertEqual(p4.x, 0.25)\n        self.assertEqual(p4.y, 0.4)\n        self.assertEqual(p4.z, -1.5)\n\n        # TODO: division by zero tests\n        # TODO: invalid type tests\n"
  },
  {
    "path": "KicadModTree/tests/moduletests/__init__.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom .test_simple_footprints import SimpleFootprintTests\nfrom .test_kicad5_padshapes import Kicad5PadsTests\nfrom .test_exposed_pad import ExposedPadTests\nfrom .test_arc import ArcTests\nfrom .test_rotation import RotationTests\n"
  },
  {
    "path": "KicadModTree/tests/moduletests/test_arc.py",
    "content": "import unittest\nimport math\nfrom KicadModTree import *\n\nRESULT_kx90DEG = \"\"\"(module test (layer F.Cu) (tedit 0)\n  (fp_arc (start 0 0) (end 1 0) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 0 -1.2) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end -1.4 0) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 0 1.6) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 2 0) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 0 2.2) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end -2.4 0) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 0 -2.6) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 3 0) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 0 -3.2) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end -3.4 0) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 0 3.6) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 4 0) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 0 4.2) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end -4.4 0) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 0 -4.6) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 5 0) (angle 270) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 0 -5.2) (angle 270) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end -5.4 0) (angle 270) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 0 5.6) (angle 270) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 6 0) (angle -180) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end -6.2 0) (angle -180) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 6.6 0) (angle 180) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end -6.8 0) (angle 180) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 4.949747 -4.949747) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end -5.091169 -5.091169) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end -5.23259 5.23259) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 5.374012 5.374012) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 5.656854 5.656854) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end 5.798276 -5.798276) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end -5.939697 -5.939697) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 0 0) (end -6.081118 6.081118) (angle -90) (layer F.SilkS) (width 0.12))\n)\"\"\"\n\nRESULT_kx90DEG_45deg = \"\"\"(module test (layer F.Cu) (tedit 0)\n  (fp_arc (start -5 5) (end -4.292893 5.707107) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -4.151472 4.151472) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -5.989949 4.010051) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -6.131371 6.131371) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -3.585786 6.414214) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -6.555635 6.555635) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -6.697056 3.302944) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -3.161522 3.161522) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -2.87868 7.12132) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -2.737258 2.737258) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -7.404163 2.595837) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -7.545584 7.545584) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -2.171573 7.828427) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -7.969848 7.969848) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -8.11127 1.88873) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -1.747309 1.747309) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -1.464466 8.535534) (angle 270) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -1.323045 1.323045) (angle 270) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -8.818377 1.181623) (angle 270) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -8.959798 8.959798) (angle 270) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -0.757359 9.242641) (angle -180) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -9.384062 0.615938) (angle -180) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -0.333095 9.666905) (angle 180) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -9.808326 0.191674) (angle 180) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end 2 5) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -5 -2.2) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -12.4 5) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -5 12.6) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -5 13) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end 3.2 5) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -5 -3.4) (angle -90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start -5 5) (end -13.6 5) (angle -90) (layer F.SilkS) (width 0.12))\n)\"\"\"\n\n\nclass ArcTests(unittest.TestCase):\n\n    def testArcsKx90deg(self):\n        kicad_mod = Footprint(\"test\")\n\n        center = Vector2D(0, 0)\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(1, 0), angle=-90))\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(0, -1.2), angle=-90))\n\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(-1.4, 0), angle=-90))\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(0, 1.6), angle=-90))\n\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(2, 0), angle=90))\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(0, 2.2), angle=90))\n\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(-2.4, 0), angle=90))\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(0, -2.6), angle=90))\n\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(3, 0), end=Vector2D(0, -3)))\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(0, -3.2), end=Vector2D(-3.2, 0)))\n\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(-3.4, 0), end=Vector2D(0, 3.4)))\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(0, 3.6), end=Vector2D(3.6, 0)))\n\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(4, 0), end=Vector2D(0, 4)))\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(0, 4.2), end=Vector2D(-4.2, 0)))\n\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(-4.4, 0), end=Vector2D(0, -4.4)))\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(0, -4.6), end=Vector2D(4.6, 0)))\n\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(5, 0), end=Vector2D(0, -5),\n                long_way=True))\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(0, -5.2), end=Vector2D(-5.2, 0),\n                long_way=True))\n\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(-5.4, 0), end=Vector2D(0, 5.4),\n                long_way=True))\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(0, 5.6), end=Vector2D(5.6, 0),\n                long_way=True))\n\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(6, 0), end=Vector2D(-6, 0)))\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(-6.2, 0), end=Vector2D(6.2, 0)))\n\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(6.6, 0), end=Vector2D(-6.6, 0),\n                long_way=True))\n        kicad_mod.append(\n            Arc(center=center, start=Vector2D(-6.8, 0), end=Vector2D(6.8, 0),\n                long_way=True))\n\n        kicad_mod.append(\n            Arc(center=center, midpoint=Vector2D(7, 0), angle=90))\n        kicad_mod.append(\n            Arc(center=center, midpoint=Vector2D(0, -7.2), angle=90))\n        kicad_mod.append(\n            Arc(center=center, midpoint=Vector2D(-7.4, 0), angle=90))\n        kicad_mod.append(\n            Arc(center=center, midpoint=Vector2D(0, 7.6), angle=90))\n\n        kicad_mod.append(\n            Arc(center=center, midpoint=Vector2D(8, 0), angle=-90))\n        kicad_mod.append(\n            Arc(center=center, midpoint=Vector2D(0, -8.2), angle=-90))\n        kicad_mod.append(\n            Arc(center=center, midpoint=Vector2D(-8.4, 0), angle=-90))\n        kicad_mod.append(\n            Arc(center=center, midpoint=Vector2D(0, 8.6), angle=-90))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        self.assertEqual(file_handler.serialize(timestamp=0), RESULT_kx90DEG)\n        # file_handler.writeFile('test_arc4.kicad_mod')\n\n    def testArcsKx90degOffsetRotated(self):\n        kicad_mod = Footprint(\"test\")\n\n        center = Vector2D(-5, 5)\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(1, 0)+center).rotate(45, origin=center),\n              angle=-90\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(0, -1.2)+center).rotate(45, origin=center),\n              angle=-90\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(-1.4, 0)+center).rotate(45, origin=center),\n              angle=-90\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(0, 1.6)+center).rotate(45, origin=center),\n              angle=-90\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(2, 0)+center).rotate(45, origin=center),\n              angle=90\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(0, 2.2)+center).rotate(45, origin=center),\n              angle=90\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(-2.4, 0)+center).rotate(45, origin=center),\n              angle=90\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(0, -2.6)+center).rotate(45, origin=center),\n              angle=90\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(3, 0)+center).rotate(45, origin=center),\n              end=(Vector2D(0, -3)+center).rotate(45, origin=center)\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(0, -3.2)+center).rotate(45, origin=center),\n              end=(Vector2D(-3.2, 0)+center).rotate(45, origin=center)\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(-3.4, 0)+center).rotate(45, origin=center),\n              end=(Vector2D(0, 3.4)+center).rotate(45, origin=center)\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(0, 3.6)+center).rotate(45, origin=center),\n              end=(Vector2D(3.6, 0)+center).rotate(45, origin=center)\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(4, 0)+center).rotate(45, origin=center),\n              end=(Vector2D(0, 4)+center).rotate(45, origin=center)\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(0, 4.2)+center).rotate(45, origin=center),\n              end=(Vector2D(-4.2, 0)+center).rotate(45, origin=center)\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(-4.4, 0)+center).rotate(45, origin=center),\n              end=(Vector2D(0, -4.4)+center).rotate(45, origin=center)\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(0, -4.6)+center).rotate(45, origin=center),\n              end=(Vector2D(4.6, 0)+center).rotate(45, origin=center)\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(5, 0)+center).rotate(45, origin=center),\n              end=(Vector2D(0, -5)+center).rotate(45, origin=center),\n              long_way=True\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(0, -5.2)+center).rotate(45, origin=center),\n              end=(Vector2D(-5.2, 0)+center).rotate(45, origin=center),\n              long_way=True\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(-5.4, 0)+center).rotate(45, origin=center),\n              end=(Vector2D(0, 5.4)+center).rotate(45, origin=center),\n              long_way=True\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(0, 5.6)+center).rotate(45, origin=center),\n              end=(Vector2D(5.6, 0)+center).rotate(45, origin=center),\n              long_way=True\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(6, 0)+center).rotate(45, origin=center),\n              end=(Vector2D(-6, 0)+center).rotate(45, origin=center)\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(-6.2, 0)+center).rotate(45, origin=center),\n              end=(Vector2D(6.2, 0)+center).rotate(45, origin=center)\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(6.6, 0)+center).rotate(45, origin=center),\n              end=(Vector2D(-6.6, 0)+center).rotate(45, origin=center),\n              long_way=True\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              start=(Vector2D(-6.8, 0)+center).rotate(45, origin=center),\n              end=(Vector2D(6.8, 0)+center).rotate(45, origin=center),\n              long_way=True\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              midpoint=(Vector2D(7, 0)+center).rotate(45, origin=center),\n              angle=90\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              midpoint=(Vector2D(0, -7.2)+center).rotate(45, origin=center),\n              angle=90\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              midpoint=(Vector2D(-7.4, 0)+center).rotate(45, origin=center),\n              angle=90\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              midpoint=(Vector2D(0, 7.6)+center).rotate(45, origin=center),\n              angle=90\n              ))\n\n        kicad_mod.append(\n          Arc(\n              center=center,\n              midpoint=(Vector2D(8, 0)+center).rotate(45, origin=center),\n              angle=-90\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              midpoint=(Vector2D(0, -8.2)+center).rotate(45, origin=center),\n              angle=-90\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              midpoint=(Vector2D(-8.4, 0)+center).rotate(45, origin=center),\n              angle=-90\n              ))\n        kicad_mod.append(\n          Arc(\n              center=center,\n              midpoint=(Vector2D(0, 8.6)+center).rotate(45, origin=center),\n              angle=-90\n              ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        self.assertEqual(file_handler.serialize(timestamp=0), RESULT_kx90DEG_45deg)\n        # file_handler.writeFile('test_arc5.kicad_mod')\n"
  },
  {
    "path": "KicadModTree/tests/moduletests/test_exposed_pad.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n# (C) 2018 by Rene Poeschl, github @poeschlr\n\nimport unittest\n\nfrom KicadModTree import *\n\nRESULT_SIMPLE_EP_FP = \"\"\"(module simple_exposed (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value simple_exposed (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad \"\" smd rect (at 0 1) (size 2.1 2.1) (layers F.Mask))\n  (pad 3 smd rect (at 0 1) (size 2.1 3) (layers F.Cu))\n  (pad 3 thru_hole circle (at -0.75 -0.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0 -0.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0.75 -0.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -0.75 2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0 2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0.75 2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 0 1) (size 2.1 3) (layers B.Cu))\n  (pad \"\" smd rect (at -0.525 0.3) (size 0.85 0.56) (layers F.Paste))\n  (pad \"\" smd rect (at -0.525 1) (size 0.85 0.56) (layers F.Paste))\n  (pad \"\" smd rect (at -0.525 1.7) (size 0.85 0.56) (layers F.Paste))\n  (pad \"\" smd rect (at 0.525 0.3) (size 0.85 0.56) (layers F.Paste))\n  (pad \"\" smd rect (at 0.525 1) (size 0.85 0.56) (layers F.Paste))\n  (pad \"\" smd rect (at 0.525 1.7) (size 0.85 0.56) (layers F.Paste))\n)\"\"\"\n\nRESULT_SIMPLE_EP_NO_ROUNDING_FP = \"\"\"(module simple_exposed (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value simple_exposed (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad \"\" smd rect (at 0 1) (size 2.1 2.1) (layers F.Mask))\n  (pad 3 smd rect (at 0 1) (size 2.1 3) (layers F.Cu))\n  (pad 3 thru_hole circle (at -0.75 -0.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0 -0.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0.75 -0.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -0.75 2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0 2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0.75 2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 0 1) (size 2.1 3) (layers B.Cu))\n  (pad \"\" smd rect (at -0.525 0.3) (size 0.846537 0.564358) (layers F.Paste))\n  (pad \"\" smd rect (at -0.525 1) (size 0.846537 0.564358) (layers F.Paste))\n  (pad \"\" smd rect (at -0.525 1.7) (size 0.846537 0.564358) (layers F.Paste))\n  (pad \"\" smd rect (at 0.525 0.3) (size 0.846537 0.564358) (layers F.Paste))\n  (pad \"\" smd rect (at 0.525 1) (size 0.846537 0.564358) (layers F.Paste))\n  (pad \"\" smd rect (at 0.525 1.7) (size 0.846537 0.564358) (layers F.Paste))\n)\"\"\"\n\nRESULT_MINIMAL_EP_SPECIFICATION = \"\"\"(module simple_exposed (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value simple_exposed (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 3 smd rect (at 0 0) (size 2.1 3) (layers F.Cu F.Mask))\n  (pad 3 thru_hole circle (at -0.75 -1.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0 -1.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0.75 -1.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -0.75 0) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0 0) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0.75 0) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -0.75 1.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0 1.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0.75 1.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 0 0) (size 2.1 3) (layers B.Cu))\n  (pad \"\" smd rect (at -0.525 -0.75) (size 0.85 1.21) (layers F.Paste))\n  (pad \"\" smd rect (at -0.525 0.75) (size 0.85 1.21) (layers F.Paste))\n  (pad \"\" smd rect (at 0.525 -0.75) (size 0.85 1.21) (layers F.Paste))\n  (pad \"\" smd rect (at 0.525 0.75) (size 0.85 1.21) (layers F.Paste))\n)\"\"\"\n\nRESULT_EP_PASTE_GEN_INNER = \"\"\"(module exposed_paste_autogen (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value exposed_paste_autogen (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 3 smd rect (at 0 0) (size 5 5) (layers F.Cu F.Mask))\n  (pad 3 thru_hole circle (at -2.2 -2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 2.2 -2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -2.2 2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 2.2 2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 0 0) (size 5 5) (layers B.Cu))\n  (pad \"\" smd custom (at -1.466667 -1.466667) (size 1.230653 1.230653) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.671855 -0.511969) (xy -0.511969 -0.671855) (xy 0.671855 -0.671855) (xy 0.671855 0.671855)\n         (xy -0.671855 0.671855)) (width 0))\n    ))\n  (pad \"\" smd rect (at -1.466667 0) (size 1.34371 1.34371) (layers F.Paste))\n  (pad \"\" smd custom (at -1.466667 1.466667) (size 1.230653 1.230653) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.671855 -0.671855) (xy 0.671855 -0.671855) (xy 0.671855 0.671855) (xy -0.511969 0.671855)\n         (xy -0.671855 0.511969)) (width 0))\n    ))\n  (pad \"\" smd rect (at 0 -1.466667) (size 1.34371 1.34371) (layers F.Paste))\n  (pad \"\" smd rect (at 0 0) (size 1.34371 1.34371) (layers F.Paste))\n  (pad \"\" smd rect (at 0 1.466667) (size 1.34371 1.34371) (layers F.Paste))\n  (pad \"\" smd custom (at 1.466667 -1.466667) (size 1.230653 1.230653) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.671855 -0.671855) (xy 0.511969 -0.671855) (xy 0.671855 -0.511969) (xy 0.671855 0.671855)\n         (xy -0.671855 0.671855)) (width 0))\n    ))\n  (pad \"\" smd rect (at 1.466667 0) (size 1.34371 1.34371) (layers F.Paste))\n  (pad \"\" smd custom (at 1.466667 1.466667) (size 1.230653 1.230653) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.671855 -0.671855) (xy 0.671855 -0.671855) (xy 0.671855 0.511969) (xy 0.511969 0.671855)\n         (xy -0.671855 0.671855)) (width 0))\n    ))\n)\"\"\"\n\nRESULT_EP_PASTE_GEN_INNER2 = \"\"\"(module exposed_paste_autogen (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value exposed_paste_autogen (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 3 smd rect (at 0 0) (size 5 5) (layers F.Cu F.Mask))\n  (pad 3 thru_hole circle (at -2.2 -2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -0.733333 -2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0.733333 -2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 2.2 -2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -2.2 -0.733333) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -0.733333 -0.733333) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0.733333 -0.733333) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 2.2 -0.733333) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -2.2 0.733333) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -0.733333 0.733333) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0.733333 0.733333) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 2.2 0.733333) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -2.2 2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -0.733333 2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0.733333 2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 2.2 2.2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 0 0) (size 5 5) (layers B.Cu))\n  (pad \"\" smd custom (at -1.833333 -1.833333) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.155863) (xy -0.155863 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.833333 -1.1) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628) (xy -0.155863 0.294628)\n         (xy -0.294628 0.155863)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.1 -1.833333) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.155863 -0.294628) (xy 0.294628 -0.155863) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.1 -1.1) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.155863) (xy 0.155863 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.833333 -0.366667) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.155863) (xy -0.155863 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.833333 0.366667) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628) (xy -0.155863 0.294628)\n         (xy -0.294628 0.155863)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.1 -0.366667) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.155863 -0.294628) (xy 0.294628 -0.155863) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.1 0.366667) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.155863) (xy 0.155863 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.833333 1.1) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.155863) (xy -0.155863 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.833333 1.833333) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628) (xy -0.155863 0.294628)\n         (xy -0.294628 0.155863)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.1 1.1) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.155863 -0.294628) (xy 0.294628 -0.155863) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.1 1.833333) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.155863) (xy 0.155863 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.366667 -1.833333) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.155863) (xy -0.155863 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.366667 -1.1) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628) (xy -0.155863 0.294628)\n         (xy -0.294628 0.155863)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.366667 -1.833333) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.155863 -0.294628) (xy 0.294628 -0.155863) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.366667 -1.1) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.155863) (xy 0.155863 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.366667 -0.366667) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.155863) (xy -0.155863 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.366667 0.366667) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628) (xy -0.155863 0.294628)\n         (xy -0.294628 0.155863)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.366667 -0.366667) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.155863 -0.294628) (xy 0.294628 -0.155863) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.366667 0.366667) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.155863) (xy 0.155863 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.366667 1.1) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.155863) (xy -0.155863 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.366667 1.833333) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628) (xy -0.155863 0.294628)\n         (xy -0.294628 0.155863)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.366667 1.1) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.155863 -0.294628) (xy 0.294628 -0.155863) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.366667 1.833333) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.155863) (xy 0.155863 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.1 -1.833333) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.155863) (xy -0.155863 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.1 -1.1) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628) (xy -0.155863 0.294628)\n         (xy -0.294628 0.155863)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.833333 -1.833333) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.155863 -0.294628) (xy 0.294628 -0.155863) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.833333 -1.1) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.155863) (xy 0.155863 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.1 -0.366667) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.155863) (xy -0.155863 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.1 0.366667) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628) (xy -0.155863 0.294628)\n         (xy -0.294628 0.155863)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.833333 -0.366667) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.155863 -0.294628) (xy 0.294628 -0.155863) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.833333 0.366667) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.155863) (xy 0.155863 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.1 1.1) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.155863) (xy -0.155863 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.1 1.833333) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.294628) (xy -0.155863 0.294628)\n         (xy -0.294628 0.155863)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.833333 1.1) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.155863 -0.294628) (xy 0.294628 -0.155863) (xy 0.294628 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.833333 1.833333) (size 0.491134 0.491134) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.294628 -0.294628) (xy 0.294628 -0.294628) (xy 0.294628 0.155863) (xy 0.155863 0.294628)\n         (xy -0.294628 0.294628)) (width 0))\n    ))\n)\"\"\"\n\nRESULT_EP_PASTE_GEN_INNER_AND_OUTHER = \"\"\"(module exposed_paste_autogen (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value exposed_paste_autogen (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 3 smd rect (at 7 5) (size 12 8) (layers F.Cu F.Mask))\n  (pad 3 thru_hole circle (at 4 3) (size 0.8 0.8) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 7 3) (size 0.8 0.8) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 10 3) (size 0.8 0.8) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 4 5) (size 0.8 0.8) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 7 5) (size 0.8 0.8) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 10 5) (size 0.8 0.8) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 4 7) (size 0.8 0.8) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 7 7) (size 0.8 0.8) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 10 7) (size 0.8 0.8) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 7 5) (size 6.8 4.8) (layers B.Cu))\n  (pad \"\" smd custom (at 4.75 3.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.05682) (xy -0.265985 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 4.75 4.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833) (xy -0.265985 0.41833)\n         (xy -0.627495 0.05682)) (width 0))\n    ))\n  (pad \"\" smd custom (at 6.25 3.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.265985 -0.41833) (xy 0.627495 -0.05682) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 6.25 4.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.05682) (xy 0.265985 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 4.75 5.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.05682) (xy -0.265985 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 4.75 6.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833) (xy -0.265985 0.41833)\n         (xy -0.627495 0.05682)) (width 0))\n    ))\n  (pad \"\" smd custom (at 6.25 5.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.265985 -0.41833) (xy 0.627495 -0.05682) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 6.25 6.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.05682) (xy 0.265985 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 7.75 3.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.05682) (xy -0.265985 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 7.75 4.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833) (xy -0.265985 0.41833)\n         (xy -0.627495 0.05682)) (width 0))\n    ))\n  (pad \"\" smd custom (at 9.25 3.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.265985 -0.41833) (xy 0.627495 -0.05682) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 9.25 4.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.05682) (xy 0.265985 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 7.75 5.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.05682) (xy -0.265985 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 7.75 6.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833) (xy -0.265985 0.41833)\n         (xy -0.627495 0.05682)) (width 0))\n    ))\n  (pad \"\" smd custom (at 9.25 5.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.265985 -0.41833) (xy 0.627495 -0.05682) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 9.25 6.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.05682) (xy 0.265985 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd rect (at 1.75 3.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 1.75 4.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 3.25 3.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.265985 -0.41833) (xy 0.627495 -0.05682) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 3.25 4.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.05682) (xy 0.265985 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd rect (at 1.75 5.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 1.75 6.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 3.25 5.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.265985 -0.41833) (xy 0.627495 -0.05682) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 3.25 6.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.05682) (xy 0.265985 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 10.75 3.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.05682) (xy -0.265985 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 10.75 4.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833) (xy -0.265985 0.41833)\n         (xy -0.627495 0.05682)) (width 0))\n    ))\n  (pad \"\" smd rect (at 12.25 3.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 12.25 4.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 10.75 5.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.05682) (xy -0.265985 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 10.75 6.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833) (xy -0.265985 0.41833)\n         (xy -0.627495 0.05682)) (width 0))\n    ))\n  (pad \"\" smd rect (at 12.25 5.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 12.25 6.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 4.75 1.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 4.75 2.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833) (xy -0.265985 0.41833)\n         (xy -0.627495 0.05682)) (width 0))\n    ))\n  (pad \"\" smd rect (at 6.25 1.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 6.25 2.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.05682) (xy 0.265985 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd rect (at 7.75 1.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 7.75 2.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833) (xy -0.265985 0.41833)\n         (xy -0.627495 0.05682)) (width 0))\n    ))\n  (pad \"\" smd rect (at 9.25 1.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 9.25 2.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.05682) (xy 0.265985 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd custom (at 4.75 7.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.05682) (xy -0.265985 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd rect (at 4.75 8.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 6.25 7.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.265985 -0.41833) (xy 0.627495 -0.05682) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd rect (at 6.25 8.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 7.75 7.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.05682) (xy -0.265985 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd rect (at 7.75 8.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 9.25 7.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.265985 -0.41833) (xy 0.627495 -0.05682) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd rect (at 9.25 8.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 1.75 1.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 1.75 2.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 3.25 1.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 3.25 2.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.05682) (xy 0.265985 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd rect (at 1.75 7.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 1.75 8.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 3.25 7.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.265985 -0.41833) (xy 0.627495 -0.05682) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd rect (at 3.25 8.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 10.75 1.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 10.75 2.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833) (xy -0.265985 0.41833)\n         (xy -0.627495 0.05682)) (width 0))\n    ))\n  (pad \"\" smd rect (at 12.25 1.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 12.25 2.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd custom (at 10.75 7.5) (size 0.581034 0.581034) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.627495 -0.05682) (xy -0.265985 -0.41833) (xy 0.627495 -0.41833) (xy 0.627495 0.41833)\n         (xy -0.627495 0.41833)) (width 0))\n    ))\n  (pad \"\" smd rect (at 10.75 8.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 12.25 7.5) (size 1.25499 0.83666) (layers F.Paste))\n  (pad \"\" smd rect (at 12.25 8.5) (size 1.25499 0.83666) (layers F.Paste))\n)\"\"\"\n\nRESULT_EP_PASTE_GEN_INNER_ONLY_Y_AND_OUTHER = \"\"\"(module exposed_paste_autogen (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value exposed_paste_autogen (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 3 smd rect (at 0 0) (size 3 5) (layers F.Cu F.Mask))\n  (pad 3 thru_hole circle (at 0 -2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0 0) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0 2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 0 0) (size 0.6 4.6) (layers B.Cu))\n  (pad \"\" smd rect (at -1.125 -1.5) (size 0.604669 0.806226) (layers F.Paste))\n  (pad \"\" smd rect (at -1.125 -0.5) (size 0.604669 0.806226) (layers F.Paste))\n  (pad \"\" smd custom (at -0.375 -1.5) (size 0.424561 0.424561) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.302335 -0.403113) (xy 0.047623 -0.403113) (xy 0.302335 -0.148401) (xy 0.302335 0.403113)\n         (xy -0.302335 0.403113)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.375 -0.5) (size 0.424561 0.424561) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.302335 -0.403113) (xy 0.302335 -0.403113) (xy 0.302335 0.148401) (xy 0.047623 0.403113)\n         (xy -0.302335 0.403113)) (width 0))\n    ))\n  (pad \"\" smd rect (at -1.125 0.5) (size 0.604669 0.806226) (layers F.Paste))\n  (pad \"\" smd rect (at -1.125 1.5) (size 0.604669 0.806226) (layers F.Paste))\n  (pad \"\" smd custom (at -0.375 0.5) (size 0.424561 0.424561) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.302335 -0.403113) (xy 0.047623 -0.403113) (xy 0.302335 -0.148401) (xy 0.302335 0.403113)\n         (xy -0.302335 0.403113)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.375 1.5) (size 0.424561 0.424561) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.302335 -0.403113) (xy 0.302335 -0.403113) (xy 0.302335 0.148401) (xy 0.047623 0.403113)\n         (xy -0.302335 0.403113)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.375 -1.5) (size 0.424561 0.424561) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.302335 -0.148401) (xy -0.047623 -0.403113) (xy 0.302335 -0.403113) (xy 0.302335 0.403113)\n         (xy -0.302335 0.403113)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.375 -0.5) (size 0.424561 0.424561) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.302335 -0.403113) (xy 0.302335 -0.403113) (xy 0.302335 0.403113) (xy -0.047623 0.403113)\n         (xy -0.302335 0.148401)) (width 0))\n    ))\n  (pad \"\" smd rect (at 1.125 -1.5) (size 0.604669 0.806226) (layers F.Paste))\n  (pad \"\" smd rect (at 1.125 -0.5) (size 0.604669 0.806226) (layers F.Paste))\n  (pad \"\" smd custom (at 0.375 0.5) (size 0.424561 0.424561) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.302335 -0.148401) (xy -0.047623 -0.403113) (xy 0.302335 -0.403113) (xy 0.302335 0.403113)\n         (xy -0.302335 0.403113)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.375 1.5) (size 0.424561 0.424561) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.302335 -0.403113) (xy 0.302335 -0.403113) (xy 0.302335 0.403113) (xy -0.047623 0.403113)\n         (xy -0.302335 0.148401)) (width 0))\n    ))\n  (pad \"\" smd rect (at 1.125 0.5) (size 0.604669 0.806226) (layers F.Paste))\n  (pad \"\" smd rect (at 1.125 1.5) (size 0.604669 0.806226) (layers F.Paste))\n  (pad \"\" smd rect (at -1.125 -2.25) (size 0.604669 0.403113) (layers F.Paste))\n  (pad \"\" smd custom (at -0.375 -2.25) (size 0.18875 0.18875) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.302335 -0.201556) (xy 0.302335 -0.201556) (xy 0.302335 -0.101599) (xy -0.000821 0.201556)\n         (xy -0.302335 0.201556)) (width 0))\n    ))\n  (pad \"\" smd rect (at -1.125 2.25) (size 0.604669 0.403113) (layers F.Paste))\n  (pad \"\" smd custom (at -0.375 2.25) (size 0.18875 0.18875) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.302335 -0.201556) (xy -0.000821 -0.201556) (xy 0.302335 0.101599) (xy 0.302335 0.201556)\n         (xy -0.302335 0.201556)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.375 -2.25) (size 0.18875 0.18875) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.302335 -0.201556) (xy 0.302335 -0.201556) (xy 0.302335 0.201556) (xy 0.000821 0.201556)\n         (xy -0.302335 -0.101599)) (width 0))\n    ))\n  (pad \"\" smd rect (at 1.125 -2.25) (size 0.604669 0.403113) (layers F.Paste))\n  (pad \"\" smd custom (at 0.375 2.25) (size 0.18875 0.18875) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.302335 0.101599) (xy 0.000821 -0.201556) (xy 0.302335 -0.201556) (xy 0.302335 0.201556)\n         (xy -0.302335 0.201556)) (width 0))\n    ))\n  (pad \"\" smd rect (at 1.125 2.25) (size 0.604669 0.403113) (layers F.Paste))\n)\"\"\"\n\nRESULT_EP_PASTE_GEN_INNER_ONLY_X_AND_OUTHER = \"\"\"(module exposed_paste_autogen (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value exposed_paste_autogen (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 3 smd rect (at 0 0) (size 4 3) (layers F.Cu F.Mask))\n  (pad 3 thru_hole circle (at -1 0) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 0 0) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 1 0) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 0 0) (size 2.6 0.6) (layers B.Cu))\n  (pad \"\" smd rect (at -0.75 -1.125) (size 0.403113 0.604669) (layers F.Paste))\n  (pad \"\" smd custom (at -0.75 -0.375) (size 0.33875 0.33875) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.201556 -0.302335) (xy 0.201556 -0.302335) (xy 0.201556 0.302335) (xy -0.110533 0.302335)\n         (xy -0.201556 0.211312)) (width 0))\n    ))\n  (pad \"\" smd rect (at -0.25 -1.125) (size 0.403113 0.604669) (layers F.Paste))\n  (pad \"\" smd custom (at -0.25 -0.375) (size 0.33875 0.33875) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.201556 -0.302335) (xy 0.201556 -0.302335) (xy 0.201556 0.211312) (xy 0.110533 0.302335)\n         (xy -0.201556 0.302335)) (width 0))\n    ))\n  (pad \"\" smd rect (at 0.25 -1.125) (size 0.403113 0.604669) (layers F.Paste))\n  (pad \"\" smd custom (at 0.25 -0.375) (size 0.33875 0.33875) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.201556 -0.302335) (xy 0.201556 -0.302335) (xy 0.201556 0.302335) (xy -0.110533 0.302335)\n         (xy -0.201556 0.211312)) (width 0))\n    ))\n  (pad \"\" smd rect (at 0.75 -1.125) (size 0.403113 0.604669) (layers F.Paste))\n  (pad \"\" smd custom (at 0.75 -0.375) (size 0.33875 0.33875) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.201556 -0.302335) (xy 0.201556 -0.302335) (xy 0.201556 0.211312) (xy 0.110533 0.302335)\n         (xy -0.201556 0.302335)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.75 0.375) (size 0.33875 0.33875) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.201556 -0.211312) (xy -0.110533 -0.302335) (xy 0.201556 -0.302335) (xy 0.201556 0.302335)\n         (xy -0.201556 0.302335)) (width 0))\n    ))\n  (pad \"\" smd rect (at -0.75 1.125) (size 0.403113 0.604669) (layers F.Paste))\n  (pad \"\" smd custom (at -0.25 0.375) (size 0.33875 0.33875) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.201556 -0.302335) (xy 0.110533 -0.302335) (xy 0.201556 -0.211312) (xy 0.201556 0.302335)\n         (xy -0.201556 0.302335)) (width 0))\n    ))\n  (pad \"\" smd rect (at -0.25 1.125) (size 0.403113 0.604669) (layers F.Paste))\n  (pad \"\" smd custom (at 0.25 0.375) (size 0.33875 0.33875) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.201556 -0.211312) (xy -0.110533 -0.302335) (xy 0.201556 -0.302335) (xy 0.201556 0.302335)\n         (xy -0.201556 0.302335)) (width 0))\n    ))\n  (pad \"\" smd rect (at 0.25 1.125) (size 0.403113 0.604669) (layers F.Paste))\n  (pad \"\" smd custom (at 0.75 0.375) (size 0.33875 0.33875) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.201556 -0.302335) (xy 0.110533 -0.302335) (xy 0.201556 -0.211312) (xy 0.201556 0.302335)\n         (xy -0.201556 0.302335)) (width 0))\n    ))\n  (pad \"\" smd rect (at 0.75 1.125) (size 0.403113 0.604669) (layers F.Paste))\n  (pad \"\" smd rect (at -1.5 -1.125) (size 0.806226 0.604669) (layers F.Paste))\n  (pad \"\" smd custom (at -1.5 -0.375) (size 0.574561 0.574561) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.403113 -0.302335) (xy 0.403113 -0.302335) (xy 0.403113 0.259755) (xy 0.360533 0.302335)\n         (xy -0.403113 0.302335)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.5 0.375) (size 0.574561 0.574561) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.403113 -0.302335) (xy 0.360533 -0.302335) (xy 0.403113 -0.259755) (xy 0.403113 0.302335)\n         (xy -0.403113 0.302335)) (width 0))\n    ))\n  (pad \"\" smd rect (at -1.5 1.125) (size 0.806226 0.604669) (layers F.Paste))\n  (pad \"\" smd rect (at 1.5 -1.125) (size 0.806226 0.604669) (layers F.Paste))\n  (pad \"\" smd custom (at 1.5 -0.375) (size 0.574561 0.574561) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.403113 -0.302335) (xy 0.403113 -0.302335) (xy 0.403113 0.302335) (xy -0.360533 0.302335)\n         (xy -0.403113 0.259755)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.5 0.375) (size 0.574561 0.574561) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.403113 -0.259755) (xy -0.360533 -0.302335) (xy 0.403113 -0.302335) (xy 0.403113 0.302335)\n         (xy -0.403113 0.302335)) (width 0))\n    ))\n  (pad \"\" smd rect (at 1.5 1.125) (size 0.806226 0.604669) (layers F.Paste))\n)\"\"\"\n\nRESULT_EP_PASTE_GEN_ONLY_OUTHER = \"\"\"(module exposed_paste_autogen (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value exposed_paste_autogen (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 3 smd rect (at 0 0) (size 2 2) (layers F.Cu F.Mask))\n  (pad 3 thru_hole circle (at 0 0) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 0 0) (size 0.6 0.6) (layers B.Cu))\n  (pad \"\" smd custom (at -0.5 -0.5) (size 0.743245 0.743245) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.403113 -0.403113) (xy 0.403113 -0.403113) (xy 0.403113 0.314044) (xy 0.314044 0.403113)\n         (xy -0.403113 0.403113)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.5 0.5) (size 0.743245 0.743245) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.403113 -0.403113) (xy 0.314044 -0.403113) (xy 0.403113 -0.314044) (xy 0.403113 0.403113)\n         (xy -0.403113 0.403113)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.5 -0.5) (size 0.743245 0.743245) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.403113 -0.403113) (xy 0.403113 -0.403113) (xy 0.403113 0.403113) (xy -0.314044 0.403113)\n         (xy -0.403113 0.314044)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.5 0.5) (size 0.743245 0.743245) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.403113 -0.314044) (xy -0.314044 -0.403113) (xy 0.403113 -0.403113) (xy 0.403113 0.403113)\n         (xy -0.403113 0.403113)) (width 0))\n    ))\n)\"\"\"\n\nRESULT_EP_BOTTOM_PAD = \"\"\"(module exposed_paste_autogen (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value exposed_paste_autogen (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 3 smd rect (at -2 -2) (size 2 2) (layers F.Cu F.Mask))\n  (pad 3 thru_hole circle (at -2 -2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad \"\" smd rect (at -2 -2) (size 1.61 1.61) (layers F.Paste))\n  (pad 3 smd rect (at 2 -2) (size 2 2) (layers F.Cu F.Mask))\n  (pad 3 thru_hole circle (at 2 -2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 2 -2) (size 3 3) (layers B.Cu B.Mask))\n  (pad \"\" smd rect (at 2 -2) (size 1.61 1.61) (layers F.Paste))\n)\"\"\"\n\nRESULT_EP_4x4 = \"\"\"(module exposed_paste_autogen (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value exposed_paste_autogen (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 33 smd rect (at 0 0) (size 3.55 3.55) (layers F.Cu F.Mask))\n  (pad 33 thru_hole circle (at -1 -1) (size 0.5 0.5) (drill 0.2) (layers *.Cu))\n  (pad 33 thru_hole circle (at 0 -1) (size 0.5 0.5) (drill 0.2) (layers *.Cu))\n  (pad 33 thru_hole circle (at 1 -1) (size 0.5 0.5) (drill 0.2) (layers *.Cu))\n  (pad 33 thru_hole circle (at -1 0) (size 0.5 0.5) (drill 0.2) (layers *.Cu))\n  (pad 33 thru_hole circle (at 0 0) (size 0.5 0.5) (drill 0.2) (layers *.Cu))\n  (pad 33 thru_hole circle (at 1 0) (size 0.5 0.5) (drill 0.2) (layers *.Cu))\n  (pad 33 thru_hole circle (at -1 1) (size 0.5 0.5) (drill 0.2) (layers *.Cu))\n  (pad 33 thru_hole circle (at 0 1) (size 0.5 0.5) (drill 0.2) (layers *.Cu))\n  (pad 33 thru_hole circle (at 1 1) (size 0.5 0.5) (drill 0.2) (layers *.Cu))\n  (pad 33 smd rect (at 0 0) (size 2.5 2.5) (layers B.Cu))\n  (pad \"\" smd custom (at -0.5 -0.5) (size 0.733981 0.733981) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.387298 -0.329859) (xy -0.329859 -0.387298) (xy 0.329859 -0.387298) (xy 0.387298 -0.329859)\n         (xy 0.387298 0.329859) (xy 0.329859 0.387298) (xy -0.329859 0.387298) (xy -0.387298 0.329859)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.5 0.5) (size 0.733981 0.733981) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.387298 -0.329859) (xy -0.329859 -0.387298) (xy 0.329859 -0.387298) (xy 0.387298 -0.329859)\n         (xy 0.387298 0.329859) (xy 0.329859 0.387298) (xy -0.329859 0.387298) (xy -0.387298 0.329859)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.5 -0.5) (size 0.733981 0.733981) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.387298 -0.329859) (xy -0.329859 -0.387298) (xy 0.329859 -0.387298) (xy 0.387298 -0.329859)\n         (xy 0.387298 0.329859) (xy 0.329859 0.387298) (xy -0.329859 0.387298) (xy -0.387298 0.329859)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.5 0.5) (size 0.733981 0.733981) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.387298 -0.329859) (xy -0.329859 -0.387298) (xy 0.329859 -0.387298) (xy 0.387298 -0.329859)\n         (xy 0.387298 0.329859) (xy 0.329859 0.387298) (xy -0.329859 0.387298) (xy -0.387298 0.329859)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.3875 -0.5) (size 0.541766 0.541766) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.300156 -0.387298) (xy 0.217359 -0.387298) (xy 0.300156 -0.304501) (xy 0.300156 0.304501)\n         (xy 0.217359 0.387298) (xy -0.300156 0.387298)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.3875 0.5) (size 0.541766 0.541766) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.300156 -0.387298) (xy 0.217359 -0.387298) (xy 0.300156 -0.304501) (xy 0.300156 0.304501)\n         (xy 0.217359 0.387298) (xy -0.300156 0.387298)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.3875 -0.5) (size 0.541766 0.541766) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.300156 -0.304501) (xy -0.217359 -0.387298) (xy 0.300156 -0.387298) (xy 0.300156 0.387298)\n         (xy -0.217359 0.387298) (xy -0.300156 0.304501)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.3875 0.5) (size 0.541766 0.541766) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.300156 -0.304501) (xy -0.217359 -0.387298) (xy 0.300156 -0.387298) (xy 0.300156 0.387298)\n         (xy -0.217359 0.387298) (xy -0.300156 0.304501)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.5 -1.3875) (size 0.541766 0.541766) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.387298 -0.300156) (xy 0.387298 -0.300156) (xy 0.387298 0.217359) (xy 0.304501 0.300156)\n         (xy -0.304501 0.300156) (xy -0.387298 0.217359)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.5 -1.3875) (size 0.541766 0.541766) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.387298 -0.300156) (xy 0.387298 -0.300156) (xy 0.387298 0.217359) (xy 0.304501 0.300156)\n         (xy -0.304501 0.300156) (xy -0.387298 0.217359)) (width 0))\n    ))\n  (pad \"\" smd custom (at -0.5 1.3875) (size 0.541766 0.541766) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.387298 -0.217359) (xy -0.304501 -0.300156) (xy 0.304501 -0.300156) (xy 0.387298 -0.217359)\n         (xy 0.387298 0.300156) (xy -0.387298 0.300156)) (width 0))\n    ))\n  (pad \"\" smd custom (at 0.5 1.3875) (size 0.541766 0.541766) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.387298 -0.217359) (xy -0.304501 -0.300156) (xy 0.304501 -0.300156) (xy 0.387298 -0.217359)\n         (xy 0.387298 0.300156) (xy -0.387298 0.300156)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.3875 -1.3875) (size 0.523835 0.523835) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.300156 -0.300156) (xy 0.300156 -0.300156) (xy 0.300156 0.192001) (xy 0.192001 0.300156)\n         (xy -0.300156 0.300156)) (width 0))\n    ))\n  (pad \"\" smd custom (at -1.3875 1.3875) (size 0.523835 0.523835) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.300156 -0.300156) (xy 0.192001 -0.300156) (xy 0.300156 -0.192001) (xy 0.300156 0.300156)\n         (xy -0.300156 0.300156)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.3875 -1.3875) (size 0.523835 0.523835) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.300156 -0.300156) (xy 0.300156 -0.300156) (xy 0.300156 0.300156) (xy -0.192001 0.300156)\n         (xy -0.300156 0.192001)) (width 0))\n    ))\n  (pad \"\" smd custom (at 1.3875 1.3875) (size 0.523835 0.523835) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.300156 -0.192001) (xy -0.192001 -0.300156) (xy 0.300156 -0.300156) (xy 0.300156 0.300156)\n         (xy -0.300156 0.300156)) (width 0))\n    ))\n)\"\"\"\n\nRESULT_EP_AUTOGEN_EDGECASE_1 = \"\"\"(module exposed_paste_autogen (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value exposed_paste_autogen (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 3 smd rect (at -2 -2) (size 2 2) (layers F.Cu F.Mask))\n  (pad 3 thru_hole circle (at -2.7 -2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at -1.3 -2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at -2 -2) (size 2 0.6) (layers B.Cu))\n  (pad \"\" smd custom (at -2 -2.5) (size 0.770649 0.770649) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.564358 -0.403113) (xy 0.564358 -0.403113) (xy 0.564358 0.352799) (xy 0.514044 0.403113)\n         (xy -0.514044 0.403113) (xy -0.564358 0.352799)) (width 0))\n    ))\n  (pad \"\" smd custom (at -2 -1.5) (size 0.770649 0.770649) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.564358 -0.352799) (xy -0.514044 -0.403113) (xy 0.514044 -0.403113) (xy 0.564358 -0.352799)\n         (xy 0.564358 0.403113) (xy -0.564358 0.403113)) (width 0))\n    ))\n  (pad 3 smd rect (at 2 -2) (size 2 2) (layers F.Cu F.Mask))\n  (pad 3 thru_hole circle (at 1.3 -2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 2.7 -2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 2 -2) (size 2 0.6) (layers B.Cu))\n  (pad \"\" smd custom (at 2 -2.5) (size 0.770649 0.770649) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.564358 -0.403113) (xy 0.564358 -0.403113) (xy 0.564358 0.352799) (xy 0.514044 0.403113)\n         (xy -0.514044 0.403113) (xy -0.564358 0.352799)) (width 0))\n    ))\n  (pad \"\" smd custom (at 2 -1.5) (size 0.770649 0.770649) (layers F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.564358 -0.352799) (xy -0.514044 -0.403113) (xy 0.514044 -0.403113) (xy 0.564358 -0.352799)\n         (xy 0.564358 0.403113) (xy -0.564358 0.403113)) (width 0))\n    ))\n  (pad \"\" smd rect (at 0 3) (size 2 2) (layers F.Mask))\n  (pad 3 smd rect (at 0 3) (size 3 3) (layers F.Cu))\n  (pad 3 thru_hole circle (at -1.2 3) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 1.2 3) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 0 3) (size 3 0.6) (layers B.Cu))\n  (pad \"\" smd rect (at 0 2.5) (size 1.61 0.81) (layers F.Paste))\n  (pad \"\" smd rect (at 0 3.5) (size 1.61 0.81) (layers F.Paste))\n)\"\"\"\n\nRESULT_EP_VIA_TENTING = \"\"\"(module exposed_paste_autogen (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value exposed_paste_autogen (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad \"\" smd rect (at -2 -2) (size 2 2) (layers F.Mask))\n  (pad 3 smd rect (at -2 -2) (size 3 3) (layers F.Cu))\n  (pad 3 thru_hole circle (at -3.2 -2) (size 0.6 0.6) (drill 0.3) (layers *.Cu F.Mask B.Mask))\n  (pad 3 thru_hole circle (at -0.8 -2) (size 0.6 0.6) (drill 0.3) (layers *.Cu F.Mask B.Mask))\n  (pad 3 smd rect (at -2 -2) (size 3 0.6) (layers B.Cu))\n  (pad \"\" smd rect (at -2 -2.5) (size 1.61 0.81) (layers F.Paste))\n  (pad \"\" smd rect (at -2 -1.5) (size 1.61 0.81) (layers F.Paste))\n  (pad \"\" smd rect (at 2 -2) (size 2 2) (layers F.Mask))\n  (pad 3 smd rect (at 2 -2) (size 3 3) (layers F.Cu))\n  (pad 3 thru_hole circle (at 0.8 -2) (size 0.6 0.6) (drill 0.3) (layers *.Cu F.Mask))\n  (pad 3 thru_hole circle (at 3.2 -2) (size 0.6 0.6) (drill 0.3) (layers *.Cu F.Mask))\n  (pad 3 smd rect (at 2 -2) (size 3 0.6) (layers B.Cu))\n  (pad \"\" smd rect (at 2 -2.5) (size 1.61 0.81) (layers F.Paste))\n  (pad \"\" smd rect (at 2 -1.5) (size 1.61 0.81) (layers F.Paste))\n  (pad \"\" smd rect (at -2 2) (size 2 2) (layers F.Mask))\n  (pad 3 smd rect (at -2 2) (size 3 3) (layers F.Cu))\n  (pad 3 thru_hole circle (at -3.2 2) (size 0.6 0.6) (drill 0.3) (layers *.Cu B.Mask))\n  (pad 3 thru_hole circle (at -0.8 2) (size 0.6 0.6) (drill 0.3) (layers *.Cu B.Mask))\n  (pad 3 smd rect (at -2 2) (size 3 0.6) (layers B.Cu))\n  (pad \"\" smd rect (at -2 1.5) (size 1.61 0.81) (layers F.Paste))\n  (pad \"\" smd rect (at -2 2.5) (size 1.61 0.81) (layers F.Paste))\n  (pad \"\" smd rect (at 2 2) (size 2 2) (layers F.Mask))\n  (pad 3 smd rect (at 2 2) (size 3 3) (layers F.Cu))\n  (pad 3 thru_hole circle (at 0.8 2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 thru_hole circle (at 3.2 2) (size 0.6 0.6) (drill 0.3) (layers *.Cu))\n  (pad 3 smd rect (at 2 2) (size 3 0.6) (layers B.Cu))\n  (pad \"\" smd rect (at 2 1.5) (size 1.61 0.81) (layers F.Paste))\n  (pad \"\" smd rect (at 2 2.5) (size 1.61 0.81) (layers F.Paste))\n)\"\"\"\n\n\nclass ExposedPadTests(unittest.TestCase):\n\n    def testSimpleExposedPad(self):\n        kicad_mod = Footprint(\"simple_exposed\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"simple_exposed\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=3, at=[0, 1], size=[2.1, 3],\n            mask_size=[2.1, 2.1], paste_layout=[2, 3], via_layout=[3, 2]\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep.kicad_mod')\n        self.assertEqual(result, RESULT_SIMPLE_EP_FP)\n\n    def testSimpleExposedPadNoRounding(self):\n        kicad_mod = Footprint(\"simple_exposed\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"simple_exposed\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=3, at=[0, 1], size=[2.1, 3],\n            mask_size=[2.1, 2.1], paste_layout=[2, 3], via_layout=[3, 2],\n            grid_round_base=None, size_round_base=0\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep.kicad_mod')\n        self.assertEqual(result, RESULT_SIMPLE_EP_NO_ROUNDING_FP)\n\n    def testSimpleExposedMinimal(self):\n        kicad_mod = Footprint(\"simple_exposed\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"simple_exposed\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[2.1, 3], paste_layout=2, via_layout=3\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep.kicad_mod')\n        self.assertEqual(result, RESULT_MINIMAL_EP_SPECIFICATION)\n\n    def testExposedPasteAutogenInner(self):\n        kicad_mod = Footprint(\"exposed_paste_autogen\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"exposed_paste_autogen\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[5, 5], paste_layout=3, via_layout=2,\n            paste_avoid_via=True\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep.kicad_mod')\n        self.assertEqual(result, RESULT_EP_PASTE_GEN_INNER)\n\n    def testExposedPasteAutogenInner2(self):\n        kicad_mod = Footprint(\"exposed_paste_autogen\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"exposed_paste_autogen\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[5, 5], paste_layout=6, via_layout=4,\n            paste_avoid_via=True, paste_coverage=0.5\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep1.kicad_mod')\n        self.assertEqual(result, RESULT_EP_PASTE_GEN_INNER2)\n\n    def testExposedPasteAutogenInnerAndOuther(self):\n        kicad_mod = Footprint(\"exposed_paste_autogen\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"exposed_paste_autogen\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[12, 8], paste_between_vias=2,\n            paste_rings_outside=2, via_layout=3,\n            paste_avoid_via=True, paste_coverage=0.7, via_grid=[3, 2],\n            via_paste_clarance=0.25, min_annular_ring=0.25, at=[7, 5]\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep.kicad_mod')\n        self.assertEqual(result, RESULT_EP_PASTE_GEN_INNER_AND_OUTHER)\n\n    def testExposedPasteAutogenInnerYonlyAndOuther(self):\n        kicad_mod = Footprint(\"exposed_paste_autogen\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"exposed_paste_autogen\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[3, 5], paste_between_vias=2, paste_rings_outside=[2, 1], via_layout=[1, 3],\n            paste_avoid_via=True, paste_coverage=0.65, via_grid=2, via_paste_clarance=0.15\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep.kicad_mod')\n        self.assertEqual(result, RESULT_EP_PASTE_GEN_INNER_ONLY_Y_AND_OUTHER)\n\n    def testExposedPasteAutogenInnerXonlyAndOuther(self):\n        kicad_mod = Footprint(\"exposed_paste_autogen\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"exposed_paste_autogen\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[4, 3], paste_between_vias=2, paste_rings_outside=[1, 2], via_layout=[3, 1],\n            paste_avoid_via=True, paste_coverage=0.65, via_grid=1, via_paste_clarance=0.0\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep.kicad_mod')\n        self.assertEqual(result, RESULT_EP_PASTE_GEN_INNER_ONLY_X_AND_OUTHER)\n\n    def testExposedPasteAutogenOnlyOuther(self):\n        kicad_mod = Footprint(\"exposed_paste_autogen\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"exposed_paste_autogen\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[2, 2], paste_between_vias=0, paste_rings_outside=[1, 1], via_layout=[1, 1],\n            paste_avoid_via=True, paste_coverage=0.65, via_grid=1.5\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep.kicad_mod')\n        self.assertEqual(result, RESULT_EP_PASTE_GEN_ONLY_OUTHER)\n\n    def testExposedPasteBottomPadTests(self):\n        kicad_mod = Footprint(\"exposed_paste_autogen\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"exposed_paste_autogen\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[2, 2], via_layout=[1, 1], at=[-2, -2],\n            paste_coverage=0.65, via_grid=1, bottom_pad_Layers=None\n            ))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[2, 2], via_layout=[1, 1], at=[2, -2],\n            paste_coverage=0.65, via_grid=1, bottom_pad_Layers=['B.Cu', 'B.Mask'],\n            bottom_pad_min_size=[3, 3]\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep.kicad_mod')\n        self.assertEqual(result, RESULT_EP_BOTTOM_PAD)\n\n    def testExposed4x4paste(self):\n        kicad_mod = Footprint(\"exposed_paste_autogen\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"exposed_paste_autogen\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=33, size=[3.55, 3.55],\n            paste_layout=[3, 3],\n            paste_between_vias=1,\n            paste_rings_outside=1,\n            paste_coverage=0.6,\n            via_layout=[3, 3],\n            via_drill=0.2,\n            via_grid=[1, 1],\n            paste_avoid_via=True,\n            via_paste_clarance=0.1,\n            min_annular_ring=0.15,\n            bottom_pad_min_size=[0, 0]\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep.kicad_mod')\n        self.assertEqual(result, RESULT_EP_4x4)\n\n    def testExposedPadEdgeCase1(self):\n        kicad_mod = Footprint(\"exposed_paste_autogen\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"exposed_paste_autogen\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[2, 2], via_layout=[2, 1], at=[-2, -2],\n            paste_coverage=0.65, paste_layout=[1, 2],\n            paste_avoid_via=True\n            ))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[2, 2], via_layout=[2, 1], at=[2, -2],\n            paste_coverage=0.65, paste_layout=[1, 2],\n            paste_avoid_via=True\n            ))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[3, 3], via_layout=[2, 1], at=[0, 3],\n            paste_coverage=0.65, paste_layout=[1, 2], mask_size=[2, 2],\n            paste_avoid_via=True\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep.kicad_mod')\n        self.assertEqual(result, RESULT_EP_AUTOGEN_EDGECASE_1)\n\n    def testExposedPasteViaTented(self):\n        kicad_mod = Footprint(\"exposed_paste_autogen\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"exposed_paste_autogen\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[3, 3], via_layout=[2, 1], at=[-2, -2],\n            paste_coverage=0.65, paste_layout=[1, 2], mask_size=[2, 2],\n            paste_avoid_via=True, via_tented=ExposedPad.VIA_NOT_TENTED\n            ))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[3, 3], via_layout=[2, 1], at=[2, -2],\n            paste_coverage=0.65, paste_layout=[1, 2], mask_size=[2, 2],\n            paste_avoid_via=True, via_tented=ExposedPad.VIA_TENTED_BOTTOM_ONLY\n            ))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[3, 3], via_layout=[2, 1], at=[-2, 2],\n            paste_coverage=0.65, paste_layout=[1, 2], mask_size=[2, 2],\n            paste_avoid_via=True, via_tented=ExposedPad.VIA_TENTED_TOP_ONLY\n            ))\n\n        kicad_mod.append(ExposedPad(\n            number=3, size=[3, 3], via_layout=[2, 1], at=[2, 2],\n            paste_coverage=0.65, paste_layout=[1, 2], mask_size=[2, 2],\n            paste_avoid_via=True, via_tented=ExposedPad.VIA_TENTED\n            ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_ep.kicad_mod')\n        self.assertEqual(result, RESULT_EP_VIA_TENTING)\n"
  },
  {
    "path": "KicadModTree/tests/moduletests/test_kicad5_padshapes.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n# (C) 2018 by Rene Poeschl, github @poeschlr\n\nfrom __future__ import division\n\nimport unittest\n\nfrom KicadModTree import *\n\nRESULT_ROUNDRECT_FP = \"\"\"(module round_rect_test (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value round_rect_test (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 3 smd roundrect (at 5 0 45) (size 1 1) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.1))\n  (pad 2 smd roundrect (at -5 0) (size 1 1) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.5))\n  (pad 1 smd rect (at 0 0) (size 1 1) (layers F.Cu F.Mask F.Paste))\n)\"\"\"\n\nRESULT_ROUNDRECT_FP2 = \"\"\"(module round_rect_test (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value round_rect_test (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 3 smd roundrect (at 5 0 45) (size 1 1) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))\n  (pad 2 smd roundrect (at -5 0) (size 1 2) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.25))\n  (pad 1 smd roundrect (at 0 0) (size 2 4) (layers F.Cu F.Mask F.Paste) (roundrect_rratio 0.125))\n)\"\"\"\n\nRESULT_SIMPLE_POLYGON_PAD = \"\"\"(module round_rect_test (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value round_rect_test (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 1 smd custom (at 0 0) (size 1 1) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -1 -1) (xy 2 -1) (xy 1 1) (xy -1 2)) (width 0))\n    ))\n)\"\"\"\n\nRESULT_SIMPLE_OTHER_CUSTOM_PAD = \"\"\"(module round_rect_test (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value round_rect_test (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 1 smd custom (at 0 0) (size 1 1) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_arc (start -1 0) (end -1 -0.5) (angle -180) (width 0.15))\n      (gr_line (start -1 -0.5) (end 1.25 -0.5) (width 0.15))\n      (gr_line (start 1.25 -0.5) (end 1.25 0.5) (width 0.15))\n      (gr_line (start 1.25 0.5) (end -1 0.5) (width 0.15))\n    ))\n  (pad 2 smd custom (at 0 3) (size 1 1) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_arc (start -1 0) (end -1 -0.5) (angle -180) (width 0.15))\n      (gr_line (start -1 -0.5) (end 1.25 -0.5) (width 0.15))\n      (gr_line (start 1.25 -0.5) (end 1.25 0.5) (width 0.15))\n      (gr_line (start 1.25 0.5) (end -1 0.5) (width 0.15))\n    ))\n  (pad 3 smd custom (at 0 -3) (size 1 1) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_circle (center 0.5 0.5) (end 1 0.5) (width 0.15))\n    ))\n)\"\"\"\n\nRESULT_CUT_POLYGON = \"\"\"(module round_rect_test (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value round_rect_test (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 1 smd custom (at 0 0) (size 0.5 0.5) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -2 -2) (xy 2 -2) (xy 2 2) (xy 1 1)\n         (xy 1 0) (xy 0 0) (xy 0 1) (xy 1 1)\n         (xy 2 2) (xy -2 2)) (width 0))\n    ))\n)\"\"\"\n\nRESULT_CHAMFERED_PAD = \"\"\"(module chamfered_pad (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value chamfered_pad (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 1 smd custom (at 0 0) (size 0.764298 0.764298) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -0.166667) (xy -0.166667 -0.5) (xy 0.166667 -0.5) (xy 0.5 -0.166667)\n         (xy 0.5 0.166667) (xy 0.166667 0.5) (xy -0.166667 0.5) (xy -0.5 0.166667)) (width 0))\n    ))\n  (pad 1 smd custom (at 2 2) (size 1.357538 1.357538) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -1.05 -0.5) (xy -0.55 -1.55) (xy 0.55 -1.55) (xy 1.05 -0.5)\n         (xy 1.05 0.5) (xy 0.55 1.55) (xy -0.55 1.55) (xy -1.05 0.5)) (width 0))\n    ))\n)\"\"\"\n\nRESULT_CHAMFERED_PAD_AVOID_CIRCLE = \"\"\"(module test_avoid_circle (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value test_avoid_circle (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_circle (center 3 3.5) (end 3.3 3.5) (layer F.SilkS) (width 0.01))\n  (pad 1 smd custom (at 2 2.5) (size 1.445 1.445) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.875 -0.693665) (xy -0.443665 -1.125) (xy 0.443665 -1.125) (xy 0.875 -0.693665)\n         (xy 0.875 0.693665) (xy 0.443665 1.125) (xy -0.443665 1.125) (xy -0.875 0.693665)) (width 0))\n    ))\n)\"\"\"\n\nRESULT_CHAMFERED_PAD_GRID = \"\"\"(module test_chamfered_grid (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value test_chamfered_grid (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 1 smd custom (at 0 -1.25) (size 0.823223 0.823223) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -0.75) (xy -0.25 -1) (xy 0.5 -1) (xy 0.5 1)\n         (xy -0.25 1) (xy -0.5 0.75)) (width 0))\n    ))\n  (pad 1 smd custom (at 0 1.25) (size 0.823223 0.823223) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -0.75) (xy -0.25 -1) (xy 0.5 -1) (xy 0.5 1)\n         (xy -0.25 1) (xy -0.5 0.75)) (width 0))\n    ))\n  (pad 1 smd custom (at 0 3.75) (size 0.823223 0.823223) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -0.75) (xy -0.25 -1) (xy 0.5 -1) (xy 0.5 1)\n         (xy -0.25 1) (xy -0.5 0.75)) (width 0))\n    ))\n  (pad 1 smd custom (at 0 6.25) (size 0.823223 0.823223) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -0.75) (xy -0.25 -1) (xy 0.5 -1) (xy 0.5 1)\n         (xy -0.25 1) (xy -0.5 0.75)) (width 0))\n    ))\n  (pad 1 smd custom (at 1.5 -1.25) (size 0.823223 0.823223) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -0.75) (xy -0.25 -1) (xy 0.25 -1) (xy 0.5 -0.75)\n         (xy 0.5 1) (xy -0.5 1)) (width 0))\n    ))\n  (pad 1 smd rect (at 1.5 1.25) (size 1 2) (layers F.Cu F.Mask F.Paste))\n  (pad 1 smd rect (at 1.5 3.75) (size 1 2) (layers F.Cu F.Mask F.Paste))\n  (pad 1 smd custom (at 1.5 6.25) (size 0.823223 0.823223) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -1) (xy 0.5 -1) (xy 0.5 0.75) (xy 0.25 1)\n         (xy -0.25 1) (xy -0.5 0.75)) (width 0))\n    ))\n  (pad 1 smd custom (at 3 -1.25) (size 0.823223 0.823223) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -1) (xy 0.25 -1) (xy 0.5 -0.75) (xy 0.5 0.75)\n         (xy 0.25 1) (xy -0.5 1)) (width 0))\n    ))\n  (pad 1 smd custom (at 3 1.25) (size 0.823223 0.823223) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -1) (xy 0.25 -1) (xy 0.5 -0.75) (xy 0.5 0.75)\n         (xy 0.25 1) (xy -0.5 1)) (width 0))\n    ))\n  (pad 1 smd custom (at 3 3.75) (size 0.823223 0.823223) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -1) (xy 0.25 -1) (xy 0.5 -0.75) (xy 0.5 0.75)\n         (xy 0.25 1) (xy -0.5 1)) (width 0))\n    ))\n  (pad 1 smd custom (at 3 6.25) (size 0.823223 0.823223) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -1) (xy 0.25 -1) (xy 0.5 -0.75) (xy 0.5 0.75)\n         (xy 0.25 1) (xy -0.5 1)) (width 0))\n    ))\n)\"\"\"\n\nRESULT_CHAMFERED_PAD_GRID_AVOID_CIRCLE = \"\"\"(module test_chamfered_grid (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value test_chamfered_grid (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_circle (center 2 2.5) (end 2.2 2.5) (layer F.SilkS) (width 0.01))\n  (pad 1 smd custom (at -1.4 -2.1) (size 0.795 0.795) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -0.210086) (xy -0.210086 -0.5) (xy 0.5 -0.5) (xy 0.5 0.5)\n         (xy -0.5 0.5)) (width 0))\n    ))\n  (pad 1 smd rect (at -1.4 -0.7) (size 1 1) (layers F.Cu F.Mask F.Paste))\n  (pad 1 smd rect (at -1.4 0.7) (size 1 1) (layers F.Cu F.Mask F.Paste))\n  (pad 1 smd custom (at -1.4 2.1) (size 0.795 0.795) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -0.5) (xy 0.5 -0.5) (xy 0.5 0.5) (xy -0.210086 0.5)\n         (xy -0.5 0.210086)) (width 0))\n    ))\n  (pad 1 smd rect (at 0 -2.1) (size 1 1) (layers F.Cu F.Mask F.Paste))\n  (pad 1 smd rect (at 0 -0.7) (size 1 1) (layers F.Cu F.Mask F.Paste))\n  (pad 1 smd rect (at 0 0.7) (size 1 1) (layers F.Cu F.Mask F.Paste))\n  (pad 1 smd rect (at 0 2.1) (size 1 1) (layers F.Cu F.Mask F.Paste))\n  (pad 1 smd custom (at 1.4 -2.1) (size 0.795 0.795) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -0.5) (xy 0.210086 -0.5) (xy 0.5 -0.210086) (xy 0.5 0.5)\n         (xy -0.5 0.5)) (width 0))\n    ))\n  (pad 1 smd rect (at 1.4 -0.7) (size 1 1) (layers F.Cu F.Mask F.Paste))\n  (pad 1 smd rect (at 1.4 0.7) (size 1 1) (layers F.Cu F.Mask F.Paste))\n  (pad 1 smd custom (at 1.4 2.1) (size 0.795 0.795) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -0.5 -0.5) (xy 0.5 -0.5) (xy 0.5 0.210086) (xy 0.210086 0.5)\n         (xy -0.5 0.5)) (width 0))\n    ))\n)\"\"\"\n\nRESULT_CHAMFERED_ROUNDED_PAD = \"\"\"(module chamfered_pad (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value chamfered_pad (at 0 0) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (pad 1 smd custom (at 0 0) (size 3.646447 3.646447) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -2 -1.5) (xy -1.5 -2) (xy 1.5 -2) (xy 2 -1.5)\n         (xy 2 1.5) (xy 1.5 2) (xy -1.5 2) (xy -2 1.5)) (width 0))\n    ))\n  (pad 1 smd roundrect (at 0 0) (size 4 4) (layers B.Cu) (roundrect_rratio 0.25))\n  (pad 1 smd custom (at 0 5) (size 2.292893 2.292893) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -2 -0.5) (xy -1 -1.5) (xy 1 -1.5) (xy 2 -0.5)\n         (xy 2 0.5) (xy 1 1.5) (xy -1 1.5) (xy -2 0.5)) (width 0))\n    ))\n  (pad 1 smd custom (at 0 5) (size 2.292893 2.292893) (layers B.Cu)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -1.292893 -0.207107) (xy -0.707107 -0.792893) (xy 0.707107 -0.792893) (xy 1.292893 -0.207107)\n         (xy 1.292893 0.207107) (xy 0.707107 0.792893) (xy -0.707107 0.792893) (xy -1.292893 0.207107)) (width 1.414214))\n    ))\n  (pad 1 smd custom (at 5 0) (size 2.292893 2.292893) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -2 -0.5) (xy -1 -1.5) (xy 2 -1.5) (xy 2 0.5)\n         (xy 1 1.5) (xy -2 1.5)) (width 0))\n    ))\n  (pad 1 smd custom (at 5 0) (size 2.292893 2.292893) (layers B.Cu)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -1.292893 -0.207107) (xy -0.707107 -0.792893) (xy 1.292893 -0.792893) (xy 1.292893 0.207107)\n         (xy 0.707107 0.792893) (xy -1.292893 0.792893)) (width 1.414214))\n    ))\n)\"\"\"  # NOQA: E501\n\n\nclass Kicad5PadsTests(unittest.TestCase):\n\n    def testRoundRectPad(self):\n        kicad_mod = Footprint(\"round_rect_test\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"round_rect_test\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(Pad(number=3, type=Pad.TYPE_SMT, shape=Pad.SHAPE_ROUNDRECT,\n                             at=[5, 0], rotation=45, size=[1, 1], layers=Pad.LAYERS_SMT,\n                             radius_ratio=0.1))\n\n        kicad_mod.append(Pad(number=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_ROUNDRECT,\n                             at=[-5, 0], size=[1, 1], layers=Pad.LAYERS_SMT,\n                             radius_ratio=0.5))\n\n        kicad_mod.append(Pad(number=1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_ROUNDRECT,\n                             at=[0, 0], size=[1, 1], layers=Pad.LAYERS_SMT,\n                             radius_ratio=0))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test.kicad_mod')\n        self.assertEqual(result, RESULT_ROUNDRECT_FP)\n\n    def testRoundRectPad2(self):\n        kicad_mod = Footprint(\"round_rect_test\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"round_rect_test\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(Pad(number=3, type=Pad.TYPE_SMT, shape=Pad.SHAPE_ROUNDRECT,\n                             at=[5, 0], rotation=45, size=[1, 1], layers=Pad.LAYERS_SMT,\n                             radius_ratio=0.25, maximum_radius=0.25))\n\n        kicad_mod.append(Pad(number=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_ROUNDRECT,\n                             at=[-5, 0], size=[1, 2], layers=Pad.LAYERS_SMT,\n                             radius_ratio=0.25, maximum_radius=0.25))\n\n        kicad_mod.append(Pad(number=1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_ROUNDRECT,\n                             at=[0, 0], size=[2, 4], layers=Pad.LAYERS_SMT,\n                             radius_ratio=0.25, maximum_radius=0.25))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_max_radius.kicad_mod')\n        self.assertEqual(result, RESULT_ROUNDRECT_FP2)\n\n    def testPolygonPad(self):\n        kicad_mod = Footprint(\"round_rect_test\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"round_rect_test\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(Pad(number=1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_CUSTOM,\n                             at=[0, 0], size=[1, 1], layers=Pad.LAYERS_SMT,\n                             primitives=[Polygon(nodes=[(-1, -1), (2, -1), (1, 1), (-1, 2)])]\n                             ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test.kicad_mod')\n        self.assertEqual(result, RESULT_SIMPLE_POLYGON_PAD)\n\n    def testCustomPadOtherPrimitives(self):\n        kicad_mod = Footprint(\"round_rect_test\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"round_rect_test\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(\n            Pad(number=1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_CUSTOM,\n                at=[0, 0], size=[1, 1], layers=Pad.LAYERS_SMT,\n                primitives=[\n                     Arc(center=(-1, 0), start=(-1, -0.5), angle=-180, width=0.15),\n                     Line(start=(-1, -0.5), end=(1.25, -0.5), width=0.15),\n                     Line(start=(1.25, -0.5), end=(1.25, 0.5), width=0.15),\n                     Line(start=(1.25, 0.5), end=(-1, 0.5), width=0.15)\n                     ]\n                ))\n\n        kicad_mod.append(\n            Pad(number=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_CUSTOM,\n                at=[0, 3], size=[1, 1], layers=Pad.LAYERS_SMT,\n                primitives=[\n                     Arc(center=(-1, 0), start=(-1, -0.5), angle=-180, width=0.15),\n                     PolygoneLine(nodes=[(-1, -0.5), (1.25, -0.5), (1.25, 0.5), (-1, 0.5)], width=0.15)\n                     ]\n                ))\n\n        kicad_mod.append(\n            Pad(number=3, type=Pad.TYPE_SMT, shape=Pad.SHAPE_CUSTOM,\n                at=[0, -3], size=[1, 1], layers=Pad.LAYERS_SMT,\n                primitives=[\n                        Circle(center=(0.5, 0.5), radius=0.5, width=0.15)\n                     ]\n                ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test.kicad_mod')\n        self.assertEqual(result, RESULT_SIMPLE_OTHER_CUSTOM_PAD)\n\n    def testCutPolygon(self):\n        kicad_mod = Footprint(\"round_rect_test\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"round_rect_test\", at=[0, 0], layer='F.Fab'))\n\n        p1 = Polygon(nodes=[(0, 0), (1, 0), (1, 1), (0, 1)])\n        p2 = Polygon(nodes=[(-2, -2), (2, -2), (2, 2), (-2, 2)])\n        p2.cut(p1)\n\n        kicad_mod.append(Pad(number=1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_CUSTOM,\n                             at=[0, 0], size=[0.5, 0.5], layers=Pad.LAYERS_SMT,\n                             primitives=[p2]\n                             ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test.kicad_mod')\n        self.assertEqual(result, RESULT_CUT_POLYGON)\n\n    def testChamferedPad(self):\n        kicad_mod = Footprint(\"chamfered_pad\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"chamfered_pad\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(\n            ChamferedPad(number=1, type=Pad.TYPE_SMT,\n                         at=[0, 0], size=[1, 1], layers=Pad.LAYERS_SMT, chamfer_size=[1/3, 1/3],\n                         corner_selection=[1, 1, 1, 1]\n                         ))\n\n        kicad_mod.append(\n            ChamferedPad(number=1, type=Pad.TYPE_SMT,\n                         at=[2, 2], size=[2.1, 3.1], layers=Pad.LAYERS_SMT, chamfer_size=[0.5, 1.05],\n                         corner_selection=[1, 1, 1, 1]\n                         ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_cp.kicad_mod')\n        self.assertEqual(result, RESULT_CHAMFERED_PAD)\n\n    def testChamferedPadAvoidCircle(self):\n        kicad_mod = Footprint(\"test_avoid_circle\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"test_avoid_circle\", at=[0, 0], layer='F.Fab'))\n\n        pad = ChamferedPad(\n                    number=1, type=Pad.TYPE_SMT, at=[2, 2.5],\n                    size=[1.75, 2.25], layers=Pad.LAYERS_SMT, chamfer_size=[0.25, 0.25],\n                    corner_selection=[1, 1, 1, 1]\n                    )\n\n        c = [3, 3.5]\n        d = 0.6\n\n        kicad_mod.append(Circle(center=c, radius=d/2, width=0.01))\n        pad.chamferAvoidCircle(center=c, diameter=d, clearance=0.005)\n        kicad_mod.append(pad)\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_avoid_circle.kicad_mod')\n        self.assertEqual(result, RESULT_CHAMFERED_PAD_AVOID_CIRCLE)\n\n    def testChamferedPadGrid(self):\n        kicad_mod = Footprint(\"test_chamfered_grid\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"test_chamfered_grid\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(\n            ChamferedPadGrid(\n                        number=1, type=Pad.TYPE_SMT,\n                        center=[1.5, 2.5], size=[1, 2], layers=Pad.LAYERS_SMT,\n                        chamfer_size=[0.25, 0.25], chamfer_selection=1,\n                        pincount=[3, 4], grid=[1.5, 2.5]\n                        ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_chamfered_grid.kicad_mod')\n        self.assertEqual(result, RESULT_CHAMFERED_PAD_GRID)\n\n    def testChamferedPadGridCornerOnly(self):\n        kicad_mod = Footprint(\"test_chamfered_grid\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"test_chamfered_grid\", at=[0, 0], layer='F.Fab'))\n\n        chamfer_select = ChamferSelPadGrid(0)\n        chamfer_select.setCorners()\n\n        pad = ChamferedPadGrid(\n                        number=1, type=Pad.TYPE_SMT,\n                        center=[0, 0], size=[1, 1], layers=Pad.LAYERS_SMT,\n                        chamfer_size=[0.25, 0.25], chamfer_selection=chamfer_select,\n                        pincount=[3, 4], grid=[1.4, 1.4]\n                        )\n\n        c = [2.0, 2.5]\n        d = 0.4\n\n        kicad_mod.append(Circle(center=c, radius=d/2, width=0.01))\n        pad.chamferAvoidCircle(center=c, diameter=d, clearance=0.005)\n        kicad_mod.append(pad)\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_chamfered_grid.kicad_mod')\n        self.assertEqual(result, RESULT_CHAMFERED_PAD_GRID_AVOID_CIRCLE)\n\n    def testChamferedRoundedPad(self):\n        kicad_mod = Footprint(\"chamfered_pad\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, 0], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"chamfered_pad\", at=[0, 0], layer='F.Fab'))\n\n        kicad_mod.append(\n            ChamferedPad(number=1, type=Pad.TYPE_SMT,\n                         at=[0, 0], size=[4, 4], layers=Pad.LAYERS_SMT, chamfer_size=[0.5, 0.5],\n                         corner_selection=[1, 1, 1, 1]\n                         ))\n\n        kicad_mod.append(\n            ChamferedPad(number=1, type=Pad.TYPE_SMT,\n                         at=[0, 0], size=[4, 4], layers=[\"B.Cu\"], chamfer_size=[0.5, 0.5],\n                         corner_selection=[1, 1, 1, 1], radius_ratio=0.25\n                         ))\n\n        kicad_mod.append(\n            ChamferedPad(number=1, type=Pad.TYPE_SMT,\n                         at=[0, 5], size=[4, 3], layers=Pad.LAYERS_SMT, chamfer_size=[1, 1],\n                         corner_selection=[1, 1, 1, 1]\n                         ))\n\n        kicad_mod.append(\n            ChamferedPad(number=1, type=Pad.TYPE_SMT,\n                         at=[0, 5], size=[4, 3], layers=[\"B.Cu\"], chamfer_size=[1, 1],\n                         corner_selection=[1, 1, 1, 1], radius_ratio=0.25\n                         ))\n\n        kicad_mod.append(\n            ChamferedPad(number=1, type=Pad.TYPE_SMT,\n                         at=[5, 0], size=[4, 3], layers=Pad.LAYERS_SMT, chamfer_size=[1, 1],\n                         corner_selection=[1, 0, 1, 0]\n                         ))\n\n        kicad_mod.append(\n            ChamferedPad(number=1, type=Pad.TYPE_SMT,\n                         at=[5, 0], size=[4, 3], layers=[\"B.Cu\"], chamfer_size=[1, 1],\n                         corner_selection=[1, 0, 1, 0], radius_ratio=0.25\n                         ))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        result = file_handler.serialize(timestamp=0)\n        # file_handler.writeFile('test_cp.kicad_mod')\n        self.assertEqual(result, RESULT_CHAMFERED_ROUNDED_PAD)\n"
  },
  {
    "path": "KicadModTree/tests/moduletests/test_rotation.py",
    "content": "import unittest\nimport math\nfrom KicadModTree import *\n\nRESULT_rotText = \"\"\"(module test_rotate (layer F.Cu) (tedit 0)\n  (fp_text user -1 (at 2 0) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text user -1 (at 1.414214 1.414214 -45) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text user -1 (at 0 2 -90) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text user -1 (at -1.414214 1.414214 -135) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text user -1 (at -2 0 -180) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text user -1 (at -1.414214 -1.414214 -225) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text user -1 (at 0 -2 -270) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text user -1 (at 1.414214 -1.414214 -315) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n)\"\"\"\n\nRESULT_rotLine = \"\"\"(module test_rotate (layer F.Cu) (tedit 0)\n  (fp_line (start 6 0) (end 7 1) (layer F.SilkS) (width 0.12))\n  (fp_line (start 5.931852 0.517638) (end 6.638958 1.742383) (layer F.SilkS) (width 0.12))\n  (fp_line (start 5.732051 1) (end 6.098076 2.366025) (layer F.SilkS) (width 0.12))\n  (fp_line (start 5.414214 1.414214) (end 5.414214 2.828427) (layer F.SilkS) (width 0.12))\n  (fp_line (start 5 1.732051) (end 4.633975 3.098076) (layer F.SilkS) (width 0.12))\n  (fp_line (start 4.517638 1.931852) (end 3.810531 3.156597) (layer F.SilkS) (width 0.12))\n  (fp_line (start 4 2) (end 3 3) (layer F.SilkS) (width 0.12))\n  (fp_line (start 3.482362 1.931852) (end 2.257617 2.638958) (layer F.SilkS) (width 0.12))\n  (fp_line (start 3 1.732051) (end 1.633975 2.098076) (layer F.SilkS) (width 0.12))\n  (fp_line (start 2.585786 1.414214) (end 1.171573 1.414214) (layer F.SilkS) (width 0.12))\n  (fp_line (start 2.267949 1) (end 0.901924 0.633975) (layer F.SilkS) (width 0.12))\n  (fp_line (start 2.068148 0.517638) (end 0.843403 -0.189469) (layer F.SilkS) (width 0.12))\n  (fp_line (start 2 0) (end 1 -1) (layer F.SilkS) (width 0.12))\n  (fp_line (start 2.068148 -0.517638) (end 1.361042 -1.742383) (layer F.SilkS) (width 0.12))\n  (fp_line (start 2.267949 -1) (end 1.901924 -2.366025) (layer F.SilkS) (width 0.12))\n  (fp_line (start 2.585786 -1.414214) (end 2.585786 -2.828427) (layer F.SilkS) (width 0.12))\n  (fp_line (start 3 -1.732051) (end 3.366025 -3.098076) (layer F.SilkS) (width 0.12))\n  (fp_line (start 3.482362 -1.931852) (end 4.189469 -3.156597) (layer F.SilkS) (width 0.12))\n  (fp_line (start 4 -2) (end 5 -3) (layer F.SilkS) (width 0.12))\n  (fp_line (start 4.517638 -1.931852) (end 5.742383 -2.638958) (layer F.SilkS) (width 0.12))\n  (fp_line (start 5 -1.732051) (end 6.366025 -2.098076) (layer F.SilkS) (width 0.12))\n  (fp_line (start 5.414214 -1.414214) (end 6.828427 -1.414214) (layer F.SilkS) (width 0.12))\n  (fp_line (start 5.732051 -1) (end 7.098076 -0.633975) (layer F.SilkS) (width 0.12))\n  (fp_line (start 5.931852 -0.517638) (end 7.156597 0.189469) (layer F.SilkS) (width 0.12))\n)\"\"\"\n\nRESULT_rotArc = \"\"\"(module test_rotate (layer F.Cu) (tedit 0)\n  (fp_arc (start 6 1) (end 5.741181 0.034074) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 5.673033 1.483564) (end 5.673033 0.483564) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 5.232051 1.866025) (end 5.49087 0.9001) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 4.707107 2.12132) (end 5.207107 1.255295) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 4.133975 2.232051) (end 4.841081 1.524944) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 3.551712 2.190671) (end 4.417738 1.690671) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 3 2) (end 3.965926 1.741181) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 2.516436 1.673033) (end 3.516436 1.673033) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 2.133975 1.232051) (end 3.0999 1.49087) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 1.87868 0.707107) (end 2.744705 1.207107) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 1.767949 0.133975) (end 2.475056 0.841081) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 1.809329 -0.448288) (end 2.309329 0.417738) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 2 -1) (end 2.258819 -0.034074) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 2.326967 -1.483564) (end 2.326967 -0.483564) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 2.767949 -1.866025) (end 2.50913 -0.9001) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 3.292893 -2.12132) (end 2.792893 -1.255295) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 3.866025 -2.232051) (end 3.158919 -1.524944) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 4.448288 -2.190671) (end 3.582262 -1.690671) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 5 -2) (end 4.034074 -1.741181) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 5.483564 -1.673033) (end 4.483564 -1.673033) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 5.866025 -1.232051) (end 4.9001 -1.49087) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 6.12132 -0.707107) (end 5.255295 -1.207107) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 6.232051 -0.133975) (end 5.524944 -0.841081) (angle 90) (layer F.SilkS) (width 0.12))\n  (fp_arc (start 6.190671 0.448288) (end 5.690671 -0.417738) (angle 90) (layer F.SilkS) (width 0.12))\n)\"\"\"\n\nRESULT_rotCircle = \"\"\"(module test_rotate (layer F.Cu) (tedit 0)\n  (fp_circle (center 6 -1) (end 7 -1) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 5.673033 -0.516436) (end 6.673033 -0.516436) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 5.232051 -0.133975) (end 6.232051 -0.133975) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 4.707107 0.12132) (end 5.707107 0.12132) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 4.133975 0.232051) (end 5.133975 0.232051) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 3.551712 0.190671) (end 4.551712 0.190671) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 3 0) (end 4 0) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 2.516436 -0.326967) (end 3.516436 -0.326967) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 2.133975 -0.767949) (end 3.133975 -0.767949) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 1.87868 -1.292893) (end 2.87868 -1.292893) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 1.767949 -1.866025) (end 2.767949 -1.866025) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 1.809329 -2.448288) (end 2.809329 -2.448288) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 2 -3) (end 3 -3) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 2.326967 -3.483564) (end 3.326967 -3.483564) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 2.767949 -3.866025) (end 3.767949 -3.866025) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 3.292893 -4.12132) (end 4.292893 -4.12132) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 3.866025 -4.232051) (end 4.866025 -4.232051) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 4.448288 -4.190671) (end 5.448288 -4.190671) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 5 -4) (end 6 -4) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 5.483564 -3.673033) (end 6.483564 -3.673033) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 5.866025 -3.232051) (end 6.866025 -3.232051) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 6.12132 -2.707107) (end 7.12132 -2.707107) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 6.232051 -2.133975) (end 7.232051 -2.133975) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 6.190671 -1.551712) (end 7.190671 -1.551712) (layer F.SilkS) (width 0.12))\n)\"\"\"\n\nRESULT_rotPoly = \"\"\"(module test_rotate (layer F.Cu) (tedit 0)\n  (fp_poly (pts (xy -1 0) (xy -1.2 0.5) (xy 0 0) (xy -1.2 -0.5)) (layer F.SilkS) (width 0.12))\n  (fp_poly (pts (xy -0.575833 -3.334679) (xy -1.108846 -3.257884) (xy -0.075833 -2.468653) (xy -0.24282 -3.757884)) (layer F.SilkS) (width 0.12))\n  (fp_poly (pts (xy 2.524167 -4.634679) (xy 2.191154 -5.057884) (xy 2.024167 -3.768653) (xy 3.05718 -4.557884)) (layer F.SilkS) (width 0.12))\n  (fp_poly (pts (xy 5.2 -2.6) (xy 5.4 -3.1) (xy 4.2 -2.6) (xy 5.4 -2.1)) (layer F.SilkS) (width 0.12))\n  (fp_poly (pts (xy 4.775833 0.734679) (xy 5.308846 0.657884) (xy 4.275833 -0.131347) (xy 4.44282 1.157884)) (layer F.SilkS) (width 0.12))\n  (fp_poly (pts (xy 1.675833 2.034679) (xy 2.008846 2.457884) (xy 2.175833 1.168653) (xy 1.14282 1.957884)) (layer F.SilkS) (width 0.12))\n)\"\"\"  # NOQA: E501\n\nRESULT_rotPad = \"\"\"(module test_rotate (layer F.Cu) (tedit 0)\n  (pad 1 smd custom (at 0 0) (size 0.2 0.2) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -1 0) (xy -1.2 0.5) (xy 0 0) (xy -1.2 -0.5)) (width 0))\n    ))\n  (pad 2 smd custom (at 0.175 -0.303109 -60) (size 0.2 0.2) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -1 0) (xy -1.2 0.5) (xy 0 0) (xy -1.2 -0.5)) (width 0))\n    ))\n  (pad 3 smd custom (at 0.525 -0.303109 -120) (size 0.2 0.2) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -1 0) (xy -1.2 0.5) (xy 0 0) (xy -1.2 -0.5)) (width 0))\n    ))\n  (pad 4 smd custom (at 0.7 0 -180) (size 0.2 0.2) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -1 0) (xy -1.2 0.5) (xy 0 0) (xy -1.2 -0.5)) (width 0))\n    ))\n  (pad 5 smd custom (at 0.525 0.303109 -240) (size 0.2 0.2) (layers F.Cu F.Mask F.Paste)\n    (options (clearance outline) (anchor circle))\n    (primitives\n      (gr_poly (pts\n         (xy -1 0) (xy -1.2 0.5) (xy 0 0) (xy -1.2 -0.5)) (width 0))\n    ))\n)\"\"\"\n\n\nclass RotationTests(unittest.TestCase):\n\n    def testTextRotation(self):\n        kicad_mod = Footprint(\"test_rotate\")\n\n        center = Vector2D(0, 0)\n        at = center+Vector2D(2, 0)\n\n        for t in range(0, 360, 45):\n            kicad_mod.append(\n                Text(type=Text.TYPE_USER, text=\"-1\", at=at).rotate(t, origin=center))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        # file_handler.writeFile('test.kicad_mod')\n        self.assertEqual(file_handler.serialize(timestamp=0), RESULT_rotText)\n\n    def testLineRotation(self):\n        kicad_mod = Footprint(\"test_rotate\")\n\n        center = Vector2D(4, 0)\n        start = center + Vector2D(2, 0)\n        end = start + Vector2D(1, 1)\n\n        for t in range(0, 360, 15):\n            kicad_mod.append(\n                Line(start=start, end=end).rotate(t, origin=center))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        # file_handler.writeFile('test.kicad_mod')\n        self.assertEqual(file_handler.serialize(timestamp=0), RESULT_rotLine)\n\n    def testArcRotation(self):\n        kicad_mod = Footprint(\"test_rotate\")\n\n        rot_center = Vector2D(4, 0)\n        mid = rot_center + Vector2D(2, 0)\n        center = rot_center + Vector2D(2, 1)\n        angle = 90\n\n        for t in range(0, 360, 15):\n            kicad_mod.append(\n                Arc(center=center, midpoint=mid, angle=angle)\n                .rotate(angle/3, origin=center)\n                .rotate(t, origin=rot_center))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        # file_handler.writeFile('test.kicad_mod')\n        self.assertEqual(file_handler.serialize(timestamp=0), RESULT_rotArc)\n\n    def testCircleRotation(self):\n        kicad_mod = Footprint(\"test_rotate\")\n\n        rot_center = Vector2D(4, -2)\n        center = rot_center + Vector2D(2, 1)\n        radius = 1\n\n        for t in range(0, 360, 15):\n            kicad_mod.append(\n                Circle(center=center, radius=radius).rotate(t, origin=rot_center))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        # file_handler.writeFile('test.kicad_mod')\n        self.assertEqual(file_handler.serialize(timestamp=0), RESULT_rotCircle)\n\n    def testPolygonRotation(self):\n        kicad_mod = Footprint(\"test_rotate\")\n\n        rot_center = Vector2D(2.1, -1.3)\n\n        nodes = [(-1, 0), (-1.2, 0.5), (0, 0), (-1.2, -0.5)]\n\n        for t in range(0, 360, 60):\n            kicad_mod.append(\n                Polygon(nodes=nodes).rotate(t, origin=rot_center))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        # file_handler.writeFile('test.kicad_mod')\n        self.assertEqual(file_handler.serialize(timestamp=0), RESULT_rotPoly)\n\n    def testPadRotation(self):\n        kicad_mod = Footprint(\"test_rotate\")\n\n        rot_center = Vector2D(0.35, 0)\n        nodes = [(-1, 0), (-1.2, 0.5), (0, 0), (-1.2, -0.5)]\n        prim = Polygon(nodes=nodes)\n        i = 1\n        for t in range(0, 300, 60):\n            kicad_mod.append(\n                Pad(\n                    number=i, type=Pad.TYPE_SMT, shape=Pad.SHAPE_CUSTOM,\n                    at=[0, 0], size=[0.2, 0.2], layers=Pad.LAYERS_SMT,\n                    primitives=[prim]\n                    ).rotate(t, origin=rot_center))\n            i += 1\n\n        file_handler = KicadFileHandler(kicad_mod)\n        file_handler.writeFile('test.kicad_mod')\n        self.assertEqual(file_handler.serialize(timestamp=0), RESULT_rotPad)\n"
  },
  {
    "path": "KicadModTree/tests/moduletests/test_simple_footprints.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport unittest\n\nfrom KicadModTree import *\n\n\nRESULT_MINIMUM = \"\"\"(module test (layer F.Cu) (tedit 0)\n)\"\"\"\n\nRESULT_BASIC_TAGS = \"\"\"(module test (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (attr smd)\n)\"\"\"\n\nRESULT_SIMPLE_FOOTPRINT = \"\"\"(module test (layer F.Cu) (tedit 0)\n  (descr \"A example footprint\")\n  (tags example)\n  (fp_text reference REF** (at 0 -3) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value test (at 1.5 3) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_line (start -2 -2) (end -2 2) (layer F.SilkS) (width 0.12))\n  (fp_line (start -2 2) (end 5 2) (layer F.SilkS) (width 0.12))\n  (fp_line (start 5 2) (end 5 -2) (layer F.SilkS) (width 0.12))\n  (fp_line (start 5 -2) (end -2 -2) (layer F.SilkS) (width 0.12))\n  (fp_line (start -2.25 -2.25) (end -2.25 2.25) (layer F.CrtYd) (width 0.05))\n  (fp_line (start -2.25 2.25) (end 5.25 2.25) (layer F.CrtYd) (width 0.05))\n  (fp_line (start 5.25 2.25) (end 5.25 -2.25) (layer F.CrtYd) (width 0.05))\n  (fp_line (start 5.25 -2.25) (end -2.25 -2.25) (layer F.CrtYd) (width 0.05))\n  (pad 1 thru_hole rect (at 0 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask))\n  (pad 2 thru_hole circle (at 3 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask))\n  (model example.3dshapes/example_footprint.wrl\n    (at (xyz 0 0 0))\n    (scale (xyz 1 1 1))\n    (rotate (xyz 0 0 0))\n  )\n)\"\"\"\n\nRESULT_BASIC_NODES = \"\"\"(module test (layer F.Cu) (tedit 0)\n  (fp_text reference REF** (at 0 -3) (layer F.SilkS)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_text value \"footprint name\" (at 0 3) (layer F.Fab)\n    (effects (font (size 1 1) (thickness 0.15)))\n  )\n  (fp_arc (start 0 0) (end -1 0) (angle 180) (layer F.SilkS) (width 0.12))\n  (fp_circle (center 0 0) (end 1.5 0) (layer F.SilkS) (width 0.12))\n  (fp_line (start 1 0) (end -1 0) (layer F.SilkS) (width 0.12))\n  (pad 1 thru_hole rect (at 0 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask))\n  (model example.3dshapes/example_footprint.wrl\n    (at (xyz 0 0 0))\n    (scale (xyz 1 1 1))\n    (rotate (xyz 0 0 0))\n  )\n)\"\"\"\n\n\nclass SimpleFootprintTests(unittest.TestCase):\n\n    def testMinimum(self):\n        kicad_mod = Footprint(\"test\")\n\n        file_handler = KicadFileHandler(kicad_mod)\n        self.assertEqual(file_handler.serialize(timestamp=0), RESULT_MINIMUM)\n\n    def testBasicTags(self):\n        kicad_mod = Footprint(\"test\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n        kicad_mod.setAttribute(\"smd\")\n\n        file_handler = KicadFileHandler(kicad_mod)\n        self.assertEqual(file_handler.serialize(timestamp=0), RESULT_BASIC_TAGS)\n\n    def testSampleFootprint(self):\n        kicad_mod = Footprint(\"test\")\n\n        kicad_mod.setDescription(\"A example footprint\")\n        kicad_mod.setTags(\"example\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, -3], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"test\", at=[1.5, 3], layer='F.Fab'))\n        kicad_mod.append(RectLine(start=[-2, -2], end=[5, 2], layer='F.SilkS'))\n        kicad_mod.append(RectLine(start=[-2.25, -2.25], end=[5.25, 2.25], layer='F.CrtYd'))\n        kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n                             at=[0, 0], size=[2, 2], drill=1.2, layers=Pad.LAYERS_THT))\n        kicad_mod.append(Pad(number=2, type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n                             at=[3, 0], size=[2, 2], drill=1.2, layers=Pad.LAYERS_THT))\n        kicad_mod.append(Model(filename=\"example.3dshapes/example_footprint.wrl\",\n                               at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        self.assertEqual(file_handler.serialize(timestamp=0), RESULT_SIMPLE_FOOTPRINT)\n\n    def testBasicNodes(self):\n        kicad_mod = Footprint(\"test\")\n\n        kicad_mod.append(Text(type='reference', text='REF**', at=[0, -3], layer='F.SilkS'))\n        kicad_mod.append(Text(type='value', text=\"footprint name\", at=[0, 3], layer='F.Fab'))\n\n        kicad_mod.append(Arc(center=[0, 0], start=[-1, 0], angle=180, layer='F.SilkS'))\n        kicad_mod.append(Circle(center=[0, 0], radius=1.5, layer='F.SilkS'))\n        kicad_mod.append(Line(start=[1, 0], end=[-1, 0], layer='F.SilkS'))\n        kicad_mod.append(Model(filename=\"example.3dshapes/example_footprint.wrl\",\n                               at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n        kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n                             at=[0, 0], size=[2, 2], drill=1.2, layers=Pad.LAYERS_THT))\n\n        file_handler = KicadFileHandler(kicad_mod)\n        self.assertEqual(file_handler.serialize(timestamp=0), RESULT_BASIC_NODES)\n"
  },
  {
    "path": "KicadModTree/tests/nodes/__init__.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nfrom .test_Node import NodeTests\n"
  },
  {
    "path": "KicadModTree/tests/nodes/test_Node.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport unittest\n\nfrom KicadModTree.nodes.Node import *\n\n\nclass TestChildNode(Node):\n    def __init__(self):\n        Node.__init__(self)\n\n\nclass NodeTests(unittest.TestCase):\n\n    def testInit(self):\n        node = Node()\n        self.assertIs(node.getParent(), None)\n        self.assertIs(node.getRootNode(), node)\n        self.assertEqual(len(node.getNormalChilds()), 0)\n        self.assertEqual(len(node.getVirtualChilds()), 0)\n        self.assertEqual(len(node.getAllChilds()), 0)\n\n    def testAppend(self):\n        node = Node()\n        self.assertEqual(len(node.getNormalChilds()), 0)\n\n        childNode1 = Node()\n        node.append(childNode1)\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 1)\n\n        childNode2 = Node()\n        node.append(childNode2)\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 2)\n\n        with self.assertRaises(TypeError):\n            node.append(None)\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 2)\n\n        with self.assertRaises(TypeError):\n            node.append(object)\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 2)\n\n        with self.assertRaises(TypeError):\n            node.append(\"a string is not a node object\")\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 2)\n\n        with self.assertRaises(MultipleParentsError):\n            node.append(childNode1)\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 2)\n\n        childNode3 = TestChildNode()\n        node.append(childNode3)\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertIn(childNode3, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(childNode3.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 3)\n\n    def testExtend(self):\n        node = Node()\n        self.assertEqual(len(node.getNormalChilds()), 0)\n\n        childNode1 = Node()\n        childNode2 = Node()\n        node.extend([childNode1, childNode2])\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 2)\n\n        childNode3 = Node()\n        node.extend([childNode3])\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertIn(childNode3, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(childNode3.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 3)\n\n        node.extend([])\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertIn(childNode3, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(childNode3.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 3)\n\n        with self.assertRaises(TypeError):\n            node.extend([None])\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertIn(childNode3, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(childNode3.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 3)\n\n        with self.assertRaises(TypeError):\n            node.append([object])\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertIn(childNode3, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(childNode3.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 3)\n\n        with self.assertRaises(TypeError):\n            node.append([\"a string is not a node object\"])\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertIn(childNode3, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(childNode3.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 3)\n\n        with self.assertRaises(MultipleParentsError):\n            node.extend([childNode1])\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertIn(childNode3, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(childNode3.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 3)\n\n        childNode4 = Node()\n        childNode5 = Node()\n        with self.assertRaises(MultipleParentsError):\n            node.extend([childNode4, childNode5, childNode5])\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertIn(childNode3, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(childNode3.getParent(), node)\n        self.assertEqual(childNode4.getParent(), None)\n        self.assertEqual(childNode5.getParent(), None)\n        self.assertEqual(len(node.getNormalChilds()), 3)\n\n    def testRemove(self):\n        node = Node()\n        self.assertEqual(len(node.getNormalChilds()), 0)\n\n        childNode1 = Node()\n        childNode2 = Node()\n        node.extend([childNode1, childNode2])\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 2)\n\n        node.remove(childNode1)\n        self.assertNotIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), None)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 1)\n\n        node.remove(childNode1)\n        self.assertNotIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), None)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 1)\n\n        with self.assertRaises(TypeError):\n            node.remove([None])\n        self.assertNotIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), None)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 1)\n\n        with self.assertRaises(TypeError):\n            node.remove([object])\n        self.assertNotIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), None)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 1)\n\n        with self.assertRaises(TypeError):\n            node.remove([\"a string is not a node object\"])\n        self.assertNotIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), None)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 1)\n\n    def testInsert(self):\n        node = Node()\n        self.assertEqual(len(node.getNormalChilds()), 0)\n\n        childNode1 = Node()\n        node.insert(childNode1)\n        self.assertIn(childNode1, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 1)\n\n        childNode2 = Node()\n        node.insert(childNode2)\n        self.assertIn(childNode1, childNode2.getNormalChilds())\n        self.assertNotIn(childNode1, node.getNormalChilds())\n        self.assertIn(childNode2, node.getNormalChilds())\n        self.assertEqual(childNode1.getParent(), childNode2)\n        self.assertEqual(childNode2.getParent(), node)\n        self.assertEqual(len(node.getNormalChilds()), 1)\n        self.assertEqual(len(childNode1.getNormalChilds()), 0)\n        self.assertEqual(len(childNode2.getNormalChilds()), 1)\n\n    def testInsertWithManyChilds(self):\n        node = Node()\n        self.assertEqual(len(node.getNormalChilds()), 0)\n\n        for i in range(0, 200):\n            node.append(Node())\n\n        insertNode = Node()\n        self.assertEqual(len(node.getNormalChilds()), 200)\n        self.assertEqual(len(insertNode.getNormalChilds()), 0)\n        node.insert(insertNode)\n        self.assertEqual(len(node.getNormalChilds()), 1)\n        self.assertEqual(len(insertNode.getNormalChilds()), 200)\n"
  },
  {
    "path": "KicadModTree/tests/test.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016-2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport os\nimport sys\nimport unittest\n\nsys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), \"../../\"))\n\nfrom nodes import *  # NOQA\nfrom datatypes import *  # NOQA\nfrom moduletests import *  # NOQA\n\n\ndef run_tests():\n    unittest.main()\n\nif __name__ == '__main__':\n    run_tests()\n"
  },
  {
    "path": "KicadModTree/util/__init__.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n"
  },
  {
    "path": "KicadModTree/util/geometric_util.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016-2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport math\nfrom KicadModTree.Vector import *\nimport copy\n\n\nclass geometricLine():\n    r\"\"\" Handle the geometric side of lines\n\n    :params:\n        * *start* (``Vector2D``) --\n          start point of the line\n        * *end* (``Vector2D``) --\n          end point of the line\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        if 'geometry' in kwargs:\n            geometry = kwargs['geometry']\n            self.start_pos = Vector2D(geometry.start_pos)\n            self.end_pos = Vector2D(geometry.end_pos)\n        else:\n            self.start_pos = Vector2D(kwargs['start'])\n            self.end_pos = Vector2D(kwargs['end'])\n\n    def copy(self):\n        return geometricLine(geometry=self)\n\n    def rotate(self, angle, origin=(0, 0), use_degrees=True):\n        r\"\"\" Rotate around given origin\n\n        :params:\n            * *angle* (``float``)\n                rotation angle\n            * *origin* (``Vector2D``)\n                origin point for the rotation. default: (0, 0)\n            * *use_degrees* (``boolean``)\n                rotation angle is given in degrees. default:True\n        \"\"\"\n\n        self.start_pos.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        self.end_pos.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        return self\n\n    def translate(self, distance_vector):\n        r\"\"\" Translate\n\n        :params:\n            * *distance_vector* (``Vector2D``)\n                2D vector defining by how much and in what direction to translate.\n        \"\"\"\n\n        self.start_pos += distance_vector\n        self.end_pos += distance_vector\n        return self\n\n    def isPointOnSelf(self, point, tolerance=1e-7):\n        r\"\"\" is the given point on this line\n\n        :params:\n            * *point* (``Vector2D``)\n                The point to be checked\n            * *tolerance* (``float``)\n                tolerance used to determine if the point is on the element\n                default: 1e-7\n        \"\"\"\n\n        ll, la = (self.end_pos - self.start_pos).to_polar()\n        pl, pa = (point - self.start_pos).to_polar()\n        return abs(la - pa) < tolerance and pl <= ll\n\n    def sortPointsRelativeToStart(self, points):\n        r\"\"\" sort given points releative to start point\n\n        :params:\n            * *points* (``[Vector2D]``)\n                itterable of points\n        \"\"\"\n\n        if len(points) < 2:\n            return points\n\n        if len(points) > 2:\n            raise NotImplementedError(\"Sorting for more than 2 points not supported\")\n\n        if self.start_pos.distance_to(points[0]) < self.start_pos.distance_to(points[1]):\n            return points\n        else:\n            return [points[1], points[0]]\n\n    def cut(self, *other):\n        r\"\"\" cut line with given other element\n\n        :params:\n            * *other* (``Line``, ``Circle``, ``Arc``)\n                cut the element on any intersection with the given geometric element\n        \"\"\"\n        ip = BaseNodeIntersection.intersectTwoNodes(self, *other)\n        cp = []\n        for p in ip:\n            if self.isPointOnSelf(p):\n                cp.append(p)\n\n        sp = self.sortPointsRelativeToStart(cp)\n        sp.insert(0, self.start_pos)\n        sp.append(self.end_pos)\n\n        r = []\n        for i in range(len(sp)-1):\n            r.append(geometricLine(start=sp[i], end=sp[i+1]))\n\n        return r\n\n    def to_homogeneous(self):\n        r\"\"\" Get homogeneous representation of the line\n        \"\"\"\n        p1 = self.start_pos.to_homogeneous()\n        p2 = self.end_pos.to_homogeneous()\n        return p1.cross_product(p2)\n\n    def __iter__(self):\n        yield self.start_pos\n        yield self.end_pos\n\n    def __len__(self):\n        return 2\n\n    def __getitem__(self, key):\n        if key == 0 or key == 'start':\n            return self.start_pos\n        if key == 1 or key == 'end':\n            return self.end_pos\n\n        raise IndexError('Index {} is out of range'.format(key))\n\n    def __setitem__(self, key, item):\n        if key == 0 or key == 'start':\n            self.start_pos = item\n        elif key == 1 or key == 'end':\n            self.end_pos = item\n        else:\n            raise IndexError('Index {} is out of range'.format(key))\n\n\nclass geometricCircle():\n    r\"\"\"Handle the geometric side of circles\n\n    :params:\n        * *center* (``Vector2D``) --\n          center of the circle\n        * *radius* (``float``) --\n          radius of the circle\n    \"\"\"\n\n    def __init__(self, center, radius):\n        self.center_pos = Vector2D(center)\n        self.radius = float(radius)\n\n    def getRadius(self):\n        return self.radius\n\n    def rotate(self, angle, origin=(0, 0), use_degrees=True):\n        r\"\"\" Rotate around given origin\n\n        :params:\n            * *angle* (``float``)\n                rotation angle\n            * *origin* (``Vector2D``)\n                origin point for the rotation. default: (0, 0)\n            * *use_degrees* (``boolean``)\n                rotation angle is given in degrees. default:True\n        \"\"\"\n\n        self.center_pos.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        return self\n\n    def translate(self, distance_vector):\n        r\"\"\" Translate\n\n        :params:\n            * *distance_vector* (``Vector2D``)\n                2D vector defining by how much and in what direction to translate.\n        \"\"\"\n\n        self.center_pos += distance_vector\n        return self\n\n    def isPointOnSelf(self, point, tolerance=1e-7):\n        r\"\"\" is the given point on this circle\n\n        :params:\n            * *point* (``Vector2D``)\n                The point to be checked\n            * *tolerance* (``float``)\n                tolerance used to determine if the point is on the element\n                default: 1e-7\n        \"\"\"\n\n        rad_p, ang_p = Vector2D(point).to_polar(origin=self.center_pos)\n        return abs(self.radius - rad_p) < tolerance\n\n    def sortPointsRelativeToStart(self, points):\n        r\"\"\" sort given points releative to start point\n\n        :params:\n            * *points* (``[Vector2D]``)\n                itterable of points\n        \"\"\"\n\n        pass\n\n    def cut(self, *other):\n        r\"\"\" cut line with given other element\n\n        :params:\n            * *other* (``Line``, ``Circle``, ``Arc``)\n                cut the element on any intersection with the given geometric element\n        \"\"\"\n        raise NotImplemented(\"cut for circles not yet implemented\")\n        # re use arc implementation with angle set to 360 deg\n        # and start point set to 0 deg (polar)\n\n    def __iter__(self):\n        yield self.center_pos\n\n    def __len__(self):\n        return 1\n\n    def __getitem__(self, key):\n        if key == 0 or key == 'center':\n            return self.center_pos\n\n        raise IndexError('Index {} is out of range'.format(key))\n\n    def __setitem__(self, key, item):\n        if key == 0 or key == 'center':\n            self.center_pos = item\n        else:\n            raise IndexError('Index {} is out of range'.format(key))\n\n\nclass geometricArc():\n    r\"\"\" Handle the geometric side of arcs\n\n    :params:\n        * *center* (``Vector2D``) --\n          center of arc\n        * *start* (``Vector2D``) --\n          start point of arc\n        * *midpoint* (``Vector2D``) --\n          alternative to start point\n          point is on arc and defines point of equal distance to both arc ends\n          arcs of this form are given as midpoint, center plus angle\n        * *end* (``Vector2D``) --\n          alternative to angle\n          arcs of this form are given as start, end and center\n        * *angle* (``float``) --\n          angle of arc\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        if 'geometry' in kwargs:\n            geometry = kwargs['geometry']\n            self.center_pos = Vector2D(geometry.center_pos)\n            self.start_pos = Vector2D(geometry.start_pos)\n            self.angle = float(geometry.angle)\n        elif 'center' in kwargs:\n            if 'angle' in kwargs:\n                self._initFromCenterAndAngle(**kwargs)\n            elif 'end' in kwargs:\n                self._initFromCenterAndEnd(**kwargs)\n            else:\n                raise KeyError('Arcs defined with center point must define either an angle or endpoint')\n        else:\n            raise NotImplementedError('3 point arcs are not implemented, center is always required.')\n\n    @staticmethod\n    def normalizeAngle(angle):\n        a = angle % (2*360)\n        if a > 360:\n            a -= 2*360\n        return a\n\n    def _initAngle(self, angle):\n        self.angle = geometricArc.normalizeAngle(angle)\n\n    def _initFromCenterAndAngle(self, **kwargs):\n        self.center_pos = Vector2D(kwargs['center'])\n        self._initAngle(kwargs['angle'])\n\n        if 'start' in kwargs:\n            self.start_pos = Vector2D(kwargs['start'])\n        elif 'midpoint' in kwargs:\n            mp_r, mp_a = Vector2D(kwargs['midpoint']).to_polar(\n                origin=self.center_pos, use_degrees=True)\n\n            self.start_pos = Vector2D.from_polar(\n                radius=mp_r, angle=mp_a-self.angle/2,\n                origin=self.center_pos, use_degrees=True)\n        else:\n            raise KeyError('Arcs defined with center and angle must either define the start or midpoint.')\n\n    def _initFromCenterAndEnd(self, **kwargs):\n        self.center_pos = Vector2D(kwargs['center'])\n        if 'start' in kwargs:\n            self.start_pos = Vector2D(kwargs['start'])\n            sp_r, sp_a = self.start_pos.to_polar(\n                origin=self.center_pos, use_degrees=True)\n            ep_r, ep_a = Vector2D(kwargs['end']).to_polar(\n                origin=self.center_pos, use_degrees=True)\n\n            if abs(sp_r - ep_r) > 1e-7:\n                warnings.warn(\n                    \"\"\"Start and end point are not an same arc.\n                    Extended line from center to end point used to determine angle.\"\"\"\n                )\n            self._initAngle(ep_a - sp_a)\n\n            if kwargs.get('long_way', False):\n                if abs(self.angle) < 180:\n                    self.angle = -math.copysign((360-abs(self.angle)), self.angle)\n                if self.angle == -180:\n                    self.angle = 180\n            else:\n                if abs(self.angle) > 180:\n                    self.angle = -math.copysign((abs(self.angle) - 360), self.angle)\n                if self.angle == 180:\n                    self.angle = -180\n        else:\n            raise KeyError('Arcs defined with center and endpoint must define the start point.')\n\n    def rotate(self, angle, origin=(0, 0), use_degrees=True):\n        r\"\"\" Rotate around given origin\n\n        :params:\n            * *angle* (``float``)\n                rotation angle\n            * *origin* (``Vector2D``)\n                origin point for the rotation. default: (0, 0)\n            * *use_degrees* (``boolean``)\n                rotation angle is given in degrees. default:True\n        \"\"\"\n\n        self.center_pos.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        self.start_pos.rotate(angle=angle, origin=origin, use_degrees=use_degrees)\n        return self\n\n    def translate(self, distance_vector):\n        r\"\"\" Translate\n\n        :params:\n            * *distance_vector* (``Vector2D``)\n                2D vector defining by how much and in what direction to translate.\n        \"\"\"\n\n        self.center_pos += distance_vector\n        self.start_pos += distance_vector\n        return self\n\n    def getRadius(self):\n        r, a = (self.start_pos - self.center_pos).to_polar()\n        return r\n\n    def getStartPoint(self):\n        return Vector2D(self.start_pos)\n\n    def getMidPoint(self):\n        return Vector2D(self.start_pos).rotate(self.angle/2, origin=self.center_pos)\n\n    def getEndPoint(self):\n        return Vector2D(self.start_pos).rotate(self.angle, origin=self.center_pos)\n\n    def setRadius(self, radius):\n        rad_s, ang_s = self.start_pos.to_polar(origin=self.center_pos)\n        self.start_pos = Vector2D.from_polar(radius=radius, angle=ang_s, origin=self.center_pos)\n        return self\n\n    def _calulateEndPos(self):\n        radius, angle = self.start_pos.to_polar(\n            origin=self.center_pos, use_degrees=True)\n\n        return Vector2D.from_polar(\n            radius=radius, angle=angle+self.angle,\n            origin=self.center_pos, use_degrees=True)\n\n    def _toLocalCoordinates(self, point):\n        rad_s, ang_s = self.start_pos.to_polar(origin=self.center_pos)\n        rad_p, ang_p = Vector2D(point).to_polar(origin=self.center_pos)\n\n        ang_p_s = (ang_p - ang_s) % 360\n        if self.angle < 0:\n            ang_p_s -= 360\n        return (rad_p, ang_p_s)\n\n    def _compareAngles(self, a1, a2, tolerance=1e-7):\n        r\"\"\" compare which of the two angles given in the local coordinate system\n\n        :params:\n            * *a1* (``float``)\n                angle 1\n            * *a2* (``float``)\n                angle 2\n            * *tolerance* (``float``)\n                tolerance used to determine if the point is on the element\n                default: 1e-7\n\n        :return:\n            * -1: angle 1 is closer to start\n            *  0: both are of equal distance\n            *  1: angle 2 is closer to start\n        \"\"\"\n\n        if abs(a1-a2) < tolerance:\n            return 0\n\n        if self.angle < 0:\n            if a1 < a2:\n                return 1\n        else:\n            if a1 > a2:\n                return 1\n        return -1\n\n    def isPointOnSelf(self, point, tolerance=1e-7):\n        r\"\"\" is the given point on this arc\n\n        :params:\n            * *point* (``Vector2D``)\n                The point to be checked\n            * *tolerance* (``float``)\n                tolerance used to determine if the point is on the element\n                default: 1e-7\n        \"\"\"\n\n        rad_p, ang_p_s = self._toLocalCoordinates(point)\n        rad_s, ang_s = self.start_pos.to_polar(origin=self.center_pos)\n\n        # rotate to local coordinate system (start point is at 0 degree)\n        ang_e_s = self.angle\n\n        return self._compareAngles(ang_p_s, ang_e_s) == -1 and abs(rad_s - rad_p) < tolerance\n\n    def sortPointsRelativeToStart(self, points):\n        r\"\"\" sort given points releative to start point\n\n        :params:\n            * *points* (``[Vector2D]``)\n                itterable of points\n        \"\"\"\n\n        if len(points) > 2:\n            raise NotImplementedError(\"Sorting for more than 2 points not supported\")\n\n        ps = []\n        for p in points:\n            ps.append(self._toLocalCoordinates(p))\n\n        if len(points) < 2:\n            return ps\n\n        if self._compareAngles(ps[0][1], ps[1][1]) == 1:\n            return [ps[1], ps[0]]\n        else:\n            return ps\n\n    def cut(self, *other):\n        r\"\"\" cut line with given other element\n\n        :params:\n            * *other* (``Line``, ``Circle``, ``Arc``)\n                cut the element on any intersection with the given geometric element\n        \"\"\"\n\n        ip = BaseNodeIntersection.intersectTwoNodes(self, *other)\n        cp = []\n        for p in ip:\n            if self.isPointOnSelf(p):\n                cp.append(p)\n\n        sp = self.sortPointsRelativeToStart(cp)\n        sp.insert(0, (self.getRadius(), 0))\n        sp.append(self._toLocalCoordinates(self._calulateEndPos()))\n\n        r = []\n        for i in range(len(sp)-1):\n            r.append(geometricArc(\n                center=self.center_pos,\n                start=Vector2D(self.start_pos).rotate(sp[i][1], origin=self.center_pos),\n                angle=sp[i+1][1]-sp[i][1]\n                ))\n\n        return r\n\n    def __iter__(self):\n        yield self.center_pos\n        yield self.start_pos\n\n    def __len__(self):\n        return 2\n\n    def __getitem__(self, key):\n        if key == 0 or key == 'center':\n            return self.center_pos\n        if key == 1 or key == 'start':\n            return self.start_pos\n\n        raise IndexError('Index {} is out of range'.format(key))\n\n    def __setitem__(self, key, item):\n        if key == 0 or key == 'center':\n            self.center_pos = item\n        if key == 1 or key == 'start':\n            return self.start_pos\n        else:\n            raise IndexError('Index {} is out of range'.format(key))\n\n\nclass BaseNodeIntersection():\n    @staticmethod\n    def intersectTwoNodes(*nodes):\n        import KicadModTree.nodes.base.Line\n        if len(nodes) < 2 or len(nodes) > 3:\n            raise KeyError(\"intersectTwoNodes expects two node objects or a node and two vectors\")\n\n        circles = []\n        lines = []\n        vectors = []\n\n        for n in nodes:\n            if hasattr(n, 'getRadius') and hasattr(n, 'center_pos'):\n                circles.append(n)\n            elif hasattr(n, 'end_pos') and hasattr(n, 'start_pos'):\n                lines.append(n)\n            else:\n                vectors.append(n)\n\n        if len(vectors) == 2:\n            lines.append(Line(start=vectors[0], end=vectors[1]))\n\n        if len(lines) == 2:\n            return BaseNodeIntersection.intersectTwoLines(*lines)\n        if len(circles) == 2:\n            raise NotImplementedError('intersection between circles is not supported')\n        if len(lines) == 1 and len(circles) == 1:\n            return BaseNodeIntersection.intersectLineWithCircle(lines[0], circles[0])\n\n        print(lines)\n        print(circles)\n        raise NotImplementedError('unsupported combination of parameter types')\n\n    @staticmethod\n    def intersectTwoLines(line1, line2):\n        # we use homogeneous coordinates here.\n        l1 = line1.to_homogeneous()\n        l2 = line2.to_homogeneous()\n\n        ip = l1.cross_product(l2)\n        if ip.z == 0:\n            return []\n\n        return [Vector2D.from_homogeneous(ip)]\n\n    @staticmethod\n    def intersectLineWithCircle(line, circle):\n        # from http://mathworld.wolfram.com/Circle-LineIntersection.html\n        # Equations are for circle center on (0, 0) so we translate everything\n        # to the origin (well the line anyways as we do only need the radius of the circle)\n        lt = line.copy().translate(-circle.center_pos)\n\n        d = lt.end_pos - lt.start_pos\n        dr = math.hypot(d.x, d.y)\n        D = lt.start_pos.x*lt.end_pos.y - lt.end_pos.x*lt.start_pos.y\n\n        discriminant = circle.getRadius()**2 * dr**2 - D**2\n        intersection = []\n        if discriminant < 0:\n            return intersection\n\n        def calcPoint(x):\n            return Vector2D({\n                'x': (D*d.y + x*math.copysign(1, d.y)*d.x*math.sqrt(discriminant))/dr**2,\n                'y': (-D*d.x + x*abs(d.y)*math.sqrt(discriminant))/dr**2\n                }) + circle.center_pos\n\n        intersection.append(calcPoint(1))\n        if discriminant == 0:\n            return intersection\n\n        intersection.append(calcPoint(-1))\n        return intersection\n"
  },
  {
    "path": "KicadModTree/util/kicad_util.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016-2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport time\nimport re\n\n\ndef formatFloat(val):\n    '''\n    return well formated float\n    '''\n    result = ('%f' % val).rstrip('0').rstrip('.')\n    if result == '-0':\n        result = '0'\n    return result\n\n\ndef lispString(string):\n    '''\n    add quotation marks to string, when it include a white space or is empty\n    '''\n    if type(string) is not str:\n        string = str(string)\n\n    if len(string) == 0 or re.match(\".*\\s.*\", string):\n        return '\"{}\"'.format(string.replace('\"', '\\\\\"'))  # escape text\n\n    return string\n\n\ndef lispTokenizer(input):\n    '''\n    Convert a string of characters into a list of tokens.\n    '''\n    input = input.replace('(', ' ( ').replace(')', ' ) ')\n\n    # split input, including whitespaces\n    base_tokens = re.split(r'(\\s+)', input)\n\n    tokens = []\n    in_string = False\n\n    for token in base_tokens:\n        if not in_string and token.isspace():\n            continue\n\n        if len(token) == 0:\n            continue\n\n        if token[0] == '\"':\n            if in_string:\n                tokens[-1] += token[1:]\n                in_string = False\n            else:\n                tokens.append(token[1:])\n                in_string = True\n\n        elif token[-1] == '\"':\n            if in_string:\n                tokens[-1] += token[:-1]\n                in_string = False\n            else:\n                tokens.append(token[:-1])\n                in_string = True\n\n        else:\n            if in_string:\n                tokens[-1] += token\n            else:\n                tokens.append(token)\n\n    if in_string:\n        raise RuntimeError(\"missing closing quotation mark\")\n\n    # TOOD: remove invalid spaces from quotation (when having brackets inside)\n\n    return tokens\n\n\ndef parseLispString(input):\n    syntax_tree = []\n    current_node = syntax_tree\n    scope = [syntax_tree]\n\n    for token in lispTokenizer(input):\n        if token == \"(\":\n            scope.append([])\n            current_node.append(scope[-1])\n            current_node = scope[-1]\n\n        elif token == \")\":\n            if len(scope) <= 1:\n                raise RuntimeError(\"missing opening brackets\")\n\n            scope.pop()\n            current_node = scope[-1]\n\n        else:\n            current_node.append(token)\n\n    if len(scope) > 1:\n        raise RuntimeError(\"missing closing brackets\")\n\n    if len(syntax_tree) == 1:\n        syntax_tree = syntax_tree[0]\n\n    return syntax_tree\n\n\nclass SexprSerializer(object):\n    '''\n    Converts a nested python list into a sexpr syntax which can be parsed by KiCad\n    '''\n\n    NEW_LINE = object\n\n    def __init__(self, sexpr):\n        '''\n        :param sexpr: A list of lists and primitive values representing the file\n        '''\n        self.sexpr = sexpr\n\n    def primitive_to_string(self, primitive):\n        pType = type(primitive)\n        if pType is int:\n            return str(primitive)\n        elif pType is float:\n            return formatFloat(primitive)\n        elif pType is str:\n            return lispString(primitive)\n        else:\n            raise RuntimeError(\"unexpected type: {}\".format(pType))\n\n    def sexpr_to_string(self, sexpr, prefix=None):\n        if prefix is None:\n            prefix = \"\"\n\n        serial_string = \"(\"\n\n        # see: https://stackoverflow.com/questions/3190706/nonlocal-keyword-in-python-2-x\n        loop_ctrl = {'first': True, 'indentation': False}\n\n        def get_separator():\n            if loop_ctrl['first']:\n                loop_ctrl['first'] = False\n                return_str = \"\"\n            else:\n                return_str = \" \"\n\n            if loop_ctrl['indentation']:\n                return_str += \" \"\n                loop_ctrl['indentation'] = False\n\n            return return_str\n\n        for attr in sexpr:\n            if isinstance(attr, (tuple, list)):\n                return_string = self.sexpr_to_string(attr, prefix + \" \")\n\n                if loop_ctrl['indentation']:\n                    return_string = return_string.replace('\\n', '\\n ')\n                serial_string += get_separator()\n\n                serial_string += return_string\n            elif attr == SexprSerializer.NEW_LINE:\n                serial_string += \"\\n\"\n                serial_string += prefix\n                loop_ctrl['indentation'] = True\n            else:\n                serial_string += get_separator()\n                serial_string += self.primitive_to_string(attr)\n\n        serial_string += \")\"\n        return serial_string\n\n    def __str__(self):\n        '''\n        :return: A string which respresents the sexpr\n        '''\n        return self.sexpr_to_string(self.sexpr)\n\n\ndef parseTimestamp(timestamp):\n    raise NotImplemented()\n    return time.time()  # TOOD\n\n\ndef formatTimestamp(timestamp=None):\n    if timestamp is None:\n        timestamp = time.time()\n\n    return \"{timestamp:X}\".format(timestamp=int(timestamp))\n"
  },
  {
    "path": "KicadModTree/util/paramUtil.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016-2018 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n# (C) 2018 by Rene Poeschl, github @poeschlr\n\n\nfrom KicadModTree.Vector import *\n\n\ndef toNumberArray(value, length=2, min_value=1, member_type=int):\n    r\"\"\" Convert value into an array of given type with given length\n\n    :param value:\n        Possible input types:\n          * numnber (int or float) -> returns array filled with copies of value\n          * dict -> arreay created with values for keys 'x', 'y', 'z'.\n            dict only supported for len 2 and 3\n          * list or tuple -> truncated to length\n          * Vector -> truncated to lenght\n\n    :param length: (``int``) -- default: 2\n        Defines the length of the resulting array\n\n    :min_value: (``int``) -- default: 1\n        Defines the minimum alowed value (raise value error if too low)\n        None -> No check\n\n    :param mamber_type: (``type``) -- default: <type: int>\n        all members of the array will be converted to this type\n    \"\"\"\n    if type(value) in [int, float]:\n        result = [value for i in range(length)]\n    elif type(value) is dict:\n        if length in [2, 3]:\n            KEYS = ['x', 'y', 'z']\n            result = [value[KEYS[i]] for i in range(length)]\n        else:\n            raise TypeError('Dict only supported for length 2 or 3.')\n    elif type(value) in [list, tuple]:\n        if len(value) >= length:\n            result = value[:length]\n    elif type(value) in [Vector2D, Vector3D]:\n        if len(value) < length:\n            raise TypeError(\n                'Vector dimensions ({}) are too low. Must be at least {}'.format(len(value), length))\n        result = list(value)\n    else:\n        raise TypeError('Unsupported type: {}'.format(type(value)))\n\n    result = [member_type(v) for v in result]\n\n    if min_value is not None and isAnyLarger(result, min_value, False):\n        raise ValueError(\n            \"At least one value in ({}) too small. Linit is {}.\".format(result, min_value))\n\n    return result\n\n\ndef toIntArray(value, length=2, min_value=1):\n    r\"\"\" Convert value into an array of ints of given length\n\n    :param value:\n        Possible input types:\n          * numnber (int or float) -> returns array filled with copies of value\n          * dict -> arreay created with values for keys 'x', 'y', 'z'.\n            dict only supported for len 2 and 3\n          * list or tuple -> truncated to length\n          * Vector -> truncated to lenght\n\n    :param length: (``int``) -- default: 2\n        Defines the length of the resulting array\n\n    :min_value: (``int``) -- default: 1\n        Defines the minimum alowed value (raise value error if too low)\n        None -> No check\n    \"\"\"\n    return toNumberArray(value, length, min_value, member_type=int)\n\n\ndef toFloatArray(value, length=2, min_value=1):\n    r\"\"\" Convert value into an array of floats of given length\n\n    :param value:\n        Possible input types:\n          * numnber (int or float) -> returns array filled with copies of value\n          * dict -> arreay created with values for keys 'x', 'y', 'z'.\n            dict only supported for len 2 and 3\n          * list or tuple -> truncated to length\n          * Vector -> truncated to lenght\n\n    :param length: (``int``) -- default: 2\n        Defines the length of the resulting array\n\n    :min_value: (``int``) -- default: 1\n        Defines the minimum alowed value (raise value error if too low)\n        None -> No check\n    \"\"\"\n    return toNumberArray(value, length, min_value, member_type=float)\n\n\ndef isAnyLarger(values, low_limits, must_be_larger=False):\n    r\"\"\"Check if any value in the source array is larger than its respective limit\n\n    :param value: (``itterable``) --\n        The values to check.\n\n    :param low_limit: (``int``)\n        Defines the minimum alowed value (raise value error if too low)\n        None -> No check\n\n    :param must_be_larger: (``bool``) -- default: True\n       Defines if the number must be larger than the limit or if the limit is\n       the minimum value.\n    \"\"\"\n    limits = toFloatArray(low_limits, len(values), min_value=None)\n    for v, l in zip(values, limits):\n        if v < l or (v <= l and must_be_larger):\n            return True\n    return False\n\n\ndef toVectorUseCopyIfNumber(value, length=2, low_limit=None, must_be_larger=True):\n    r\"\"\" Convert value into an vector of given dimension\n\n    :param value:\n        The value to convert.\n        Supported types are all types allowed for vector constructor plus int/float.\n        If int/float vector will be initialized with the correct number of copies.\n\n    :param length: (2 or 3) -- default: 2\n        Defines the dimension of the resulting vector\n\n    :param low_limit: (``int``) -- default: None\n        Defines the minimum alowed value (raise value error if too low)\n        None -> No check\n\n    :param must_be_larger: (``bool``) -- default: True\n       Defines if the number must be larger than the limit or if the limit is\n       the minimum value.\n    \"\"\"\n\n    if type(value) in [int, float]:\n        result = [value for i in range(length)]\n    else:\n        result = value\n\n    if length == 2:\n        result = Vector2D(result)\n    elif length == 3:\n        result = Vector3D(result)\n    else:\n        raise ValueError(\"length must be 2 or 3\")\n\n    if low_limit is not None and isAnyLarger(result, low_limit, must_be_larger):\n        raise ValueError(\"One value in ({}) too small. Limit is {}.\".format(result, low_limit))\n\n    return result\n\n\ndef getOptionalNumberTypeParam(\n        kwargs, param_name, default_value=None,\n        low_limit=None, high_limit=None, allow_equal_limit=True):\n    r\"\"\" Get a named parameter from packed dict and guarantee it is a number (float or int)\n\n    :param param_name:\n        The name of the parameter (=key)\n\n    :param default_value: -- default: None\n        The value to be used if the parameter is not in the dict\n\n    :param low_limit: -- default: None\n        The minimum allowable value\n\n    :param high_limit: -- default: None\n        The maximum allowable value\n\n    :param allow_equal_limit: -- default: True\n        Limits are included in range of allowable values\n        (min <= x <= max if true else min < x < max)\n\n    :param **kwargs:\n        The parameters as packed dict\n    \"\"\"\n    val = kwargs.get(param_name, default_value)\n    if val is not None:\n        if type(val) not in [int, float]:\n            raise TypeError('{} needs to be of type int or float'.format(param_name))\n        if low_limit is not None:\n            if val < low_limit or (val == low_limit and not allow_equal_limit):\n                raise ValueError(\n                    '{} with value {} violates the low limit of {}'\n                    .format(param_name, val, low_limit))\n        if high_limit is not None:\n            if val > high_limit or (val == low_limit and not allow_equal_limit):\n                raise ValueError(\n                    '{} with value {} violates the high limit of {}'\n                    .format(param_name, val, high_limit))\n    return val\n\n\ndef round_to(value, base):\n    r\"\"\" Round a value to a given base value\n\n    :param value:\n        The value to round\n\n    :param base:\n        The base value. The resulting value will be rounded to a multiple of it\n\n    :return:\n        The rounded value\n    \"\"\"\n\n    return round(value/base) * base\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    {one line to give the program's name and a brief idea of what it does.}\n    Copyright (C) {year}  {name of author}\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    {project}  Copyright (C) {year}  {fullname}\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n\n"
  },
  {
    "path": "README.md",
    "content": "## :warning: 301 Moved Permanently\nLocation: https://gitlab.com/kicad/libraries/kicad-footprint-generator\n\n---\n\nThis repository contains scripts to generate custom KiCAD footprints using python, and a framework which allows us to\ncreate custom KiCAD footprint. A big bunch of footprints of the KiCad library was developed using this framework.\n\n# KicadModTree\n\n**Licence:** GNU GPLv3+\n\n**Maintainer:** Thomas Pointhuber\n\n[![Build Status](https://travis-ci.org/pointhi/kicad-footprint-generator.svg?branch=master)](https://travis-ci.org/pointhi/kicad-footprint-generator)\n[![Code Climate](https://codeclimate.com/github/pointhi/kicad-footprint-generator/badges/gpa.svg)](https://codeclimate.com/github/pointhi/kicad-footprint-generator)\n[![Documentation Status](https://readthedocs.org/projects/kicad-footprint-generator/badge/?version=latest)](http://kicad-footprint-generator.readthedocs.io/en/latest/?badge=latest)\n\n**Supports:** Python 2.7 and 3.3+\n\n## About\n\nI started drawing a bunch of similar footprints for KiCAD, like connectors which are mainly one base shape, and different\namount of pins. To be able to update/improve those footprints quickly I decided to write my own footprint generator Framework,\nto allow simple creation of easy as well complex shapes.\n\nThis is my second approach (the first one can be found in the git history). This solution should be able to be easy to\nuse, to read and also be easy to expand with custom nodes.\n\n\n## Overview\n\nThis framework is mainly based on the idea of scripted CAD systems (for example OpenSCAD). This means, everything is a\nnode, and can be structured like a tree. In other words, you can group parts of the footprint, and translate them in any\nway you want. Also cloning & co. is no problem anymore because of this concept.\n\nTo be able to create custom Nodes, I separated the system in two parts. Base nodes, which represents simple structures\nand also be used by KiCAD itself, and specialized nodes which alter the behaviour of base nodes (for example positioning),\nor represent a specialized usage of base nodes (for example RectLine).\n\nWhen you serialize your footprint, the serialize command only has to handle base nodes, because all other nodes are based\nupon the base nodes. This allows us to write specialized nodes without worrying about the FileHandlers or other core systems.\nYou simply create your special node, and the framework knows how to handle it seamlessly.\n\nPlease look into the **[Documentation](http://kicad-footprint-generator.readthedocs.io/en/latest/)** for further details\n\n```\nKicadModTree        - The KicadModTree framework which is used for footprint generation\ndocs                - Files required to generate a sphinx documentation\nscripts             - scripts which are generating footprints based on this library\n```\n\n## Development\n\n### Install development Dependencies\n\n```sh\nmanage.sh update_dev_packages\n```\n\n### run tests\n\n```sh\nmanage.sh tests\n```\n\n## Example Script\n\n```python\nfrom KicadModTree import *\n\nfootprint_name = \"example_footprint\"\n\n# init kicad footprint\nkicad_mod = Footprint(footprint_name)\nkicad_mod.setDescription(\"A example footprint\")\nkicad_mod.setTags(\"example\")\n\n# set general values\nkicad_mod.append(Text(type='reference', text='REF**', at=[0, -3], layer='F.SilkS'))\nkicad_mod.append(Text(type='value', text=footprint_name, at=[1.5, 3], layer='F.Fab'))\n\n# create silscreen\nkicad_mod.append(RectLine(start=[-2, -2], end=[5, 2], layer='F.SilkS'))\n\n# create courtyard\nkicad_mod.append(RectLine(start=[-2.25, -2.25], end=[5.25, 2.25], layer='F.CrtYd'))\n\n# create pads\nkicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n                     at=[0, 0], size=[2, 2], drill=1.2, layers=Pad.LAYERS_THT))\nkicad_mod.append(Pad(number=2, type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n                     at=[3, 0], size=[2, 2], drill=1.2, layers=Pad.LAYERS_THT))\n\n# add model\nkicad_mod.append(Model(filename=\"example.3dshapes/example_footprint.wrl\",\n                       at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n\n# output kicad model\nfile_handler = KicadFileHandler(kicad_mod)\nfile_handler.writeFile('example_footprint.kicad_mod')\n```\n## Usage Steps\n\n1. Navigate into the `scripts` directory, and look for the type of footprint you would like to generate. For example, if you wish to generate an SMD inductor footprint, `cd` into `scripts/Inductor_SMD`.\n2. Open the \\*.yaml (or \\*.yml) file in a text editor. Study a few of the existing footprint definitions to get an idea of how your new footprint entry should be structured.\n3. Add your new footprint by inserting your own new section in the file. An easy way to do this is by simply copying an existing footprint definition, and modifying it to suit your part. Note:  You may have to add or remove additional parameters that are not listed.\n4. Save your edits and close the text editor.\n5. Run the python script, passing the \\*.yaml or (\\*.yml) file as a parameter, e.g. `python3 Inductor_SMD.py Inductor_SMD.yml`. This will generate the \\*.kicad_mod files for each footprint defined in the \\*.yaml (or \\*.yml).\n"
  },
  {
    "path": "docs/KicadModTree.nodes.base.rst",
    "content": "KicadModTree.nodes.base package\n===============================\n\nThose nodes represent the primitives which we can use to create footprints. They are 1:1 mappings to the corresponding\ntypes used in .kicad_mod files.\n\nKicadModTree.nodes.base.Arc module\n----------------------------------\n\n.. automodule:: KicadModTree.nodes.base.Arc\n    :members:\n    :show-inheritance:\n\nKicadModTree.nodes.base.Circle module\n-------------------------------------\n\n.. automodule:: KicadModTree.nodes.base.Circle\n    :members:\n    :show-inheritance:\n\nKicadModTree.nodes.base.Line module\n-----------------------------------\n\n.. automodule:: KicadModTree.nodes.base.Line\n    :members:\n    :show-inheritance:\n\nKicadModTree.nodes.base.Model module\n------------------------------------\n\n.. automodule:: KicadModTree.nodes.base.Model\n    :members:\n    :show-inheritance:\n\nKicadModTree.nodes.base.Pad module\n----------------------------------\n\n.. automodule:: KicadModTree.nodes.base.Pad\n    :members:\n    :show-inheritance:\n\nKicadModTree.nodes.base.Polygon module\n----------------------------------\n\n.. automodule:: KicadModTree.nodes.base.Polygon\n    :members:\n    :show-inheritance:\n\nKicadModTree.nodes.base.Text module\n-----------------------------------\n\n.. automodule:: KicadModTree.nodes.base.Text\n    :members:\n    :show-inheritance:\n"
  },
  {
    "path": "docs/KicadModTree.nodes.rst",
    "content": "KicadModTree.nodes package\n==========================\n\n.. toctree::\n\n    KicadModTree.nodes.base\n    KicadModTree.nodes.specialized\n\n\nKicadModTree.nodes.Footprint module\n-----------------------------------\n\n.. automodule:: KicadModTree.nodes.Footprint\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\nKicadModTree.nodes.Node module\n------------------------------\n\n.. automodule:: KicadModTree.nodes.Node\n    :members:\n    :undoc-members:\n    :show-inheritance:\n"
  },
  {
    "path": "docs/KicadModTree.nodes.specialized.rst",
    "content": "KicadModTree.nodes.specialized package\n======================================\n\nTo simpilfy the creation on footprints, we have special classes which are build onto the base nodes. special nodes are\nconverted to base nodes when creating the footprint, and allows us to create much more complex shapes with as little\nboilerplate code as possible.\n\nKicadModTree.nodes.specialized.PolygoneLine module\n--------------------------------------------------\n\n.. automodule:: KicadModTree.nodes.specialized.PolygoneLine\n    :members:\n    :show-inheritance:\n\nKicadModTree.nodes.specialized.RectLine module\n----------------------------------------------\n\n.. automodule:: KicadModTree.nodes.specialized.RectLine\n    :members:\n    :show-inheritance:\n\nKicadModTree.nodes.specialized.RectFill module\n----------------------------------------------\n\n.. automodule:: KicadModTree.nodes.specialized.RectFill\n    :members:\n    :show-inheritance:\n\nKicadModTree.nodes.specialized.FilledRect module\n------------------------------------------------\n\n.. automodule:: KicadModTree.nodes.specialized.FilledRect\n    :members:\n    :show-inheritance:\n\nKicadModTree.nodes.specialized.PadArray module\n------------------------------------------------\n\n.. automodule:: KicadModTree.nodes.specialized.PadArray\n    :members:\n    :show-inheritance:\n\nKicadModTree.nodes.specialized.Rotation module\n----------------------------------------------\n\n.. automodule:: KicadModTree.nodes.specialized.Rotation\n    :members:\n    :show-inheritance:\n\nKicadModTree.nodes.specialized.Translation module\n-------------------------------------------------\n\n.. automodule:: KicadModTree.nodes.specialized.Translation\n    :members:\n    :show-inheritance:\n"
  },
  {
    "path": "docs/KicadModTree.rst",
    "content": "KicadModTree package\n====================\n\n.. toctree::\n\n    KicadModTree.nodes\n    KicadModTree.util\n\n\nKicadModTree.FileHandler module\n-------------------------------\n\n.. automodule:: KicadModTree.FileHandler\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\nKicadModTree.KicadFileHandler module\n------------------------------------\n\n.. automodule:: KicadModTree.KicadFileHandler\n    :members:\n    :undoc-members:\n    :inherited-members:\n    :show-inheritance:\n\nKicadModTree.ModArgparser module\n--------------------------------\n\n.. automodule:: KicadModTree.ModArgparser\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\nKicadModTree.Vector module\n-------------------------\n\n.. automodule:: KicadModTree.Vector\n    :members:\n    :undoc-members:\n    :special-members:\n    :show-inheritance:\n\n"
  },
  {
    "path": "docs/KicadModTree.util.rst",
    "content": "KicadModTree.util package\n=========================\n\nKicadModTree.util.kicad_util module\n-----------------------------------\n\n.. automodule:: KicadModTree.util.kicad_util\n    :members:\n    :undoc-members:\n    :show-inheritance:\n"
  },
  {
    "path": "docs/Makefile",
    "content": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nSPHINXPROJ    = KicadModTree\nSOURCEDIR     = .\nBUILDDIR      = _build\n\n# Put it first so that \"make\" without argument is like \"make help\".\nhelp:\n\t@$(SPHINXBUILD) -M help \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n\n.PHONY: help Makefile\n\n# Catch-all target: route all unknown targets to Sphinx using the new\n# \"make mode\" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).\n%: Makefile\n\t@$(SPHINXBUILD) -M $@ \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)"
  },
  {
    "path": "docs/conf.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n#\n# KicadModTree documentation build configuration file, created by\n# sphinx-quickstart on Sun Feb 19 20:08:44 2017.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#\nimport os\nimport sys\nsys.path.insert(0, os.path.abspath('..'))\n\n# -- General configuration ------------------------------------------------\n\nimport sphinx_rtd_theme\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#\n# needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = ['sphinx.ext.autodoc',\n    'sphinx.ext.doctest',\n    'sphinx.ext.coverage',\n    'sphinx.ext.viewcode']\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n#\n# source_suffix = ['.rst', '.md']\nsource_suffix = '.rst'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = 'KicadModTree'\ncopyright = '2017, Thomas Pointhuber'\nauthor = 'Thomas Pointhuber'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = '0.1'\n# The full version, including alpha/beta/rc tags.\nrelease = '0.1'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = None\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This patterns also effect to html_static_path and html_extra_path\nexclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = False\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\n#\n#html_theme = 'alabaster'\nhtml_theme = \"sphinx_rtd_theme\"\n\nhtml_theme_path = [sphinx_rtd_theme.get_html_theme_path()]\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#\n# html_theme_options = {}\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']\n\n\n# -- Options for HTMLHelp output ------------------------------------------\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'KicadModTreedoc'\n\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n    # The paper size ('letterpaper' or 'a4paper').\n    #\n    # 'papersize': 'letterpaper',\n\n    # The font size ('10pt', '11pt' or '12pt').\n    #\n    # 'pointsize': '10pt',\n\n    # Additional stuff for the LaTeX preamble.\n    #\n    # 'preamble': '',\n\n    # Latex figure (float) alignment\n    #\n    # 'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n    (master_doc, 'KicadModTree.tex', 'KicadModTree Documentation',\n     'Thomas Pointhuber', 'manual'),\n]\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    (master_doc, 'kicadmodtree', 'KicadModTree Documentation',\n     [author], 1)\n]\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n    (master_doc, 'KicadModTree', 'KicadModTree Documentation',\n     author, 'KicadModTree', 'One line description of project.',\n     'Miscellaneous'),\n]\n\n\n\n"
  },
  {
    "path": "docs/index.rst",
    "content": ".. KicadModTree documentation master file, created by\n   sphinx-quickstart on Sun Feb 19 20:08:44 2017.\n   You can adapt this file completely to your liking, but it should at least\n   contain the root `toctree` directive.\n\nWelcome to KicadModTree's documentation!\n========================================\n\nKicadModTree is a framework which allows standalone creation KiCAD footprint.\n\n\nOverview\n========\n\nThis framework is mainly based on the idea of scripted CAD systems (for example OpenSCAD). This means, everything is a node, and can be structured like a tree.\nIn other words, you can group parts of the footprint, and translate them in any way you want. Also cloning & co. is no Problem anymore because of this concept.\n\nTo be able to create custom Nodes, I separated the system in two parts. Base nodes, which represents simple structures and also be used by KiCAD itself,\nand specialized nodes which alter the behaviour of base nodes (for example positioning), or represent a specialized usage of base nodes (for example RectLine).\n\nWhen you serialize your footprint, the serialize command only has to handle base nodes, because all other nodes are based upon the base nodes.\nThis allows us to write specialized nodes without worrying about the FileHandlers or other core systems.\nYou simply create you special node, and the framework knows how to handle it seamlessly.\n\n\nModule Index\n============\n\n.. toctree::\n   :maxdepth: 4\n   :glob:\n\n   KicadModTree\n\n\nIndices and tables\n==================\n\n* :ref:`genindex`\n* :ref:`modindex`\n* :ref:`search`\n"
  },
  {
    "path": "manage.sh",
    "content": "#!/usr/bin/env bash\n\nif [[ \"$OSTYPE\" == \"darwin\"* ]]; then\ncommand -v greadlink >/dev/null 2>&1 || { echo >&2 \"greadlink not found. Install using 'brew install coreutils'\"; exit 1; }\nBASE_DIR=\"$(dirname \"$(greadlink -f \"$0\")\")\"\nelse\nBASE_DIR=\"$(dirname \"$(readlink -f \"$0\")\")\"\nfi\n\nPYTHONPATH=$BASE_DIR\nKICADMODTREE_DIR=\"$BASE_DIR/KicadModTree\"\nACTION=$1\n\nupdate_packages() {\n    pip install --upgrade -r \"$BASE_DIR/requirements.txt\"\n}\n\nupdate_dev_packages() {\n\tupdate_packages\n    pip install --upgrade -r \"$BASE_DIR/requirements-dev.txt\"\n}\n\npep8_check() {\n    echo ''\n    echo '[!] Running pep8 check'\n    pep8 --max-line-length=120 \"$KICADMODTREE_DIR/\"\n}\n\nflake8_check() {\n    echo ''\n    echo '[!] Running flake8 check'\n    flake8 \"$KICADMODTREE_DIR/\"\n}\n\nunit_tests() {\n    echo ''\n    echo '[!] Running unit tests'\n    python \"$KICADMODTREE_DIR/tests/test.py\"\n}\n\npy_test_coverage() {\n    echo '[!] Running python test coverage'\n    PYTHONPATH=`pwd` python -m nose2 -C --coverage \"$KICADMODTREE_DIR\" --coverage-report term-missing -s \"$KICADMODTREE_DIR/tests\"\n}\n\ntests() {\n    set -e\n    unit_tests\n    pep8_check\n    set +e\n}\n\n\n\nhelp() {\n    [ -z \"$1\" ] || printf \"Error: $1\\n\"\n    echo ''\n    echo \"Searx manage.sh help\n\nCommands\n========\n    help                 - This text\n    pep8_check           - pep8 validation\n    flake8_check         - flake8 validation\n    unit_tests           - Run unit tests\n    py_test_coverage     - Unit test coverage\n    tests                - Run all tests\n    update_packages      - Check & update production dependency changes\n    update_dev_packages  - Check & update development and production dependency changes\n\"\n}\n\n#[ \"$(command -V \"$ACTION\" | grep ' function$')\" = \"\" ] \\\n#    && help \"action not found\" \\\n#    || $ACTION\nif [ -n \"$(type -t $ACTION)\" ] && [ \"$(type -t $ACTION)\" = function ]; then\n     $ACTION\n else\n     help \"action not found\"\nfi\n"
  },
  {
    "path": "requirements-dev.txt",
    "content": "pep8\nflake8\nunittest2\nnose2\nnose2-cov\nsphinx\nsphinx_rtd_theme\n"
  },
  {
    "path": "requirements.txt",
    "content": "pyyaml\nfuture\n"
  },
  {
    "path": "scripts/Battery/BatteryHolder.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nimport re\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))\n\n# load scripts\nsys.path.append(os.path.join(sys.path[0], \"..\"))\n\nfrom KicadModTree import *\nfrom general.StandardBox import *\n\ndef qfn(args):\n\n    extraffablines = []\n\n    footprint_name = args[\"name\"]\n    description = args[\"description\"]\n    datasheet = args[\"description\"]\n    fptag = args[\"tags\"]\n    SmdTht = args[\"smd_tht\"]\n    at = args[\"at\"]\n    size = args[\"size\"]\n    pins = args[\"pins\"]\n    extratexts = args[\"extratexts\"]\n\n    dir3D = 'Battery.3dshapes'\n    f = Footprint(footprint_name)\n\n    file3Dname = \"${KISYS3DMOD}/\" + dir3D + \"/\" + footprint_name + \".wrl\"\n    words = footprint_name.split(\"_\")\n    if words[-1].lower().startswith('handsolder'):\n        words[-1] = ''\n        ff = '_'.join(words)\n        file3Dname = \"${KISYS3DMOD}/\" + dir3D + \"/\" + ff + \".wrl\"\n    f.append(StandardBox(footprint=f, description=description, datasheet=datasheet, at=at, size=size, tags=fptag, SmdTht=SmdTht, extratexts=extratexts, pins=pins, file3Dname=file3Dname ))\n    #\n    #\n    #\n    file_handler = KicadFileHandler(f)\n    file_handler.writeFile(footprint_name + \".kicad_mod\")\n\n\nif __name__ == '__main__':\n\tparser = ModArgparser(qfn)\n\t# the root node of .yml files is parsed as name\n\tparser.add_parameter(\"name\", type=str, required=True)\n\tparser.add_parameter(\"description\", type=str, required=True)\n\tparser.add_parameter(\"datasheet\", type=str, required=True)\n\tparser.add_parameter(\"tags\", type=str, required=True)\n\tparser.add_parameter(\"smd_tht\", type=str, required=False, default='tht')\n\tparser.add_parameter(\"at\", type=list, required=True)\n\tparser.add_parameter(\"size\", type=list, required=False)\n\tparser.add_parameter(\"pins\", type=list, required=True)\n\tparser.add_parameter(\"extratexts\", type=list, required=True)\n\n\n\t# now run our script which handles the whole part of parsing the files\n\tparser.run()\n"
  },
  {
    "path": "scripts/Battery/BatteryHolder.yml",
    "content": "BatteryHolder_Bulgin_BX0033_1xPP3:\n  description: \"Bulgin Battery Holder, BX0033, Battery Type 1xPP3\"\n  datasheet: \"http://www.bulgin.com/media/bulgin/data/Battery_holders.pdf\"\n  tags: \"Bulgin Battery Holder, BX0033, Battery Type 1xPP3\"\n  extratexts: [[-3.0, 0, \"-\", \"F.SilkS\", 1.0, 1.0]]\n  at: [-1.7, 8.55]\n  size: [58.7, 29.8]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.6], [\"tht\", \"2\", 0, -12.7, 3.0, 3.0, 1.6], [\"npth\", \"\", 10.7, -6.35, 3.0, 0, 3.0], [\"npth\", \"\", 24.7, -6.35, 3.0, 0, 3.0]]\n\nBatteryHolder_Bulgin_BX0034_1xAAA:\n  description: \"Bulgin Battery Holder, BX0034, Battery Type 1xAAA\"\n  datasheet: \"http://www.bulgin.com/media/bulgin/data/Battery_holders.pdf\"\n  tags: \"Bulgin Battery Holder, BX0034, Battery Type 1xAAA\"\n  extratexts: [[-4.5, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-1.7, 8.65]\n  size: [52.3, 17.3]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.6], [\"tht\", \"2\", 48.9, 0, 3.0, 3.0, 1.6], [\"npth\", \"\", 10.5, 0, 3.2, 0, 3.2], [\"npth\", \"\", 38.4, 0, 3.2, 0, 3.2]]\n  \nBatteryHolder_Bulgin_BX0035_1xAA:\n  description: \"Bulgin Battery Holder, BX0035, Battery Type 1xAA (http://www.bulgin.com/media/bulgin/data/Battery_holders.pdf)\"\n  datasheet: \"Bulgin Battery Holder, BX0035, Battery Type 1xAA (http://www.bulgin.com/media/bulgin/data/Battery_holders.pdf)\"\n  tags: \"Bulgin Battery Holder, BX0035, Battery Type 1xAA\"\n  extratexts: [[-4.5, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-1.75, 10.80]\n  size: [60.3, 21.6]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.6], [\"tht\", \"2\", 56.8, 0, 3.0, 3.0, 1.6], [\"npth\", \"\", 11.9, 0, 3.8, 0, 3.8], [\"npth\", \"\", 44.9, 0, 3.8, 0, 3.8]]\n  \nBatteryHolder_Bulgin_BX0036_1xC:\n  description: \"Bulgin Battery Holder, BX0036, Battery Type 1xC\"\n  datasheet: \"http://www.bulgin.com/media/bulgin/data/Battery_holders.pdf\"\n  tags: \"Bulgin Battery Holder, BX0036, Battery Type 1xC\"\n  extratexts: [[-4.5, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-1.75, 17.0]\n  size: [59.1, 34.0]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.6], [\"tht\", \"2\", 55.6, 0, 3.0, 3.0, 1.6], [\"npth\", \"\", 11.9, 0, 3.8, 0, 3.8], [\"npth\", \"\", 43.7, 0, 3.8, 0, 3.8]]\n  \nBatteryHolder_Bulgin_BX0037_1xD:\n  description: \"Bulgin Battery Holder, BX0037, Battery Type 1xD\"\n  datasheet: \"http://www.bulgin.com/media/bulgin/data/Battery_holders.pdf\"\n  tags: \"Bulgin Battery Holder, BX0037, Battery Type 1xD\"\n  extratexts: [[-4.5, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-1.75, 20.95]\n  size: [71.0, 41.9]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.6], [\"tht\", \"2\", 67.5, 0, 3.0, 3.0, 1.6], [\"npth\", \"\", 15.95, 0, 3.8, 0, 3.8], [\"npth\", \"\", 51.55, 0, 3.8, 0, 3.8]]\n\nBatteryHolder_Bulgin_BX0123_1xCR123:\n  description: \"Bulgin Battery Holder, BX0123, Battery Type 1xCR123\"\n  datasheet: \"http://www.bulgin.com/media/bulgin/data/Battery_holders.pdf\"\n  tags: \"Bulgin Battery Holder, BX0123, Battery Type 1xCR123\"\n  extratexts: [[-4.5, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-1.75, 10.0]\n  size: [41.3, 20.0]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.6], [\"tht\", \"2\", 37.8, 0, 3.0, 3.0, 1.6], [\"npth\", \"\", 10.425, 0, 3.2, 0, 3.2], [\"npth\", \"\", 27.375, 0, 3.2, 0, 3.2]]\n\nBatteryHolder_Keystone_1042_1x18650:\n  description: \"Keystone Battery Holder, 1042, Battery Type 1x18650\"\n  datasheet: \"http://www.keyelco.com/product.cfm/product_id/918\"\n  tags: \"Keystone Battery Holder, 1042, Battery Type 1x18650\"\n  extratexts: [[-49.0, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-43.205, 10.325]\n  size: [86.41, 20.65]\n  smd_tht: \"smd\"\n  pins: [[\"smd\", \"1\", -43.205, 0, 6.47, 6.47, 0.0], [\"smd\", \"2\", 43.205, 0, 6.47, 6.47, 0.0]]\n\nBatteryHolder_Keystone_2466_1xAAA:\n  description: \"Keystone Battery Holder, 2466, Battery Type 1xAAA\"\n  datasheet: \"http://www.keyelco.com/product-pdf.cfm?p=1031\"\n  tags: \"Keystone Battery Holder, 2466, Battery Type 1xAAA\"\n  extratexts: [[-4.5, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-2.645, 6.50]\n  size: [49.99, 13.00]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.1], [\"tht\", \"2\", 44.70, 0, 3.0, 3.0, 1.1]]\n  \nBatteryHolder_Keystone_2468_2xAAA:\n  description: \"Keystone Battery Holder, 2468, Battery Type 2xAAA\"\n  datasheet: \"http://www.keyelco.com/product-pdf.cfm?p=1033\"\n  tags: \"Keystone Battery Holder, 2468, Battery Type 2xAAA\"\n  extratexts: [[-4.5, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-2.865, 5.945]\n  size: [52.98, 24.59]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.1], [\"tht\", \"2\", 0, -12.70, 3.0, 3.0, 1.1], [\"npth\", \"\", 8.64, -4, 3.45, 0, 3.45], [\"npth\", \"\", 38.61, -8, 3.45, 0, 3.45]]\n\nBatteryHolder_Keystone_2479_3xAAA:\n  description: \"Keystone Battery Holder, 2479, Battery Type 3xAAA\"\n  datasheet: \"http://www.keyelco.com/product-pdf.cfm?p=1041\"\n  tags: \"Keystone Battery Holder 2479 Battery Type 3xAAA\"\n  extratexts: [[-4.5, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-2.59, 6.995]\n  size: [52.63, 37.49]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.1], [\"tht\", \"2\", 0, -12.70, 3.0, 3.0, 1.1], [\"npth\", \"\", 23.72, 0, 3.45, 0, 3.45], [\"npth\", \"\", 23.72, -23.50, 3.45, 0, 3.45]]\n\nBatteryHolder_MPD_BC2AAPC_2xAA:\n  description: \"Keystone Battery Holder, BC2AAPC, Battery Type 2xAA\"\n  datasheet: \"http://www.memoryprotectiondevices.com/datasheets/BC2AAPC-datasheet.pdf\"\n  tags: \"MPD Battery Holder, BC2AAPC, Battery Type 2xAA\"\n  extratexts: [[-4.5, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-2.84, 8.445]\n  size: [58.00, 30.50]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.1], [\"tht\", \"2\", 0, -13.59, 3.0, 3.0, 1.1], [\"npth\", \"\", 26.16, -6.63, 3.56, 0, 3.56]]\n\nBatteryHolder_MPD_BC12AAPC_2xAA:\n  description: \"Keystone Battery Holder, BC12AAPC, Battery Type 2xAA\"\n  datasheet: \"http://www.memoryprotectiondevices.com/datasheets/BC12AAPC-datasheet.pdf\"\n  tags: \"MPD Battery Holder, BC12AAPC, Battery Type 2xAA\"\n  extratexts: [[-4.5, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-2.9, 8.1]\n  size: [107.8, 16.20]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.1], [\"tht\", \"2\", 102.0, 0, 3.0, 3.0, 1.1],  [\"npth\", \"\", 26.15, 4.75, 2.5, 0, 1.1], [\"npth\", \"\", 26.15, -4.75, 2.5, 0, 1.1], [\"npth\", \"\", 75.85, 4.75, 2.5, 0, 1.1], [\"npth\", \"\", 75.85, -4.75, 2.5, 0, 1.1]]\n\nBatteryHolder_MPD_BH-18650-PC:\n  description: \"Keystone Battery Holder, BH-18650, Battery Type 1x18650\"\n  datasheet: \"http://www.memoryprotectiondevices.com/datasheets/BH-18650-PC-datasheet.pdf\"\n  tags: \"MPD Battery Holder, BH-18650, Battery Type 1x18650\"\n  extratexts: [[-4.5, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-2.4, 10.45]\n  size: [77.7, 20.9]\n  pins: [[\"tht\", \"1\", 0, 0,  3.0, 3.0, 1.57], [\"tht\", \"2\", 72.90, 0,  3.0, 3.0, 1.57], [\"npth\", \"\", 8.445, 0.0, 3.2, 0, 3.2], [\"npth\", \"\", 64.055, 0.0, 3.2, 0, 3.2]]\n\nBatteryHolder_MPD_BK-18650-PC2:\n  description: \"Keystone Battery Holder, BH-18650, Battery Type 1x18650\"\n  datasheet: \"http://www.memoryprotectiondevices.com/datasheets/BK-18650-PC2-datasheet.pdf\"\n  tags: \"MPD Battery Holder, BK-18650, Battery Type 1x18650\"\n  extratexts: [[-4.5, -0.05, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-2.23, 10.49]\n  size: [76.96, 20.98]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.57], [\"tht\", \"2\", 72.90, 0, 3.0, 3.0, 1.57], [\"npth\", \"\", 8.445, 0.0, 3.2, 0, 3.2], [\"npth\", \"\", 64.055, 0.0, 3.2, 0, 3.2]]\n\nBatteryHolder_TruPower_BH-331P_3xAA:\n  description: \"Keystone Battery Holder BH-331P Battery Type 3xAA\"\n  datasheet: \"https://static.rapidonline.com/pdf/18-2967_v1.pdf\"\n  tags: \"Battery Holder BH-331P Battery Type 3xAA\"\n  extratexts: [[-4.5, 0.0, \"+\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-2.3, 9.15]\n  size: [58.0, 48.3]\n  pins: [[\"tht\", \"1\", 0, 0, 3.0, 3.0, 1.2], [\"tht\", \"2\", 0, -12.8, 3.0, 3.0, 1.2], [\"npth\", \"\", 26.7, 0.0, 3.5, 0, 3.5], [\"npth\", \"\", 26.7, -30.0, 3.5, 0, 3.5]]\n\n\n"
  },
  {
    "path": "scripts/Battery/README.txt",
    "content": "Script to generate the battery holders\n\nTo create all, type\npython BatteryHolder.py BatteryHolder.yml\n"
  },
  {
    "path": "scripts/Buttons_Switches/make_DIPSwitches.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_DIP import *\n\n\n\n\n\nif __name__ == '__main__':\n    cwd= os.getcwd()\n    try:\n      os.mkdir(\"SMD\")\n    except:\n      print(\"THT exists\")\n      \n    try:\n      os.mkdir(\"THT\")\n    except:\n      print(\"THT exists\")\n\n    # common settings\n    overlen_top=1.27\n    overlen_bottom=1.27\n    rm=2.54\n    ddrill=0.8\n    pad=[1.6,1.6]\n    pad_large=[2.4,1.6]\n    pad_smdsocket=[3.1,1.6]\n    pad_smdsocket_small=[1.6,1.6]\n\n\n    # DIP-switches:\n    pins=[2,4,6,8,10,12,14,16,18,20,22,24]\n    pinrow_distance = 7.62\n    package_width = 9.78\n    switch_width=4.06\n    switch_height=1.27\n    overlen_top = 2.36\n    overlen_bottom = 2.36\n    package_width_narrow = 6.7\n    switch_width_narrow = 3.62\n    switch_height_narrow = 1.27\n    overlen_top_narrow = 2.05\n    overlen_bottom_narrow = 2.05\n    pad_smd=[2.44,1.12]\n    pinrow_distance_smd=8.61\n    pinrow_distance_smd_J=6.73\n    pad_smd_J=[2.16,1.12]\n    switch_width_piano=1.8\n    switch_height_piano=1.5\n    package_width_piano=10.8\n    overlen_top_piano = 2.05\n    overlen_bottom_piano = 2.05\n    switchtype=\"SPST\"\n\n    for p in pins:\n        os.chdir(cwd)\n        os.chdir(\"THT\")\n        makeDIPSwitch(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad, switch_width, switch_height, 'Slide', False, [], webpage=\"e.g. https://www.ctscorp.com/wp-content/uploads/206-208.pdf\",switchtype=switchtype)\n        makeDIPSwitch(p, rm, pinrow_distance, package_width_narrow, overlen_top_narrow, overlen_bottom_narrow, ddrill, pad, switch_width_narrow, switch_height_narrow, 'Slide', False, [\"LowProfile\"], webpage=\"e.g. https://www.ctscorp.com/wp-content/uploads/209-210.pdf\",switchtype=switchtype)\n        makeDIPSwitch(p, rm, pinrow_distance, package_width_piano, overlen_top_piano, overlen_bottom_piano, ddrill, pad, switch_width_piano, switch_height_piano, 'Piano', False, [], webpage=\"\",switchtype=switchtype)\n        \n        os.chdir(cwd)\n        os.chdir(\"SMD\")\n        makeDIPSwitch(p, rm, pinrow_distance_smd, package_width_narrow, overlen_top_narrow, overlen_bottom_narrow, ddrill, pad_smd, switch_width_narrow, switch_height_narrow, 'Slide', True,[\"SMD\",\"LowProfile\"], 'Button_Switch_SMD', webpage=\"e.g. https://www.ctscorp.com/wp-content/uploads/219.pdf\",switchtype=switchtype)\n        makeDIPSwitch(p, rm, pinrow_distance_smd, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, switch_width, switch_height, 'Slide', True,[\"SMD\"], 'Button_Switch_SMD', webpage=\"e.g. https://www.ctscorp.com/wp-content/uploads/204.pdf\",switchtype=switchtype)\n        makeDIPSwitch(p, rm, pinrow_distance_smd_J, package_width_narrow, overlen_top_narrow, overlen_bottom_narrow, ddrill, pad_smd_J, switch_width_narrow, switch_height_narrow, 'Slide', True,[\"SMD\",\"LowProfile\",\"JPin\"], 'Button_Switch_SMD', webpage=\"e.g. https://www.ctscorp.com/wp-content/uploads/219.pdf\",switchtype=switchtype)\n\n\n    pins=[4,6,8,10,12,14,16,18,20,22,24]\n    switch_width_piano=1.14\n    switch_height_piano=1.52\n    package_width_piano=9.78\n    overlen_top_piano = (7.26-2.54)/2\n    overlen_bottom_piano = overlen_top_piano\n    os.chdir(cwd)\n    os.chdir(\"THT\")\n    for p in pins:\n        makeDIPSwitch(p, rm, pinrow_distance, package_width_piano, overlen_top_piano, overlen_bottom_piano, ddrill, pad, switch_width_piano, switch_height_piano, 'Piano', False, device_name=\"CTS_Series194-{0}MSTN\".format(int(p/2)), webpage=\"https://www.ctscorp.com/wp-content/uploads/194-195.pdf\",switchtype=switchtype)\n\n    # Copal CVS DIP-switches (http://www.nidec-copal-electronics.com/e/catalog/switch/cvs.pdf):\n    pins = [2, 4, 6, 8, 16]\n    rm = 1\n    pinrow_distance = 5.9\n    package_width = 4.7\n    switch_width = 2\n    switch_height = 0.5\n    overlen_top = 1\n    overlen_bottom = 1\n    ddrill = 0\n    pad_smd = [1.2, 0.5]\n\n    os.chdir(cwd)\n    os.chdir(\"SMD\")\n    for p in pins:\n        makeDIPSwitch(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, switch_width,\n                      switch_height, 'Slide', True, [], \"Button_Switch_SMD\", [0, 0, 0], [1, 1, 1],\n                      [0, 0, 0], \"\", True, [0.7, 0.7], 0.2, 0, webpage=\"http://www.nidec-copal-electronics.com/e/catalog/switch/cvs.pdf\", device_name=\"Copal_CVS-{0:02}xB\".format(int(p/2)),switchtype=switchtype)\n\n\n\n    # Omron A6H DIP-switches (https://www.omron.com/ecb/products/pdf/en-a6h.pdf):\n    pins = [4,8,12,16,20]\n    rm = 1.27\n    pinrow_distance = 6.15\n    package_width = 4.5\n    switch_width = 3.2\n    switch_height = 0.5\n    overlen_top = 1.27\n    overlen_bottom = 1.27\n    ddrill = 0\n    pad_smd = [1.25, 0.76]\n    \n    os.chdir(cwd)\n    os.chdir(\"SMD\")\n    for p in pins:\n        makeDIPSwitch(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, switch_width,\n                      switch_height, 'Slide', True, [], \"Button_Switch_SMD\", [0, 0, 0], [1, 1, 1],\n                      [0, 0, 0], \"\", True, webpage=\"https://www.omron.com/ecb/products/pdf/en-a6h.pdf\", device_name=\"Omron_A6H-{0}101\".format(int(p/2)),switchtype=switchtype)\n\n\n    # Omron A6S DIP-switches (http://omronfs.omron.com/en_US/ecb/products/pdf/en-a6s.pdf):\n    pins = [2,4,6,8,10,12,14,16,18,20]\n    rm = 2.54\n    pinrow_distance = 8.9\n    package_width = 6.2\n    switch_width = 3\n    switch_height = 1.1\n    overlen_top = 1.74\n    overlen_bottom = 1.74\n    ddrill = 0\n    pad_smd = [1.5, 1.1]\n\n    os.chdir(cwd)\n    os.chdir(\"SMD\")\n    for p in pins:\n        makeDIPSwitch(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, switch_width,\n                      switch_height, 'Slide', True, [], \"Button_Switch_SMD\", [0, 0, 0], [1, 1, 1],\n                      [0, 0, 0], \"\", True, webpage=\"http://omronfs.omron.com/en_US/ecb/products/pdf/en-a6s.pdf\", device_name=\"Omron_A6S-{0}10x\".format(int(p/2)),switchtype=switchtype)\n\n\n    # Copal CHS DIP-switches (http://www.nidec-copal-electronics.com/e/catalog/switch/chs.pdf):\n    pins = [2, 4, 8, 12, 16, 20]\n    rm = 1.27\n    pinrow_distance = 5.08\n    pinrow_distanceB = 7.62\n    package_width = 5.4\n    switch_width = 3\n    switch_height = 0.5\n    overlen_top = 1.27\n    overlen_bottom = 1.27\n    ddrill = 0\n    pad_smd = [1.6, 0.76]\n    \n    os.chdir(cwd)\n    os.chdir(\"SMD\")\n    for p in pins:\n        makeDIPSwitch(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, switch_width,\n                      switch_height, 'Slide', True,[\"SMD\",\"JPin\"], \"Button_Switch_SMD\", [0, 0, 0], [1, 1, 1],\n                      [0, 0, 0], \"\", True, webpage=\"http://www.nidec-copal-electronics.com/e/catalog/switch/chs.pdf\", device_name=\"Copal_CHS-{0:02}A\".format(int(p/2)),switchtype=switchtype)\n        makeDIPSwitch(p, rm, pinrow_distanceB, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, switch_width,\n                      switch_height, 'Slide', True,[\"SMD\"], \"Button_Switch_SMD\", [0, 0, 0], [1, 1, 1],\n                      [0, 0, 0], \"\", True, webpage=\"http://www.nidec-copal-electronics.com/e/catalog/switch/chs.pdf\", device_name=\"Copal_CHS-{0:02}B\".format(int(p/2)),switchtype=switchtype)\n\n\n    # KingTek DSHPxxTS DIP-switches (http://www.kingtek.net.cn/pic/201601201417455112.pdf):\n    pins = [4,6,8,10,12,14,16,18,20]\n    rm = 1.27\n    pinrow_distance = (8.89+6.35)/2\n    package_width = 5.4\n    switch_width = 2\n    switch_height = 0.8\n    overlen_top = (9.22-(5*1.27))/2\n    overlen_bottom = overlen_top\n    ddrill = 0\n    pad_smd = [(8.89-6.35)/2, 0.76]\n    \n    os.chdir(cwd)\n    os.chdir(\"SMD\")\n    for p in pins:\n        makeDIPSwitch(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, switch_width,\n                      switch_height, 'Slide', True, [], \"Button_Switch_SMD\", [0, 0, 0], [1, 1, 1],\n                      [0, 0, 0], \"\", True, webpage=\"http://www.kingtek.net.cn/pic/201601201417455112.pdf\", device_name=\"KingTek_DSHP{0:02}TS\".format(int(p/2)),switchtype=switchtype)\n\n\n    # KingTek DSHPxxTJ DIP-switches (http://www.kingtek.net.cn/pic/201601201446313350.pdf):\n    pins = [4,6,8,10,12,14,16,18,20]\n    rm = 1.27\n    pinrow_distance = (7.9+2.6)/2\n    package_width = 5.4\n    switch_width = 2\n    switch_height = 0.8\n    overlen_top = (6.88-(3*1.27))/2\n    overlen_bottom = overlen_top\n    ddrill = 0\n    pad_smd = [(7.9-2.6)/2, 0.76]\n    \n    os.chdir(cwd)\n    os.chdir(\"SMD\")\n    for p in pins:\n        makeDIPSwitch(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, switch_width,\n                      switch_height, 'Slide', True, [\"JPin\"], \"Button_Switch_SMD\", [0, 0, 0], [1, 1, 1],\n                      [0, 0, 0], \"\", True, webpage=\"http://www.kingtek.net.cn/pic/201601201446313350.pdf\", device_name=\"KingTek_DSHP{0:02}TJ\".format(int(p/2)),switchtype=switchtype)\n    \n    os.chdir(cwd)\n"
  },
  {
    "path": "scripts/Buttons_Switches/rotary_coded_switch.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))\n\nfrom KicadModTree import *\n\ndef rotary_coded_switch(args):\n    footprint_name = args[\"name\"]\n    style = args[\"style\"]\n    datasheet = args[\"datasheet\"]\n    thru_hole = args[\"thru_hole\"]\n    pad_width = args[\"pad_width\"]\n    pad_height = args[\"pad_height\"]\n    pad_x_spacing = args[\"pad_x_spacing\"]\n    pad_y_spacing = args[\"pad_y_spacing\"]\n    gray = args[\"gray\"]\n    drill_size = args[\"drill_size\"]\n    pkg_width = args[\"pkg_width\"]\n    pkg_height = args[\"pkg_height\"]\n\n    f = Footprint(footprint_name)\n    f.setDescription(\"4-bit rotary coded switch, \" + style + \", \" + datasheet)\n    f.setTags(\"rotary switch bcd\")\n    if thru_hole:\n        tech = \"THT\"\n    else:\n        tech = \"SMD\"\n        f.setAttribute(\"smd\")\n    f.append(Model(filename=\"${KISYS3DMOD}/Buttons_Switches_\" + tech + \".3dshapes/\" + footprint_name + \".wrl\", at=[0, 0, 0], scale=[1, 1, 1], rotate=[0.0, 0.0, 0.0]))\n\n    wCrtYd = 0.05\n    wFab = 0.1\n    wSilkS = 0.12\n    s = [1.0, 1.0]\n    t = 0.15\n\n    silk_clearance = 0.2\n    crtYd = 0.25\n\n    d = [drill_size, drill_size]\n    p = [pad_width, pad_height]\n\n    if thru_hole:\n        rows = [0, pad_y_spacing, 2 * pad_y_spacing]\n        columns = [0, pad_x_spacing]\n    else:\n        rows = [-pad_y_spacing, 0, pad_y_spacing]\n        columns = [-pad_x_spacing / 2, pad_x_spacing / 2]\n\n    if gray:\n        pins = [\"1\", \"8\", \"C\", \"X\", \"4\", \"2\"]\n    else:\n        pins = [\"1\", \"8\", \"C\", \"C\", \"4\", \"2\"]\n\n    xCenter = (columns[0] + columns[1]) / 2\n    yCenter = rows[1]\n\n    xLeft = xCenter - pkg_width / 2\n    xRight = xCenter + pkg_width / 2\n    yTop = yCenter - pkg_height / 2\n    yBottom = yCenter + pkg_height / 2\n    chamfer = 1.0\n\n    yRef = yTop - 1.25\n    yValue = yBottom + 1.25\n\n    boundLeft = xCenter - (pad_x_spacing + pad_width) / 2\n    boundRight = xCenter + (pad_x_spacing + pad_width) / 2\n\n    r = (pad_x_spacing - pad_width) / 2 - silk_clearance\n\n    # Text\n    f.append(Text(type=\"reference\", text=\"REF**\", at=[xCenter, yRef],\n                  layer=\"F.SilkS\", size=s, thickness=t))\n    f.append(Text(type=\"value\", text=footprint_name, at=[xCenter, yValue],\n                  layer=\"F.Fab\", size=s, thickness=t))\n    f.append(Text(type=\"user\", text=\"%R\", at=[xCenter, yCenter],\n                  layer=\"F.Fab\", size=s, thickness=t))\n\n    # Fab\n    f.append(PolygoneLine(polygone=[[xLeft + chamfer, yTop],\n                                    [xRight, yTop],\n                                    [xRight, yBottom],\n                                    [xLeft, yBottom],\n                                    [xLeft, yTop + chamfer],\n                                    [xLeft + chamfer, yTop]],\n                          layer=\"F.Fab\",\n                          width=wFab))\n\n    def tb_silkscreen(yOuter, yInner):\n        f.append(PolygoneLine(polygone=[[xLeft - wSilkS, yInner],\n                                        [xLeft - wSilkS, yOuter],\n                                        [xRight + wSilkS, yOuter],\n                                        [xRight + wSilkS, yInner]],\n                              layer=\"F.SilkS\",\n                              width=wSilkS))\n\n    space = pad_height / 2 + silk_clearance\n\n    tb_silkscreen(yTop - wSilkS, rows[0] - space)\n    tb_silkscreen(yBottom + wSilkS, rows[2] + space)\n\n    def compute_segment(row):\n        return [rows[row] + space, rows[row + 1] - space]\n\n    def lr_silkscreen(x, noMiddle):\n        ys1 = compute_segment(0)\n        ys2 = compute_segment(1)\n        if noMiddle:\n            ys = [[ys1[0], ys2[1]]]\n        else:\n            ys = [ys1, ys2]\n        for seg in ys:\n            f.append(Line(start=[x, seg[0]],\n                          end=[x, seg[1]],\n                          layer=\"F.SilkS\",\n                          width=wSilkS))\n\n    lr_silkscreen(xLeft - wSilkS, False)\n    lr_silkscreen(xRight + wSilkS, gray)\n\n    margin = crtYd + wSilkS\n    f.append(PolygoneLine(polygone=[[boundLeft - margin, yTop + chamfer],\n                                    [boundLeft - margin, yTop - margin],\n                                    [boundLeft + chamfer, yTop - margin]],\n                          layer=\"F.SilkS\",\n                          width=wSilkS))\n\n    if thru_hole:\n        f.append(Circle(center=[xCenter, yCenter],\n                        radius=r,\n                        layer=\"F.SilkS\",\n                        width=wSilkS))\n        f.append(Line(start=[xCenter, yCenter - r * 0.75],\n                      end=[xCenter, yCenter + r * 0.75],\n                      layer=\"F.SilkS\",\n                      width=wSilkS))\n        f.append(PolygoneLine(polygone=[[xCenter - r * 0.5, yCenter - r * 0.25],\n                                        [xCenter, yCenter - r * 0.75],\n                                        [xCenter + r * 0.5, yCenter - r * 0.25]],\n                              layer=\"F.SilkS\",\n                              width=wSilkS))\n\n    # Courtyard\n    f.append(RectLine(start=[boundLeft - crtYd, yTop - crtYd],\n                      end=[boundRight + crtYd, yBottom + crtYd],\n                      layer=\"F.CrtYd\",\n                      width=wCrtYd))\n\n    # Pins\n    for row in range(0, 3):\n        for col in range(0, 2):\n            pin = pins[row * 2 + col]\n            if pin == \"1\":\n                padShape=Pad.SHAPE_RECT\n            else:\n                padShape=Pad.SHAPE_OVAL\n            if pin != \"X\":\n                if thru_hole:\n                    f.append(Pad(number=pin,\n                                 type=Pad.TYPE_THT,\n                                 shape=padShape,\n                                 at=[columns[col], rows[row]],\n                                 size=p,\n                                 layers=Pad.LAYERS_THT,\n                                 drill=d))\n                else:\n                    f.append(Pad(number=pin,\n                                 type=Pad.TYPE_SMT,\n                                 shape=Pad.SHAPE_RECT,\n                                 at=[columns[col], rows[row]],\n                                 size=p,\n                                 layers=Pad.LAYERS_SMT))\n\n    file_handler = KicadFileHandler(f)\n    file_handler.writeFile(footprint_name + \".kicad_mod\")\n\n\nif __name__ == '__main__':\n    parser = ModArgparser(rotary_coded_switch)\n    # the root node of .yml files is parsed as name\n    parser.add_parameter(\"name\", type=str, required=True)\n    parser.add_parameter(\"style\", type=str, required=True)\n    parser.add_parameter(\"datasheet\", type=str, required=False, default=\"https://www.nidec-copal-electronics.com/e/catalog/switch/sh-7000.pdf\")\n    parser.add_parameter(\"thru_hole\", type=bool, required=False, default=False)\n    parser.add_parameter(\"pad_width\", type=float, required=False, default=2.5)\n    parser.add_parameter(\"pad_height\", type=float, required=False, default=1.0)\n    parser.add_parameter(\"pad_x_spacing\", type=float, required=False, default=6.5)\n    parser.add_parameter(\"pad_y_spacing\", type=float, required=False, default=2.54)\n    parser.add_parameter(\"gray\", type=bool, required=False, default=False)\n    parser.add_parameter(\"drill_size\", type=float, required=False, default=1.0)\n    parser.add_parameter(\"pkg_width\", type=float, required=False, default=7.1)\n    parser.add_parameter(\"pkg_height\", type=float, required=False, default=7.3)\n\n    # now run our script which handles the whole part of parsing the files\n    parser.run()\n\n"
  },
  {
    "path": "scripts/Buttons_Switches/rotary_coded_switch.yml",
    "content": "Nidec_Copal_SH-7010A:\n  style: J-hook\n  pad_width: 2.5\n  pad_x_spacing: 6.5\nNidec_Copal_SH-7010B:\n  style: gull wing\n  pad_width: 3.0\n  pad_x_spacing: 8.0\nNidec_Copal_SH-7010C:\n  style: through-hole\n  thru_hole: true\n  pad_height: 1.9\n  pad_width: 2.1\n  pad_x_spacing: 7.62\n  drill_size: 1.0\nNidec_Copal_SH-7040B:\n  style: gull wing, Gray code\n  gray: true\n  pad_width: 3.0\n  pad_x_spacing: 8.0\n"
  },
  {
    "path": "scripts/Buzzers_Beepers/buzzer_round_tht.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load parent path of KicadModTree\n\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\n\n\ndef buzzer_round_tht(args):\n    # some variables\n    buzzer_center = args['pad_spacing'] / 2.\n    buzzer_radius = args['diameter'] / 2.\n\n    # init kicad footprint\n    kicad_mod = Footprint(args['name'])\n    kicad_mod.setDescription(args['datasheet'])\n    kicad_mod.setTags(\"buzzer round tht\")\n\n    # set general values\n    kicad_mod.append(Text(type='reference', text='REF**', at=[buzzer_center, -buzzer_radius - 1], layer='F.SilkS'))\n    kicad_mod.append(Text(type='user', text='%R', at=[buzzer_center, -buzzer_radius - 1], layer='F.Fab'))\n    kicad_mod.append(Text(type='value', text=args['name'], at=[buzzer_center, buzzer_radius + 1], layer='F.Fab'))\n\n    # create silkscreen\n    kicad_mod.append(Circle(center=[buzzer_center, 0], radius=buzzer_radius + 0.1, layer='F.SilkS'))\n\n    kicad_mod.append(Text(type='user', text='+', at=[0, -args['pad_size'] / 2 - 1], layer='F.SilkS'))\n    kicad_mod.append(Text(type='user', text='+', at=[0, -args['pad_size']/2 - 1], layer='F.Fab'))\n\n    # create fabrication layer\n    kicad_mod.append(Circle(center=[buzzer_center, 0], radius=buzzer_radius, layer='F.Fab'))\n\n    # create courtyard\n    kicad_mod.append(Circle(center=[buzzer_center, 0], radius=buzzer_radius + args['courtyard'], layer='F.CrtYd'))\n\n    # create pads\n    kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n                         at=[0, 0], size=args['pad_size'], drill=args['hole_size'], layers=Pad.LAYERS_THT))\n    kicad_mod.append(Pad(number=2, type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n                         at=[args['pad_spacing'], 0], size=args['pad_size'], drill=args['hole_size'], layers=Pad.LAYERS_THT))\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('{}.kicad_mod'.format(args['name']))\n\n\nif __name__ == '__main__':\n    parser = ModArgparser(buzzer_round_tht)\n    parser.add_parameter(\"name\", type=str, required=True)  # the root node of .yml files is parsed as name\n    parser.add_parameter(\"datasheet\", type=str, required=False)\n    parser.add_parameter(\"courtyard\", type=float, required=False, default=0.25)\n    parser.add_parameter(\"diameter\", type=float, required=True)\n    parser.add_parameter(\"hole_size\", type=float, required=True)\n    parser.add_parameter(\"pad_size\", type=float, required=True)\n    parser.add_parameter(\"pad_spacing\", type=float, required=True)\n\n    parser.run()  # now run our script which handles the whole part of parsing the files\n"
  },
  {
    "path": "scripts/Buzzers_Beepers/buzzer_round_tht_star_mictronics.csv",
    "content": "name,datasheet,diameter,hole_size,pad_size,pad_spacing\nMagneticBuzzer_StarMicronics_QMB-105,http://datasheet.octopart.com/HMB06-Star-Micronics-datasheet-514145.pdf,12,1,2,6.5\nMagneticBuzzer_StarMicronics_QMB-108,http://datasheet.octopart.com/HMB06-Star-Micronics-datasheet-514145.pdf,12,1,2,6.5\nMagneticBuzzer_StarMicronics_QMB-111,http://datasheet.octopart.com/HMB06-Star-Micronics-datasheet-514145.pdf,12,1,2,6.5\nMagneticBuzzer_StarMicronics_QMX,http://datasheet.octopart.com/HMB06-Star-Micronics-datasheet-514145.pdf,12,1,2,6.6\nMagneticBuzzer_StarMicronics_HGP,http://datasheet.octopart.com/HMB06-Star-Micronics-datasheet-514145.pdf,16,1.1,2,7.6\nMagneticBuzzer_StarMicronics_RMX,http://datasheet.octopart.com/HMB06-Star-Micronics-datasheet-514145.pdf,16,1.1,2,7.6\nMagneticBuzzer_StarMicronics_QMB,http://datasheet.octopart.com/HMB06-Star-Micronics-datasheet-514145.pdf,16,1.1,2,7.6\nMagneticBuzzer_StarMicronics_TMX-F,http://datasheet.octopart.com/HMB06-Star-Micronics-datasheet-514145.pdf,25,1.2,2,10.2\nMagneticBuzzer_StarMicronics_TMX-H,http://datasheet.octopart.com/HMB06-Star-Micronics-datasheet-514145.pdf,25,1.2,2,10.2\nMagneticBuzzer_StarMicronics_TMB,http://datasheet.octopart.com/HMB06-Star-Micronics-datasheet-514145.pdf,12,1,2,7.6\nMagneticBuzzer_StarMicronics_HMB,http://datasheet.octopart.com/HMB06-Star-Micronics-datasheet-514145.pdf,16,1.1,2,7.6\n"
  },
  {
    "path": "scripts/Capacitors_SMD/CP_Elec_round.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport argparse\nimport yaml\nimport math\nfrom collections import namedtuple\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load parent path of KicadModTree\n\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\n\n\ndef create_footprint(name, configuration, **kwargs):\n    kicad_mod = Footprint(name)\n\n    # init kicad footprint\n    datasheet = \"\"\n    if 'datasheet' in kwargs:\n        datasheet = kwargs['datasheet']\n    kicad_mod.setDescription(kwargs['description'] + \" \" + datasheet)\n    kicad_mod.setTags('Capacitor Electrolytic')\n    kicad_mod.setAttribute('smd')\n\n    # set general values\n    text_offset_y = kwargs['width'] / 2. + configuration['courtyard_offset']['default'] + 0.8\n\n    #silkscreen REF**\n    silk_text_size = configuration['references'][0]['size']\n    silk_text_thickness = silk_text_size[0]*configuration['references'][0]['fontwidth']\n    kicad_mod.append(Text(type='reference', text='REF**', at=[0, -text_offset_y], layer='F.SilkS', size=[silk_text_size[0], silk_text_size[1]], thickness= silk_text_thickness))\n    #fab value\n    fab_text_size = configuration['values'][0]['size']\n    fab_text_thickness = fab_text_size[0]*configuration['values'][0]['fontwidth']\n    kicad_mod.append(Text(type='value', text=name, at=[0, text_offset_y], layer='F.Fab', size=[fab_text_size[0], fab_text_size[1]], thickness= fab_text_thickness))\n    #fab REF**\n    fab_text_size = kwargs['diameter']/5.\n    fab_text_size = min(fab_text_size, configuration['references'][1]['size_max'][0])\n    fab_text_size = max(fab_text_size, configuration['references'][1]['size_min'][0])\n    fab_text_thickness = fab_text_size*configuration['references'][1]['thickness_factor']\n    kicad_mod.append(Text(type='user', text='%R', at=[0, 0], layer='F.Fab', size=[fab_text_size, fab_text_size], thickness= fab_text_thickness))\n\n    # create fabrication layer\n    fab_x = kwargs['length'] / 2.\n    fab_y = kwargs['width'] / 2.\n\n    if kwargs['pin1_chamfer'] == 'auto':\n        fab_edge = min(fab_x/2, fab_y/2, configuration['fab_pin1_marker_length'])\n    else:\n        fab_edge = kwargs['pin1_chamfer']\n    fab_x_edge = fab_x - fab_edge\n    fab_y_edge = fab_y - fab_edge\n    kicad_mod.append(Line(start=[fab_x, -fab_y], end=[fab_x, fab_y], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Line(start=[-fab_x_edge, -fab_y], end=[fab_x, -fab_y], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Line(start=[-fab_x_edge, fab_y], end=[fab_x, fab_y], layer='F.Fab', width=configuration['fab_line_width']))\n    if fab_edge > 0:\n        kicad_mod.append(Line(start=[-fab_x, -fab_y_edge], end=[-fab_x, fab_y_edge], layer='F.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(Line(start=[-fab_x, -fab_y_edge], end=[-fab_x_edge, -fab_y], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Line(start=[-fab_x, fab_y_edge], end=[-fab_x_edge, fab_y], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Circle(center=[0, 0], radius=kwargs['diameter']/2., layer='F.Fab', width=configuration['fab_line_width']))\n\n\n    #fab polarity marker\n    fab_pol_size = kwargs['diameter']/10.\n    fab_pol_wing = fab_pol_size/2.\n    fab_pol_distance = kwargs['diameter']/2. - fab_pol_wing - configuration['fab_line_width']\n    fab_pol_pos_y = fab_text_size/2 + configuration['silk_pad_clearance'] + fab_pol_size\n    fab_pol_pos_x = math.sqrt(fab_pol_distance*fab_pol_distance-fab_pol_pos_y*fab_pol_pos_y)\n    fab_pol_pos_x = -fab_pol_pos_x\n    fab_pol_pos_y = -fab_pol_pos_y\n    kicad_mod.append(Line(start=[fab_pol_pos_x-fab_pol_wing, fab_pol_pos_y], end=[fab_pol_pos_x+fab_pol_wing, fab_pol_pos_y], \n        layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Line(start=[fab_pol_pos_x, fab_pol_pos_y-fab_pol_wing], end=[fab_pol_pos_x, fab_pol_pos_y+fab_pol_wing], \n        layer='F.Fab', width=configuration['fab_line_width']))\n\n\n    # create silkscreen\n    fab_to_silk_offset = configuration['silk_fab_offset']\n    silk_x = kwargs['length'] / 2. + fab_to_silk_offset\n    silk_y = kwargs['width'] / 2. + fab_to_silk_offset\n    silk_y_start = kwargs['pad_width'] / 2. + configuration['silk_pad_clearance'] + configuration['silk_line_width']/2.\n    silk_45deg_offset = fab_to_silk_offset*math.tan(math.radians(22.5))\n    silk_x_edge = fab_x - fab_edge + silk_45deg_offset\n    silk_y_edge = fab_y - fab_edge + silk_45deg_offset\n\n    kicad_mod.append(Line(start=[silk_x, silk_y], end=[silk_x, silk_y_start], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[silk_x, -silk_y], end=[silk_x, -silk_y_start], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[-silk_x_edge, -silk_y], end=[silk_x, -silk_y], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[-silk_x_edge, silk_y], end=[silk_x, silk_y], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    if silk_y_edge > silk_y_start:\n        kicad_mod.append(Line(start=[-silk_x, silk_y_edge], end=[-silk_x, silk_y_start], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[-silk_x, -silk_y_edge], end=[-silk_x, -silk_y_start], layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Line(start=[-silk_x, -silk_y_edge], end=[-silk_x_edge, -silk_y], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[-silk_x, silk_y_edge], end=[-silk_x_edge, silk_y], layer='F.SilkS', width=configuration['silk_line_width']))\n    else:\n        silk_x_cut = silk_x - (silk_y_start - silk_y_edge) # because of the 45 degree edge we can user a simple apporach\n        silk_y_edge_cut = silk_y_start\n\n        kicad_mod.append(Line(start=[-silk_x_cut, -silk_y_edge_cut], end=[-silk_x_edge, -silk_y], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[-silk_x_cut, silk_y_edge_cut], end=[-silk_x_edge, silk_y], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #silk polarity marker\n    silk_pol_size = kwargs['diameter']/8.\n    silk_pol_wing = silk_pol_size/2.\n    silk_pol_pos_y = silk_y_start + silk_pol_size\n    silk_pol_pos_x = silk_x + silk_pol_wing + configuration['silk_line_width']*2\n    silk_pol_pos_x = -silk_pol_pos_x\n    silk_pol_pos_y = -silk_pol_pos_y\n    kicad_mod.append(Line(start=[silk_pol_pos_x-silk_pol_wing, silk_pol_pos_y], end=[silk_pol_pos_x+silk_pol_wing, silk_pol_pos_y], \n        layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[silk_pol_pos_x, silk_pol_pos_y-silk_pol_wing], end=[silk_pol_pos_x, silk_pol_pos_y+silk_pol_wing], \n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    # create courtyard\n    courtyard_offset = configuration['courtyard_offset']['default']\n    courtyard_x = kwargs['length'] / 2. + courtyard_offset\n    courtyard_y = kwargs['width'] / 2. + courtyard_offset\n    courtyard_pad_x = kwargs['pad_spacing'] / 2. + kwargs['pad_length'] + courtyard_offset\n    courtyard_pad_y = kwargs['pad_width'] / 2. + courtyard_offset\n    courtyard_45deg_offset = courtyard_offset*math.tan(math.radians(22.5))\n    courtyard_x_edge = fab_x - fab_edge + courtyard_45deg_offset\n    courtyard_y_edge = fab_y - fab_edge + courtyard_45deg_offset\n    courtyard_x_lower_edge = courtyard_x\n    if courtyard_y_edge < courtyard_pad_y:\n        courtyard_x_lower_edge = courtyard_x_lower_edge - courtyard_pad_y + courtyard_y_edge\n        courtyard_y_edge = courtyard_pad_y\n    #rounding\n    courtyard_x = float(format(courtyard_x, \".2f\"))\n    courtyard_y = float(format(courtyard_y, \".2f\"))\n    courtyard_pad_x = float(format(courtyard_pad_x, \".2f\"))\n    courtyard_pad_y = float(format(courtyard_pad_y, \".2f\"))\n    courtyard_x_edge = float(format(courtyard_x_edge, \".2f\"))\n    courtyard_y_edge = float(format(courtyard_y_edge, \".2f\"))\n    courtyard_x_lower_edge = float(format(courtyard_x_lower_edge, \".2f\"))\n\n    # drawing courtyard\n    kicad_mod.append(Line(start=[courtyard_x, -courtyard_y], end=[courtyard_x, -courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[courtyard_x, -courtyard_pad_y], end=[courtyard_pad_x, -courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[courtyard_pad_x, -courtyard_pad_y], end=[courtyard_pad_x, courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[courtyard_pad_x, courtyard_pad_y], end=[courtyard_x, courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[courtyard_x, courtyard_pad_y], end=[courtyard_x, courtyard_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    kicad_mod.append(Line(start=[-courtyard_x_edge, courtyard_y], end=[courtyard_x, courtyard_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[-courtyard_x_edge, -courtyard_y], end=[courtyard_x, -courtyard_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    if fab_edge > 0:\n        kicad_mod.append(Line(start=[-courtyard_x_lower_edge, courtyard_y_edge], end=[-courtyard_x_edge, courtyard_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n        kicad_mod.append(Line(start=[-courtyard_x_lower_edge, -courtyard_y_edge], end=[-courtyard_x_edge, -courtyard_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    if courtyard_y_edge > courtyard_pad_y:\n        kicad_mod.append(Line(start=[-courtyard_x, -courtyard_y_edge], end=[-courtyard_x, -courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n        kicad_mod.append(Line(start=[-courtyard_x, courtyard_pad_y], end=[-courtyard_x, courtyard_y_edge], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[-courtyard_x_lower_edge, -courtyard_pad_y], end=[-courtyard_pad_x, -courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[-courtyard_pad_x, -courtyard_pad_y], end=[-courtyard_pad_x, courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[-courtyard_pad_x, courtyard_pad_y], end=[-courtyard_x_lower_edge, courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    \n\n    # all pads have this kwargs, so we only write them once\n    pad_kwargs = {'type': Pad.TYPE_SMT,\n                  'shape': Pad.SHAPE_RECT,\n                  'layers': ['F.Cu', 'F.Mask', 'F.Paste']}\n\n    # create pads\n    x_pad_spacing = kwargs['pad_spacing'] / 2. + kwargs['pad_length'] / 2.\n    kicad_mod.append(Pad(number= 1, at=[-x_pad_spacing, 0],\n                         size=[kwargs['pad_length'], kwargs['pad_width']], **pad_kwargs))\n    kicad_mod.append(Pad(number= 2, at=[x_pad_spacing, 0],\n                         size=[kwargs['pad_length'], kwargs['pad_width']], **pad_kwargs))\n\n    lib_name ='Capacitor_SMD'\n    # add model\n    modelname = name.replace(\"_HandSoldering\", \"\")\n    kicad_mod.append(Model(filename=\"{model_prefix:s}{lib_name:s}.3dshapes/{name:s}.wrl\".format(model_prefix=configuration['3d_model_prefix'], lib_name=lib_name, name=modelname),\n                            at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n\n    # write file\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n\n    filename = '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=name)\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\n\ndef parse_and_execute_yml_file(filepath, configuration):\n    with open(filepath, 'r') as stream:\n        try:\n            yaml_parsed = yaml.safe_load(stream)\n            for footprint in yaml_parsed:\n                print(\"generate {name}.kicad_mod\".format(name=footprint))\n                create_footprint(footprint, configuration , **yaml_parsed.get(footprint))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='Parse *.kicad_mod.yml file(s) and create matching footprints')\n    parser.add_argument('files', metavar='file', type=str, nargs='+',\n                        help='yml-files to parse')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../tools/global_config_files/config_KLCv3.0.yaml')\n    #parser.add_argument('-v', '--verbose', help='show more information when creating footprint', action='store_true')\n    # TODO: allow writing into sub file\n    args = parser.parse_args()\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for filepath in args.files:\n        parse_and_execute_yml_file(filepath, configuration)\n"
  },
  {
    "path": "scripts/Capacitors_SMD/CP_Elec_round.yaml",
    "content": "#CP_Elec_6.3x5.8:\n#    body_length:\n#      nominal: 6.6\n#    body_width:\n#      nominal: 6.6\n#    body_height:\n#      nominal: 5.8\n#    body_diameter:\n#      nominal: 6.3\n#    pad_width: 1.9\n#    pin1_chamfer: 'auto'\n#    pad_length: 3.5\n#    pad_spacing: 1.6\n\n# https://industrial.panasonic.com/cdbs/www-data/pdf/AAB8000/AAB8000COL60.pdf # broken link\n# https://industrial.panasonic.com/cdbs/www-data/pdf/AAB8000/AAB8000COL10.pdf # pad sizes\n\n# https://www.vishay.com/docs/28395/150crz.pdf\n\n# http://www.nichicon.co.jp/english/products/pdfs/e-ch_ref.pdf # pad sizes\n# https://media.digikey.com/pdf/Data%20Sheets/Nichicon%20PDFs/ZD_Series.pdf\n# http://nichicon-us.com/english/products/pdfs/e-uzr.pdf\n# http://nichicon-us.com/english/products/pdfs/e-uzs.pdf\n# http://nichicon-us.com/english/products/pdfs/e-uwx.pdf\n\n# UCC, CDE, nor Rubycon datasheets are given above\n\n# 3x5.3\n\nCP_Elec_3x5.4:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 3.3\n    body_width:\n      nominal: 3.3\n    body_height:\n      nominal: 5.4\n    body_diameter:\n      nominal: 3.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 2.2\n    pad_spacing: 0.8\n\nCP_Elec_4x3:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 4.3\n    body_width:\n      nominal: 4.3\n    body_height:\n      nominal: 3\n    body_diameter:\n      nominal: 4.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 2.6\n    pad_spacing: 1\n\nCP_Elec_4x3.9:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 4.3\n    body_width:\n      nominal: 4.3\n    body_height:\n      nominal: 3.9\n    body_diameter:\n      nominal: 4.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 2.6\n    pad_spacing: 1\n\nCP_Elec_4x4.5:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 4.3\n    body_width:\n      nominal: 4.3\n    body_height:\n      nominal: 4.5\n    body_diameter:\n      nominal: 4.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 2.6\n    pad_spacing: 1\n\nCP_Elec_4x5.3:\n    extra_description: \"Vishay\"\n    body_length:\n      nominal: 4.3\n    body_width:\n      nominal: 4.3\n    body_height:\n      nominal: 5.3\n    body_diameter:\n      nominal: 4.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 2.6\n    pad_spacing: 1\n\nCP_Elec_4x5.4:\n    extra_description: \"Panasonic A5 / Nichicon\"\n    body_length:\n      nominal: 4.3\n    body_width:\n      nominal: 4.3\n    body_height:\n      nominal: 5.4\n    body_diameter:\n      nominal: 4.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 2.6\n    pad_spacing: 1\n\nCP_Elec_4x5.7:\n    extra_description: \"United Chemi-Con\"\n    body_length:\n      nominal: 4.3\n    body_width:\n      nominal: 4.3\n    body_height:\n      nominal: 5.7\n    body_diameter:\n      nominal: 4.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 2.6\n    pad_spacing: 1\n\nCP_Elec_4x5.8:\n    extra_description: \"Panasonic\"\n    body_length:\n      nominal: 4.3\n    body_width:\n      nominal: 4.3\n    body_height:\n      nominal: 5.8\n    body_diameter:\n      nominal: 4.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 2.6\n    pad_spacing: 1\n\nCP_Elec_5x3:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 5.3\n    body_width:\n      nominal: 5.3\n    body_height:\n      nominal: 3.0\n    body_diameter:\n      nominal: 5.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3\n    pad_spacing: 1.4\n\nCP_Elec_5x3.9:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 5.3\n    body_width:\n      nominal: 5.3\n    body_height:\n      nominal: 3.9\n    body_diameter:\n      nominal: 5.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3\n    pad_spacing: 1.4\n\nCP_Elec_5x4.4:\n    extra_description: \"Panasonic B45\"\n    body_length:\n      nominal: 5.3\n    body_width:\n      nominal: 5.3\n    body_height:\n      nominal: 4.4\n    body_diameter:\n      nominal: 5.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3\n    pad_spacing: 1.4\n\nCP_Elec_5x4.5:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 5.3\n    body_width:\n      nominal: 5.3\n    body_height:\n      nominal: 4.5\n    body_diameter:\n      nominal: 5.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3\n    pad_spacing: 1.4\n\nCP_Elec_5x5.3:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 5.3\n    body_width:\n      nominal: 5.3\n    body_height:\n      nominal: 5.3\n    body_diameter:\n      nominal: 5.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3\n    pad_spacing: 1.4\n\nCP_Elec_5x5.4:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 5.3\n    body_width:\n      nominal: 5.3\n    body_height:\n      nominal: 5.4\n    body_diameter:\n      nominal: 5.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3\n    pad_spacing: 1.4\n\nCP_Elec_5x5.7:\n    extra_description: \"United Chemi-Con\"\n    body_length:\n      nominal: 5.3\n    body_width:\n      nominal: 5.3\n    body_height:\n      nominal: 5.7\n    body_diameter:\n      nominal: 5.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3\n    pad_spacing: 1.4\n\nCP_Elec_5x5.8:\n    extra_description: \"Panasonic\"\n    body_length:\n      nominal: 5.3\n    body_width:\n      nominal: 5.3\n    body_height:\n      nominal: 5.8\n    body_diameter:\n      nominal: 5.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3\n    pad_spacing: 1.4\n\nCP_Elec_5x5.9:\n    extra_description: \"Panasonic B6\"\n    body_length:\n      nominal: 5.3\n    body_width:\n      nominal: 5.3\n    body_height:\n      nominal: 5.9\n    body_diameter:\n      nominal: 5.0\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3\n    pad_spacing: 1.4\n\nCP_Elec_6.3x3:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 3.0\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 1.9\n\nCP_Elec_6.3x3.9:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 3.9\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 1.9\n\nCP_Elec_6.3x4.5:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 4.5\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 1.9\n\nCP_Elec_6.3x4.9:\n    extra_description: \"Panasonic C5\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 4.9\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 2.1\n\nCP_Elec_6.3x5.2:\n    extra_description: \"United Chemi-Con\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 5.2\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 2.1\n\nCP_Elec_6.3x5.3:\n    extra_description: \"Cornell Dubilier\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 5.3\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 2.1\n\nCP_Elec_6.3x5.4:\n    extra_description: \"Panasonic C55\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 5.4\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 2.1\n\nCP_Elec_6.3x5.4_Nichicon:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 5.4\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 1.9\n\nCP_Elec_6.3x5.7:\n    extra_description: \"United Chemi-Con\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 5.7\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 1.9\n\nCP_Elec_6.3x5.8:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 5.8\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 1.9\n\nCP_Elec_6.3x5.9:\n    extra_description: \"Panasonic C6\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 5.9\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 2.1\n\nCP_Elec_6.3x7.7:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 7.7\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 1.9\n\nCP_Elec_6.3x9.9:\n    extra_description: \"Panasonic C10\"\n    body_length:\n      nominal: 6.6\n    body_width:\n      nominal: 6.6\n    body_height:\n      nominal: 9.9\n    body_diameter:\n      nominal: 6.3\n    pad_width: 1.6\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 2.1\n\nCP_Elec_8x5.4:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 8.3\n    body_width:\n      nominal: 8.3\n    body_height:\n      nominal: 5.4\n    body_diameter:\n      nominal: 8.0\n    pad_width: 2.5\n    pin1_chamfer: 'auto'\n    pad_length: 4\n    pad_spacing: 2.1\n\nCP_Elec_8x6.2:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 8.3\n    body_width:\n      nominal: 8.3\n    body_height:\n      nominal: 6.2\n    body_diameter:\n      nominal: 8.0\n    pad_width: 2.5\n    pin1_chamfer: 'auto'\n    pad_length: 4\n    pad_spacing: 2.1\n\nCP_Elec_8x6.5:\n    extra_description: \"Rubycon\"\n    body_length:\n      nominal: 8.3\n    body_width:\n      nominal: 8.3\n    body_height:\n      nominal: 6.5\n    body_diameter:\n      nominal: 8.0\n    pad_width: 2.5\n    pin1_chamfer: 'auto'\n    pad_length: 4\n    pad_spacing: 2.1\n\nCP_Elec_8x6.7:\n    extra_description: \"United Chemi-Con\"\n    body_length:\n      nominal: 8.3\n    body_width:\n      nominal: 8.3\n    body_height:\n      nominal: 6.7\n    body_diameter:\n      nominal: 8.0\n    pad_width: 2.5\n    pin1_chamfer: 'auto'\n    pad_length: 4\n    pad_spacing: 2.1\n\nCP_Elec_8x6.9:\n    extra_description: \"Panasonic E7\"\n    body_length:\n      nominal: 8.3\n    body_width:\n      nominal: 8.3\n    body_height:\n      nominal: 6.9\n    body_diameter:\n      nominal: 8.0\n    pad_width: 1.9\n    pin1_chamfer: 'auto'\n    pad_length: 4.15\n    pad_spacing: 2.8\n\nCP_Elec_8x10:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 8.3\n    body_width:\n      nominal: 8.3\n    body_height:\n      nominal: 10\n    body_diameter:\n      nominal: 8.0\n    pad_width: 2.5\n    pin1_chamfer: 'auto'\n    pad_length: 3.5\n    pad_spacing: 3\n\nCP_Elec_8x10.5:\n    extra_description: \"Vishay 0810\"\n    datasheet: \"http://www.vishay.com/docs/28395/150crz.pdf\"\n    body_length:\n      nominal: 8.5\n    body_width:\n      nominal: 8.5\n    body_height:\n      nominal: 10.5\n    body_diameter:\n      nominal: 8.0\n    pad_width: 2.5\n    pin1_chamfer: 'auto'\n    pad_length: 4.4\n    pad_spacing: 3.0\n\nCP_Elec_8x11.9:\n    extra_description: \"Panasonic E12\"\n    body_length:\n      nominal: 8.3\n    body_width:\n      nominal: 8.3\n    body_height:\n      nominal: 11.9\n    body_diameter:\n      nominal: 8.0\n    pad_width: 1.9\n    pin1_chamfer: 'auto'\n    pad_length: 4.15\n    pad_spacing: 2.8\n\nCP_Elec_10x7.7:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 10.3\n    body_width:\n      nominal: 10.3\n    body_height:\n      nominal: 7.7\n    body_diameter:\n      nominal: 10.0\n    pad_width: 1.9\n    pin1_chamfer: 'auto'\n    pad_length: 4.4\n    pad_spacing: 4.3\n\nCP_Elec_10x7.9:\n    extra_description: \"Panasonic F8\"\n    body_length:\n      nominal: 10.3\n    body_width:\n      nominal: 10.3\n    body_height:\n      nominal: 7.9\n    body_diameter:\n      nominal: 10.0\n    pad_width: 1.9\n    pin1_chamfer: 'auto'\n    pad_length: 4.4\n    pad_spacing: 4.3\n\nCP_Elec_10x10:\n    extra_description: \"Nichicon\"\n    body_length:\n      nominal: 10.3\n    body_width:\n      nominal: 10.3\n    body_height:\n      nominal: 10.0\n    body_diameter:\n      nominal: 10.0\n    pad_width: 2.5\n    pin1_chamfer: 'auto'\n    pad_length: 4\n    pad_spacing: 4\n\nCP_Elec_10x10.5:\n    extra_description: \"Vishay 1010\"\n    datasheet: \"http://www.vishay.com/docs/28395/150crz.pdf\"\n    body_length:\n      nominal: 10.5\n    body_width:\n      nominal: 10.5\n    body_height:\n      nominal: 10.5\n    body_diameter:\n      nominal: 10.0\n    pad_width: 2.5\n    pin1_chamfer: 'auto'\n    pad_length: 4.4\n    pad_spacing: 4.0\n\nCP_Elec_10x12.5:\n    extra_description: \"Vishay 1012\"\n    datasheet: \"http://www.vishay.com/docs/28395/150crz.pdf\"\n    body_length:\n      nominal: 10.5\n    body_width:\n      nominal: 10.5\n    body_height:\n      nominal: 12.5\n    body_diameter:\n      nominal: 10.0\n    pad_width: 2.5\n    pin1_chamfer: 'auto'\n    pad_length: 4.4\n    pad_spacing: 4.0\n\nCP_Elec_10x12.6:\n    extra_description: \"Panasonic F12\"\n    body_length:\n      nominal: 10.3\n    body_width:\n      nominal: 10.3\n    body_height:\n      nominal: 12.6\n    body_diameter:\n      nominal: 10.0\n    pad_width: 1.9\n    pin1_chamfer: 'auto'\n    pad_length: 4.4\n    pad_spacing: 4.3\n\nCP_Elec_10x14.3:\n    extra_description: \"Vishay 1014\"\n    datasheet: \"http://www.vishay.com/docs/28395/150crz.pdf\"\n    body_length:\n      nominal: 10.5\n    body_width:\n      nominal: 10.5\n    body_height:\n      nominal: 14.3\n    body_diameter:\n      nominal: 10.0\n    pad_width: 2.5\n    pin1_chamfer: 'auto'\n    pad_length: 4.4\n    pad_spacing: 4.0\n\n# TODO: Vishay 12.5x14\n# TODO: Vishay 12.5x16.5\n\nCP_Elec_16x17.5:\n    extra_description: \"Vishay 1616\"\n    datasheet: \"http://www.vishay.com/docs/28395/150crz.pdf\"\n    body_length:\n      nominal: 16.6\n    body_width:\n      nominal: 16.6\n    body_height:\n      nominal: 17.5\n    body_diameter:\n      nominal: 16.0\n    pad_width: 9.6\n    pin1_chamfer: 'auto'\n    pad_length: 7.8\n    pad_spacing: 4.7\n\nCP_Elec_16x22:\n    extra_description: \"Vishay 1621\"\n    datasheet: \"http://www.vishay.com/docs/28395/150crz.pdf\"\n    body_length:\n      nominal: 16.6\n    body_width:\n      nominal: 16.6\n    body_height:\n      nominal: 22.0\n    body_diameter:\n      nominal: 16.0\n    pad_width: 9.6\n    pin1_chamfer: 'auto'\n    pad_length: 7.8\n    pad_spacing: 4.7\n\nCP_Elec_18x17.5:\n    extra_description: \"Vishay 1816\"\n    datasheet: \"http://www.vishay.com/docs/28395/150crz.pdf\"\n    body_length:\n      nominal: 19.0\n    body_width:\n      nominal: 19.0\n    body_height:\n      nominal: 17.5\n    body_diameter:\n      nominal: 18.0\n    pad_width: 9.6\n    pin1_chamfer: 'auto'\n    pad_length: 8.8\n    pad_spacing: 4.7\n\nCP_Elec_18x22:\n    extra_description: \"Vishay 1821\"\n    datasheet: \"http://www.vishay.com/docs/28395/150crz.pdf\"\n    body_length:\n      nominal: 19.0\n    body_width:\n      nominal: 19.0\n    body_height:\n      nominal: 22.0\n    body_diameter:\n      nominal: 18.0\n    pad_width: 9.6\n    pin1_chamfer: 'auto'\n    pad_length: 8.8\n    pad_spacing: 4.7\n\n######################Panasonic\n#\n#CP_Panasonic_Standard_B:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 4.3\n#    width: 4.3\n#    height: 5.8\n#    diameter: 4.0\n#    pad_width: 1.6\n#    pin1_chamfer: 'auto'\n#    pad_length: 2.5\n#    pad_spacing: 1.0\n#\n#CP_Panasonic_Standard_B_HandSoldering:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 4.3\n#    width: 4.3\n#    height: 5.8\n#    diameter: 4.0\n#    pad_width: 1.6\n#    pin1_chamfer: 'auto'\n#    pad_length: 3.5\n#    pad_spacing: 1.0\n#\n#CP_Panasonic_Standard_C:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 5.3\n#    width: 5.3\n#    height: 5.8\n#    diameter: 5.0\n#    pad_width: 1.6\n#    pin1_chamfer: 'auto'\n#    pad_length: 2.8\n#    pad_spacing: 1.5\n#\n#CP_Panasonic_Standard_C_HandSoldering:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 5.3\n#    width: 5.3\n#    height: 5.8\n#    diameter: 5.0\n#    pad_width: 1.6\n#    pin1_chamfer: 'auto'\n#    pad_length: 3.8\n#    pad_spacing: 1.5\n#\n#CP_Panasonic_Standard_D:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 6.6\n#    width: 6.6\n#    height: 5.8\n#    diameter: 6.3\n#    pad_width: 1.6\n#    pin1_chamfer: 'auto'\n#    pad_length: 3.2\n#    pad_spacing: 1.8\n#\n#CP_Panasonic_Standard_D_HandSoldering:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 6.6\n#    width: 6.6\n#    height: 5.8\n#    diameter: 6.3\n#    pad_width: 1.6\n#    pin1_chamfer: 'auto'\n#    pad_length: 4.2\n#    pad_spacing: 1.8\n#\n#CP_Panasonic_Standard_E:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 8.3\n#    width: 8.3\n#    height: 6.2\n#    diameter: 8.0\n#    pad_width: 1.6\n#    pin1_chamfer: 'auto'\n#    pad_length: 4.0\n#    pad_spacing: 2.2\n#\n#CP_Panasonic_Standard_E_HandSoldering:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 8.3\n#    width: 8.3\n#    height: 6.2\n#    diameter: 8.0\n#    pad_width: 1.6\n#    pin1_chamfer: 'auto'\n#    pad_length: 5.0\n#    pad_spacing: 2.2\n#\n#CP_Panasonic_Standard_F:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 8.3\n#    width: 8.3\n#    height: 10.2\n#    diameter: 8.0\n#    pad_width: 2.0\n#    pin1_chamfer: 'auto'\n#    pad_length: 4.0\n#    pad_spacing: 3.1\n#\n#CP_Panasonic_Standard_F_HandSoldering:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 8.3\n#    width: 8.3\n#    height: 10.2\n#    diameter: 8.0\n#    pad_width: 2.0\n#    pin1_chamfer: 'auto'\n#    pad_length: 5.0\n#    pad_spacing: 3.1\n#\n#CP_Panasonic_Standard_G:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 10.3\n#    width: 10.3\n#    height: 10.2\n#    diameter: 10.0\n#    pad_width: 2.0\n#    pin1_chamfer: 'auto'\n#    pad_length: 4.1\n#    pad_spacing: 4.6\n#\n#CP_Panasonic_Standard_G_HandSoldering:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 10.3\n#    width: 10.3\n#    height: 10.2\n#    diameter: 10.0\n#    pad_width: 2.0\n#    pin1_chamfer: 'auto'\n#    pad_length: 5.1\n#    pad_spacing: 4.6\n#\n#CP_Panasonic_Standard_H:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 13.5\n#    width: 13.5\n#    height: 13.5\n#    diameter: 12.5\n#    pad_width: 2.0\n#    pin1_chamfer: 'auto'\n#    pad_length: 5.7\n#    pad_spacing: 4.0\n#\n#CP_Panasonic_Standard_H_HandSoldering:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 13.5\n#    width: 13.5\n#    height: 13.5\n#    diameter: 12.5\n#    pad_width: 2.0\n#    pin1_chamfer: 'auto'\n#    pad_length: 6.7\n#    pad_spacing: 4.0\n#\n#CP_Panasonic_Standard_J:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 17.0\n#    width: 17.0\n#    height: 16.5\n#    diameter: 16.0\n#    pad_width: 2.5\n#    pin1_chamfer: 'auto'\n#    pad_length: 6.5\n#    pad_spacing: 6.0\n#\n#CP_Panasonic_Standard_J_HandSoldering:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 17.0\n#    width: 17.0\n#    height: 16.5\n#    diameter: 16.0\n#    pad_width: 2.5\n#    pin1_chamfer: 'auto'\n#    pad_length: 7.5\n#    pad_spacing: 6.0\n#\n#CP_Panasonic_Standard_K:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 19.0\n#    width: 19.0\n#    height: 16.5\n#    diameter: 18.0\n#    pad_width: 2.5\n#    pin1_chamfer: 'auto'\n#    pad_length: 7.5\n#    pad_spacing: 6.0\n#\n#CP_Panasonic_Standard_K_HandSoldering:\n#    extra_description: \"Panasonic\"\n#    datasheet: \"https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/DME0000COL48.pdf\"\n#    length: 19.0\n#    width: 19.0\n#    height: 16.5\n#    diameter: 18.0\n#    pad_width: 2.5\n#    pin1_chamfer: 'auto'\n#    pad_length: 8.5\n#    pad_spacing: 6.0"
  },
  {
    "path": "scripts/Capacitors_SMD/C_Elec_round.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport argparse\nimport yaml\nimport math\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load parent path of KicadModTree\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"tools\"))  # load parent path of tools\nfrom ipc_pad_size_calculators import *\n\ndef create_footprint(name, configuration, **kwargs):\n    kicad_mod = Footprint(name)\n\n    # init kicad footprint\n    datasheet = \", \" + kwargs['datasheet'] if 'datasheet' in kwargs else \"\"\n    description = \"SMD capacitor, aluminum electrolytic\"\n    tags = 'capacitor electrolytic'\n    if name[:2] == \"C_\":\n        description += \" nonpolar\"\n        tags += \" nonpolar\"\n    if 'extra_description' in kwargs:\n        description += \", \" + kwargs['extra_description']\n\n    # ensure all provided dimensions are fully toleranced\n    device_dimensions = {\n        'body_length': TolerancedSize.fromYaml(kwargs, base_name='body_length'),\n        'body_width': TolerancedSize.fromYaml(kwargs, base_name='body_width'),\n        'body_height': TolerancedSize.fromYaml(kwargs, base_name='body_height'),\n        'body_diameter': TolerancedSize.fromYaml(kwargs, base_name='body_diameter')\n    }\n    \n    # for ease of use, capture nominal body and pad sizes\n    body_size = {\n        'length': device_dimensions['body_length'].nominal,\n        'width': device_dimensions['body_width'].nominal,\n        'height': device_dimensions['body_height'].nominal,\n        'diameter': device_dimensions['body_diameter'].nominal\n    }\n\n    description += \", \" + str(body_size['diameter']) + \"x\" + str(body_size['height']) + \"mm\"\n    kicad_mod.setDescription(description + datasheet)\n    kicad_mod.setTags(tags)\n    kicad_mod.setAttribute('smd')\n\n    # set general values\n    text_offset_y = body_size['width'] / 2.0 + configuration['courtyard_offset']['default'] + 0.8\n\n    #silkscreen REF**\n    silk_text_size = configuration['references'][0]['size']\n    silk_text_thickness = silk_text_size[0]*configuration['references'][0]['fontwidth']\n    kicad_mod.append(Text(type='reference', text='REF**', at=[0, -text_offset_y], layer='F.SilkS', size=[silk_text_size[0], silk_text_size[1]], thickness= silk_text_thickness))\n    #fab value\n    fab_text_size = configuration['values'][0]['size']\n    fab_text_thickness = fab_text_size[0]*configuration['values'][0]['fontwidth']\n    kicad_mod.append(Text(type='value', text=name, at=[0, text_offset_y], layer='F.Fab', size=[fab_text_size[0], fab_text_size[1]], thickness= fab_text_thickness))\n    #fab REF**\n    fab_text_size = body_size['diameter']/5.0\n    fab_text_size = min(fab_text_size, configuration['references'][1]['size_max'][0])\n    fab_text_size = max(fab_text_size, configuration['references'][1]['size_min'][0])\n    fab_text_thickness = fab_text_size*configuration['references'][1]['thickness_factor']\n    kicad_mod.append(Text(type='user', text='%R', at=[0, 0], layer='F.Fab', size=[fab_text_size, fab_text_size], thickness= fab_text_thickness))\n\n    # create pads\n    # all pads have these properties\n    pad_params = {'type': Pad.TYPE_SMT, 'layers': Pad.LAYERS_SMT, 'shape': Pad.SHAPE_RECT}\n    \n    # prefer IPC-7351C compliant rounded rectangle pads\n    if not configuration['force_rectangle_pads']:\n        pad_params['shape'] = Pad.SHAPE_ROUNDRECT\n        pad_params['radius_ratio'] = 0.25\n        pad_params['maximum_radius'] = 0.25\n\n    # prefer calculating pads from lead dimensions per IPC\n    # fall back to using pad sizes directly if necessary\n    if ('lead_length' in kwargs) and ('lead_width' in kwargs) and ('lead_spacing' in kwargs):\n        # gather IPC data (unique parameters for >= 10mm tall caps)\n        ipc_density_suffix = '' if body_size['height'] < 10 else '_10mm'\n        ipc_density = configuration['ipc_density']\n        ipc_data = ipc_defintions['ipc_spec_capae_crystal'][ipc_density + ipc_density_suffix]\n        ipc_round_base = ipc_defintions['ipc_spec_capae_crystal']['round_base']\n        \n        manf_tol = {\n            'F': configuration.get('manufacturing_tolerance', 0.1),\n            'P': configuration.get('placement_tolerance', 0.05)\n        }\n        \n        # # fully tolerance lead dimensions; leads are dimensioned like SOIC so use gullwing calculator\n        device_dimensions['lead_width'] = TolerancedSize.fromYaml(kwargs, base_name='lead_width')\n        device_dimensions['lead_spacing'] = TolerancedSize.fromYaml(kwargs, base_name='lead_spacing')\n        device_dimensions['lead_length'] = TolerancedSize.fromYaml(kwargs, base_name='lead_length')\n        device_dimensions['lead_outside'] = TolerancedSize(maximum =\n            device_dimensions['lead_spacing'].maximum +\n            device_dimensions.get('lead_length').maximum * 2,\n            minimum = device_dimensions['lead_spacing'].minimum +\n            device_dimensions.get('lead_length').minimum * 2)\n        \n        Gmin, Zmax, Xmax = ipc_gull_wing(ipc_data, ipc_round_base, manf_tol,\n                device_dimensions['lead_width'], device_dimensions['lead_outside'],\n                lead_len=device_dimensions.get('lead_length'))\n        \n        pad_params['size'] = [(Zmax - Gmin) / 2.0, Xmax]\n\n        x_pad_spacing = (Zmax + Gmin) / 4.0\n    elif ('pad_length' in kwargs) and ('pad_width' in kwargs) and ('pad_spacing' in kwargs):\n        x_pad_spacing = kwargs['pad_spacing'] / 2.0 + kwargs['pad_length'] / 2.0\n        pad_params['size'] = [kwargs['pad_length'], kwargs['pad_width']]\n    else:\n        raise KeyError(\"Provide all three 'pad' or 'lead' properties ('_spacing', '_length', and '_width')\")\n\n    kicad_mod.append(Pad(number=1, at=[-x_pad_spacing, 0], **pad_params))\n    kicad_mod.append(Pad(number=2, at=[x_pad_spacing, 0], **pad_params))\n    \n    # create fabrication layer\n    fab_x = body_size['length'] / 2.0\n    fab_y = body_size['width'] / 2.0\n\n    if kwargs['pin1_chamfer'] == 'auto':\n        fab_edge = min(fab_x/2.0, fab_y/2.0, configuration['fab_pin1_marker_length'])\n    else:\n        fab_edge = kwargs['pin1_chamfer']\n    fab_x_edge = fab_x - fab_edge\n    fab_y_edge = fab_y - fab_edge\n    kicad_mod.append(Line(start=[fab_x, -fab_y], end=[fab_x, fab_y], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Line(start=[-fab_x_edge, -fab_y], end=[fab_x, -fab_y], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Line(start=[-fab_x_edge, fab_y], end=[fab_x, fab_y], layer='F.Fab', width=configuration['fab_line_width']))\n    if fab_edge > 0:\n        kicad_mod.append(Line(start=[-fab_x, -fab_y_edge], end=[-fab_x, fab_y_edge], layer='F.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(Line(start=[-fab_x, -fab_y_edge], end=[-fab_x_edge, -fab_y], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Line(start=[-fab_x, fab_y_edge], end=[-fab_x_edge, fab_y], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Circle(center=[0, 0], radius=body_size['diameter']/2.0, layer='F.Fab', width=configuration['fab_line_width']))\n\n\n    #fab polarity marker for polarized caps\n    if name[:2].upper() == \"CP\":\n        fab_pol_size = body_size['diameter']/10.0\n        fab_pol_wing = fab_pol_size/2.0\n        fab_pol_distance = body_size['diameter']/2.0 - fab_pol_wing - configuration['fab_line_width']\n        fab_pol_pos_y = fab_text_size/2.0 + configuration['silk_pad_clearance'] + fab_pol_size\n        fab_pol_pos_x = math.sqrt(fab_pol_distance*fab_pol_distance-fab_pol_pos_y*fab_pol_pos_y)\n        fab_pol_pos_x = -fab_pol_pos_x\n        fab_pol_pos_y = -fab_pol_pos_y\n        kicad_mod.append(Line(start=[fab_pol_pos_x-fab_pol_wing, fab_pol_pos_y], end=[fab_pol_pos_x+fab_pol_wing, fab_pol_pos_y], \n            layer='F.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(Line(start=[fab_pol_pos_x, fab_pol_pos_y-fab_pol_wing], end=[fab_pol_pos_x, fab_pol_pos_y+fab_pol_wing], \n            layer='F.Fab', width=configuration['fab_line_width']))\n\n\n    # create silkscreen\n    fab_to_silk_offset = configuration['silk_fab_offset']\n    silk_x = body_size['length'] / 2.0 + fab_to_silk_offset\n    silk_y = body_size['width'] / 2.0 + fab_to_silk_offset\n    silk_y_start = pad_params['size'][1] / 2.0 + configuration['silk_pad_clearance'] + configuration['silk_line_width']/2.0\n    silk_45deg_offset = fab_to_silk_offset*math.tan(math.radians(22.5))\n    silk_x_edge = fab_x - fab_edge + silk_45deg_offset\n    silk_y_edge = fab_y - fab_edge + silk_45deg_offset\n\n    kicad_mod.append(Line(start=[silk_x, silk_y], end=[silk_x, silk_y_start], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[silk_x, -silk_y], end=[silk_x, -silk_y_start], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[-silk_x_edge, -silk_y], end=[silk_x, -silk_y], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[-silk_x_edge, silk_y], end=[silk_x, silk_y], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    if silk_y_edge > silk_y_start:\n        kicad_mod.append(Line(start=[-silk_x, silk_y_edge], end=[-silk_x, silk_y_start], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[-silk_x, -silk_y_edge], end=[-silk_x, -silk_y_start], layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Line(start=[-silk_x, -silk_y_edge], end=[-silk_x_edge, -silk_y], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[-silk_x, silk_y_edge], end=[-silk_x_edge, silk_y], layer='F.SilkS', width=configuration['silk_line_width']))\n    else:\n        silk_x_cut = silk_x - (silk_y_start - silk_y_edge) # because of the 45 degree edge we can user a simple apporach\n        silk_y_edge_cut = silk_y_start\n\n        kicad_mod.append(Line(start=[-silk_x_cut, -silk_y_edge_cut], end=[-silk_x_edge, -silk_y], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[-silk_x_cut, silk_y_edge_cut], end=[-silk_x_edge, silk_y], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #silk polarity marker\n    if name[:2].upper() == \"CP\":\n        silk_pol_size = body_size['diameter']/8.0\n        silk_pol_wing = silk_pol_size/2.0\n        silk_pol_pos_y = silk_y_start + silk_pol_size\n        silk_pol_pos_x = silk_x + silk_pol_wing + configuration['silk_line_width']*2\n        silk_pol_pos_x = -silk_pol_pos_x\n        silk_pol_pos_y = -silk_pol_pos_y\n        kicad_mod.append(Line(start=[silk_pol_pos_x-silk_pol_wing, silk_pol_pos_y], end=[silk_pol_pos_x+silk_pol_wing, silk_pol_pos_y], \n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[silk_pol_pos_x, silk_pol_pos_y-silk_pol_wing], end=[silk_pol_pos_x, silk_pol_pos_y+silk_pol_wing], \n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    # create courtyard\n    courtyard_offset = configuration['courtyard_offset']['default']\n    courtyard_x = body_size['length'] / 2.0 + courtyard_offset\n    courtyard_y = body_size['width'] / 2.0 + courtyard_offset\n    courtyard_pad_x = x_pad_spacing + pad_params['size'][0] / 2.0 + courtyard_offset\n    courtyard_pad_y = pad_params['size'][1] / 2.0 + courtyard_offset\n    courtyard_45deg_offset = courtyard_offset*math.tan(math.radians(22.5))\n    courtyard_x_edge = fab_x - fab_edge + courtyard_45deg_offset\n    courtyard_y_edge = fab_y - fab_edge + courtyard_45deg_offset\n    courtyard_x_lower_edge = courtyard_x\n    if courtyard_y_edge < courtyard_pad_y:\n        courtyard_x_lower_edge = courtyard_x_lower_edge - courtyard_pad_y + courtyard_y_edge\n        courtyard_y_edge = courtyard_pad_y\n    #rounding\n    courtyard_x = float(format(courtyard_x, \".2f\"))\n    courtyard_y = float(format(courtyard_y, \".2f\"))\n    courtyard_pad_x = float(format(courtyard_pad_x, \".2f\"))\n    courtyard_pad_y = float(format(courtyard_pad_y, \".2f\"))\n    courtyard_x_edge = float(format(courtyard_x_edge, \".2f\"))\n    courtyard_y_edge = float(format(courtyard_y_edge, \".2f\"))\n    courtyard_x_lower_edge = float(format(courtyard_x_lower_edge, \".2f\"))\n\n    # drawing courtyard\n    kicad_mod.append(Line(start=[courtyard_x, -courtyard_y], end=[courtyard_x, -courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[courtyard_x, -courtyard_pad_y], end=[courtyard_pad_x, -courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[courtyard_pad_x, -courtyard_pad_y], end=[courtyard_pad_x, courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[courtyard_pad_x, courtyard_pad_y], end=[courtyard_x, courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[courtyard_x, courtyard_pad_y], end=[courtyard_x, courtyard_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    kicad_mod.append(Line(start=[-courtyard_x_edge, courtyard_y], end=[courtyard_x, courtyard_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[-courtyard_x_edge, -courtyard_y], end=[courtyard_x, -courtyard_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    if fab_edge > 0:\n        kicad_mod.append(Line(start=[-courtyard_x_lower_edge, courtyard_y_edge], end=[-courtyard_x_edge, courtyard_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n        kicad_mod.append(Line(start=[-courtyard_x_lower_edge, -courtyard_y_edge], end=[-courtyard_x_edge, -courtyard_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    if courtyard_y_edge > courtyard_pad_y:\n        kicad_mod.append(Line(start=[-courtyard_x, -courtyard_y_edge], end=[-courtyard_x, -courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n        kicad_mod.append(Line(start=[-courtyard_x, courtyard_pad_y], end=[-courtyard_x, courtyard_y_edge], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[-courtyard_x_lower_edge, -courtyard_pad_y], end=[-courtyard_pad_x, -courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[-courtyard_pad_x, -courtyard_pad_y], end=[-courtyard_pad_x, courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(Line(start=[-courtyard_pad_x, courtyard_pad_y], end=[-courtyard_x_lower_edge, courtyard_pad_y], layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    lib_name ='Capacitor_SMD'\n    # add model\n    modelname = name.replace(\"_HandSoldering\", \"\")\n    kicad_mod.append(Model(filename=\"{model_prefix:s}{lib_name:s}.3dshapes/{name:s}.wrl\".format(model_prefix=configuration['3d_model_prefix'], lib_name=lib_name, name=modelname),\n                            at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n\n    # write file\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n\n    filename = '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=name)\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='Parse *.kicad_mod.yml file(s) and create matching footprints')\n    parser.add_argument('files', metavar='file', type=str, nargs='+', help='yml-files to parse')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../SMD_chip_package_rlc-etc/config_KLCv3.0.yaml')\n    parser.add_argument('--ipc_definition', type=str, nargs='?', help='the IPC definition file', default='ipc7351B_capae_crystal.yaml')\n    parser.add_argument('--ipc_density', type=str, nargs='?', help='the IPC desnity', default='nominal')\n    parser.add_argument('--force_rectangle_pads', action='store_true', help='Force the generation of rectangle pads instead of rounded rectangle (KiCad 4.x compatibility.)')\n    #parser.add_argument('-v', '--verbose', help='show more information when creating footprint', action='store_true')\n    # TODO: allow writing into sub file\n    \n    args = parser.parse_args()\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n    \n    ipc_doc = args.ipc_definition\n    with open(ipc_doc, 'r') as ipc_stream:\n        try:\n            ipc_defintions = yaml.safe_load(ipc_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['ipc_density'] = args.ipc_density\n    configuration['force_rectangle_pads'] = args.force_rectangle_pads\n    \n    for filepath in args.files:\n        with open(filepath, 'r') as stream:\n            try:\n                yaml_parsed = yaml.safe_load(stream)\n                for footprint in yaml_parsed:\n                    print(\"generate {name}.kicad_mod\".format(name=footprint))\n                    create_footprint(footprint, configuration , **yaml_parsed.get(footprint))\n            except yaml.YAMLError as exc:\n                print(exc)\n"
  },
  {
    "path": "scripts/Capacitors_SMD/C_Elec_round.yaml",
    "content": "# http://nichicon-us.com/english/products/pdfs/e-uup.pdf\n# http://nichicon-us.com/english/products/pdfs/e-uwp.pdf\n# https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/ABA0000C1145.pdf\n# https://media.digikey.com/pdf/Data%20Sheets/Panasonic%20Electronic%20Components/S_Series_Type_V_.pdf\n# https://industrial.panasonic.com/cdbs/www-data/pdf/RDE0000/ABA0000C1157.pdf\n\n# Note: KLC puts pin 1 to the left so body_length is across the pins (horizontal)\n\n# Note: Due to minor variations in lead dimension for the same body size,\n# given dimensions are the greatest of all common body sizes in the datasheets\n# above. This may result in slightly more paste than if the lead size was\n# specific to one vendor's datasheet dimensions. However, as the lead sizes are\n# already large, lead-to-PCB coplanarity is quite varaible, and the capacitor\n# body does not sit flush with the PCB, the amount of paste is not extremely\n# critical. Pads a few tenths of a millimeter bigger or smaller than ideal\n# won't affect solderability or reliability.\n\nC_Elec_3x5.4:\n    body_length:\n      nominal: 3.3\n      tolerance: 0.2\n    body_width:\n      nominal: 3.3\n      tolerance: 0.2\n    body_height:\n      nominal: 5.4\n    body_diameter:\n      nominal: 3.0\n    lead_width:\n      minimum: 0.45\n      maximum: 0.65\n    lead_length:\n      nominal: 1.5\n      tolerance: 0.2\n    lead_spacing:\n      nominal: 0.6\n    pin1_chamfer: 'auto'\n\nC_Elec_4x5.4:\n    body_length:\n      nominal: 4.3\n      tolerance: 0.2\n    body_width:\n      nominal: 4.3\n      tolerance: 0.2\n    body_height:\n      nominal: 5.4\n    body_diameter:\n      nominal: 4.0\n    lead_width:\n      minimum: 0.5\n      maximum: 0.8\n    lead_length:\n      nominal: 1.8\n      tolerance: 0.2\n    lead_spacing:\n      nominal: 1.0\n    pin1_chamfer: 'auto'\n\nC_Elec_4x5.8:\n    body_length:\n      nominal: 4.3\n      tolerance: 0.2\n    body_width:\n      nominal: 4.3\n      tolerance: 0.2\n    body_height:\n      nominal: 5.8\n    body_diameter:\n      nominal: 4.0\n    lead_width:\n      minimum: 0.5\n      maximum: 0.8\n    lead_length:\n      nominal: 1.8\n      tolerance: 0.2\n    lead_spacing:\n      nominal: 1.0\n    pin1_chamfer: 'auto'\n\nC_Elec_5x5.4:\n    body_length:\n      nominal: 5.3\n      tolerance: 0.2\n    body_width:\n      nominal: 5.3\n      tolerance: 0.2\n    body_height:\n      nominal: 5.4\n    body_diameter:\n      nominal: 5.0\n    lead_width:\n      minimum: 0.5\n      maximum: 0.8\n    lead_length:\n      minimum: 2.1\n      maximum: 2.2\n    lead_spacing:\n      minimum: 1.3\n      maximum: 1.5\n    pin1_chamfer: 'auto'\n\nC_Elec_5x5.8:\n    body_length:\n      nominal: 5.3\n      tolerance: 0.2\n    body_width:\n      nominal: 5.3\n      tolerance: 0.2\n    body_height:\n      nominal: 5.8\n    body_diameter:\n      nominal: 5.0\n    lead_width:\n      minimum: 0.5\n      maximum: 0.8\n    lead_length:\n      minimum: 2.1\n      maximum: 2.2\n    lead_spacing:\n      minimum: 1.3\n      maximum: 1.5\n    pin1_chamfer: 'auto'\n    \nC_Elec_6.3x5.4:\n    body_length:\n      nominal: 6.6\n      tolerance: 0.2\n    body_width:\n      nominal: 6.6\n      tolerance: 0.2\n    body_height:\n      nominal: 5.4\n    body_diameter:\n      nominal: 6.3\n    lead_width:\n      minimum: 0.5\n      maximum: 0.8\n    lead_length:\n      minimum: 2.4\n      maximum: 2.6\n    lead_spacing:\n      minimum: 1.8\n      maximum: 2.2\n    pin1_chamfer: 'auto'\n\nC_Elec_6.3x5.8:\n    body_length:\n      nominal: 6.6\n      tolerance: 0.2\n    body_width:\n      nominal: 6.6\n      tolerance: 0.2\n    body_height:\n      nominal: 5.8\n    body_diameter:\n      nominal: 6.3\n    lead_width:\n      minimum: 0.5\n      maximum: 0.8\n    lead_length:\n      minimum: 2.4\n      maximum: 2.6\n    lead_spacing:\n      minimum: 1.8\n      maximum: 2.2\n    pin1_chamfer: 'auto'\n\nC_Elec_6.3x7.7:\n    body_length:\n      nominal: 6.6\n      tolerance: 0.2\n    body_width:\n      nominal: 6.6\n      tolerance: 0.2\n    body_height:\n      nominal: 7.7\n    body_diameter:\n      nominal: 6.3\n    lead_width:\n      minimum: 0.5\n      maximum: 0.8\n    lead_length:\n      minimum: 2.4\n      maximum: 2.6\n    lead_spacing:\n      minimum: 1.8\n      maximum: 2.2\n    pin1_chamfer: 'auto'\n\nC_Elec_8x5.4:\n    body_length:\n      nominal: 8.3\n      tolerance: 0.2\n    body_width:\n      nominal: 8.3\n      tolerance: 0.2\n    body_height:\n      nominal: 5.4\n    body_diameter:\n      nominal: 8.0\n    lead_width:\n      minimum: 0.5\n      maximum: 0.8\n    lead_length:\n      minimum: 3.3\n      maximum: 3.4\n    lead_spacing:\n      minimum: 2.2\n      maximum: 2.3\n    pin1_chamfer: 'auto'\n\nC_Elec_8x6.2:\n    body_length:\n      nominal: 8.3\n      tolerance: 0.2\n    body_width:\n      nominal: 8.3\n      tolerance: 0.2\n    body_height:\n      nominal: 6.2\n    body_diameter:\n      nominal: 8.0\n    lead_width:\n      minimum: 0.5\n      maximum: 0.8\n    lead_length:\n      minimum: 3.3\n      maximum: 3.4\n    lead_spacing:\n      minimum: 2.2\n      maximum: 2.3\n    pin1_chamfer: 'auto'\n\nC_Elec_8x10.2:\n    body_length:\n      nominal: 8.3\n      tolerance: 0.2\n    body_width:\n      nominal: 8.3\n      tolerance: 0.2\n    body_height:\n      nominal: 10.2\n    body_diameter:\n      nominal: 8.0\n    lead_width:\n      minimum: 0.7\n      maximum: 1.1\n    lead_length:\n      nominal: 3.4\n      tolerance: 0.2\n    lead_spacing:\n      nominal: 3.1\n    pin1_chamfer: 'auto'\n\nC_Elec_10x10.2:\n    body_length:\n      nominal: 10.3\n      tolerance: 0.2\n    body_width:\n      nominal: 10.3\n      tolerance: 0.2\n    body_height:\n      nominal: 10.2\n    body_diameter:\n      nominal: 10.0\n    lead_width:\n      minimum: 0.7\n      maximum: 1.1\n    lead_length:\n      nominal: 3.5\n      tolerance: 0.2\n    lead_spacing:\n      nominal: 4.6\n    pin1_chamfer: 'auto'\n"
  },
  {
    "path": "scripts/Capacitors_SMD/C_Trimmer_config.yaml",
    "content": "# SMD trimmer capacitors STYLE A\nbase:\n    family: STYLE-A\n    description: 'trimmer capacitor SMD horizontal'\n    keywords: ''\n    device:\n        body:\n            colour: 'white body'\n        frame:\n            colour: 'metal grey pins'\n        contacts:\n            colour: 'metal grey pins'\n        cover:\n           colour: 'white body'\n        rotor:\n           colour: 'white body'\n    3d_prefix: '${KISYS3DMOD}/Capacitors_SMD.3dshapes'\nvariants:\n    - series: TZR1\n      manufacturer: Murata\n      footprint:\n          x_mm: 2.2\n          pad:\n              x_mm: 0.5\n              y_mm: 0.5\n      device:\n          body:\n              x_mm: 1.7\n              y_mm: 1.4\n          chamfer:\n              sides: []\n              size_mm: 0.0\n          projection: \n              sides: ['top', 'bottom', 'right']\n              offset_mm: 0.1\n              x_side_mm: 0.9\n              y_side_mm: 0.6\n      keywords: 'Murata TZR1'\n      datasheet: http://www.murata.com/~/media/webrenewal/support/library/catalog/products/capacitor/trimmer/t13e.ashx?la=en-gb\n    - series: TZY2\n      manufacturer: Murata\n      footprint:\n          x_mm: 4.0\n          pad:\n              x_mm: 0.8\n              y_mm: 1.2\n      device:\n          body:\n              x_mm: 3.0\n              y_mm: 2.1\n          chamfer:\n              sides: []\n              size_mm: 0.0\n          projection: \n              sides: ['top', 'bottom', 'right']\n              offset_mm: 0.2\n              x_side_mm: 1.8              \n              y_side_mm: 1.0\n      keywords: 'Murata TZY2'\n      datasheet: http://www.murata.com/~/media/webrenewal/support/library/catalog/products/capacitor/trimmer/t13e.ashx?la=en-gb\n    - series: TZW4\n      manufacturer: Murata\n      footprint:\n          x_mm: 7.0\n          pad:\n              x_mm: 1.3\n              y_mm: 2.5\n      device:\n          body:\n              x_mm: 5.2\n              y_mm: 4.0\n          chamfer:\n              sides: []\n              size_mm: 0.0\n          projection: \n              sides: ['top', 'bottom']\n              offset_mm: 0.1\n              x_side_mm: 3.0\n              y_side_mm: 0.0\n      keywords: 'Murata TZW4'\n      datasheet: http://www.murata.com/~/media/webrenewal/support/library/catalog/products/capacitor/trimmer/t13e.ashx?la=en-gb\n    - series: JR\n      manufacturer: Voltronics\n      footprint:\n          x_mm: 4.4\n          pad:\n              x_mm: 1.0\n              y_mm: 1.8\n      device:\n          body:\n              x_mm: 3.5\n              y_mm: 3.1\n          chamfer:\n              sides: ['left']\n              size_mm: 0.6\n          projection: \n              sides: ['right']\n              offset_mm: 0.4\n              x_side_mm: 0.0\n              y_side_mm: 1.6\n      keywords: 'Voltronics JR'\n      datasheet: http://www.knowlescapacitors.com/File%20Library/Voltronics/English/GlobalNavigation/Products/Trimmer%20Capacitors/CerChipTrimCap.pdf\n    - series: JN\n      manufacturer: Voltronics\n      footprint:\n          x_mm: 2.2\n          pad:\n              x_mm: 0.5\n              y_mm: 0.5\n      device:\n          body:\n              x_mm: 1.7\n              y_mm: 1.4\n          chamfer:\n              sides: []\n              size_mm: 0.0\n          projection: \n              sides: ['top', 'bottom', 'right']\n              offset_mm: 0.1\n              x_side_mm: 0.9\n              y_side_mm: 0.6\n      keywords: 'Voltronics JN'\n      datasheet: http://www.knowlescapacitors.com/File%20Library/Voltronics/English/GlobalNavigation/Products/Trimmer%20Capacitors/CerChipTrimCap.pdf\n    - series: JV\n      manufacturer: Voltronics\n      footprint:\n          x_mm: 4.0\n          pad:\n              x_mm: 0.8\n              y_mm: 1.2\n      device:\n          body:\n              x_mm: 3.0\n              y_mm: 2.1\n          chamfer:\n              sides: []\n              size_mm: 0.0\n          projection: \n              sides: ['top', 'bottom', 'right']\n              offset_mm: 0.2\n              x_side_mm: 1.8              \n              y_side_mm: 1.0\n      keywords: 'Voltronics JV'\n      datasheet: http://www.knowlescapacitors.com/File%20Library/Voltronics/English/GlobalNavigation/Products/Trimmer%20Capacitors/CerChipTrimCap.pdf\n    - series: JQ\n      manufacturer: Voltronics\n      footprint:\n          x_mm: 3.2\n          pad:\n              x_mm: 0.55\n              y_mm: 1.0\n      device:\n          body:\n              x_mm: 2.5\n              y_mm: 1.8\n          chamfer:\n              sides: []\n              size_mm: 0.0\n          projection: \n              sides: ['top', 'bottom', 'right']\n              offset_mm: 0.2\n              x_side_mm: 1.5            \n              y_side_mm: 1.0\n      keywords: 'Voltronics JQ'\n      datasheet: http://www.knowlescapacitors.com/File%20Library/Voltronics/English/GlobalNavigation/Products/Trimmer%20Capacitors/CerChipTrimCap.pdf\n---\n# SMD trimmer capacitors STYLE B\nbase:\n    family: STYLE-B\n    description: 'trimmer capacitor SMD horizontal'\n    keywords: ''\n    device:\n        body:\n            colour: 'white body'\n        frame:\n            colour: 'metal grey pins'\n        contacts:\n            colour: 'metal grey pins'\n        cover:\n           colour: 'white body'\n        rotor:\n           colour: 'white body'\n    3d_prefix: '${KISYS3DMOD}/Capacitors_SMD.3dshapes'\nvariants:\n    - series: TZC3\n      manufacturer: Murata\n      footprint:\n          x_mm: 5.0\n          pad:\n              x_mm: 0.85\n              y_mm: 1.0\n      device:\n          body:\n              x_mm: 4.5\n              y_mm: 3.2\n          chamfer:\n              sides: ['left']\n              size_mm: 0.6\n          projection: \n              sides: []\n              offset_mm:\n              x_side_mm:\n              y_side_mm:\n      keywords: 'Murata TZC3'\n      datasheet: http://www.murata.com/~/media/webrenewal/support/library/catalog/products/capacitor/trimmer/t13e.ashx?la=en-gb\n---\n# SMD trimmer capacitors STYLE C\nbase:\n    family: STYLE-C\n    description: 'trimmer capacitor SMD horizontal'\n    keywords: ''\n    device:\n        body:\n            colour: 'white body'\n        frame:\n            colour: 'metal grey pins'\n        contacts:\n            colour: 'metal grey pins'\n        cover:\n           colour: 'white body'\n        rotor:\n           colour: 'white body'\n    3d_prefix: '${KISYS3DMOD}/Capacitors_SMD.3dshapes'\nvariants:\n    - series: JZ\n      manufacturer: Voltronics\n      footprint:\n          x_mm: 4.8\n          pad:\n              x_mm: 0.9\n              y_mm: 1.4\n      device:\n          body:\n              x_mm: 4.5\n              y_mm: 3.2\n          chamfer:\n              sides: ['left']\n              size_mm: 0.6\n          projection: \n              sides: []\n              offset_mm:\n              x_side_mm:\n              y_side_mm:\n      keywords: 'Voltronics JR'\n      datasheet: http://www.knowlescapacitors.com/File%20Library/Voltronics/English/GlobalNavigation/Products/Trimmer%20Capacitors/CerChipTrimCap.pdf\n    - series: SGC3\n      manufacturer: Sprague-Goodman\n      footprint:\n          x_mm: 4.75\n          pad:\n              x_mm: 1.075\n              y_mm: 1.4\n      device:\n          body:\n              x_mm: 4.5\n              y_mm: 3.2\n          chamfer:\n              sides: ['left']\n              size_mm: 0.6\n          projection: \n              sides: []\n              offset_mm:\n              x_side_mm:\n              y_side_mm:\n      keywords: 'Sprague Goodman SGC3'\n      datasheet: http://media.wix.com/ugd/d86717_38d9821e12823a7aa9cef38c6c2a73cc.pdf\n---\n# SMD trimmer capacitors STYLE D\nbase:\n    family: STYLE-D\n    description: 'trimmer capacitor SMD horizontal'\n    keywords: ''\n    device:\n        body:\n            colour: 'white body'\n        frame:\n            colour: 'metal grey pins'\n        contacts:\n            colour: 'metal grey pins'\n        cover:\n           colour: 'white body'\n        rotor:\n           colour: 'white body'\n    3d_prefix: '${KISYS3DMOD}/Capacitors_SMD.3dshapes'\nvariants:\n    - series: TZB4-A\n      manufacturer: Murata\n      footprint:\n          x_mm: 7.0\n          pad:\n              x_mm: 2.3\n              y_mm: 1.6\n      device:\n          body:\n              x_mm: 4.5\n              y_mm: 4.0\n          chamfer:\n              sides: []\n              size_mm:\n          projection: \n              sides: ['left', 'right']\n              offset_mm: 0.25\n              x_side_mm:\n              y_side_mm: 1.2\n      keywords: 'Murata TZB4 TZB4-A'\n      datasheet: http://www.murata.com/~/media/webrenewal/support/library/catalog/products/capacitor/trimmer/t13e.ashx?la=en-gb\n    - series: TZB4-B\n      manufacturer: Murata\n      footprint:\n          x_mm: 8.0\n          pad:\n              x_mm: 2.0\n              y_mm: 1.6\n      device:\n          body:\n              x_mm: 4.5\n              y_mm: 4.0\n          chamfer:\n              sides: []\n              size_mm:\n          projection: \n              sides: ['left', 'right']\n              offset_mm: 1.25\n              x_side_mm:\n              y_side_mm: 1.2\n      keywords: 'Murata TZB4 TZB4-A'\n      datasheet: http://www.murata.com/~/media/webrenewal/support/library/catalog/products/capacitor/trimmer/t13e.ashx?la=en-gb\n---\n\n"
  },
  {
    "path": "scripts/Capacitors_SMD/C_Trimmer_factory.py",
    "content": "import sys\nimport os\nimport argparse\nimport yaml\nimport pprint\n\nsys.path.append(os.path.join(sys.path[0], \"../..\"))  # enable package import from parent directory\n\nfrom KicadModTree import *  # NOQA\nfrom bump import *\nfrom corners import *\nfrom chamfers import *\n\n\nclass Dimensions(object):\n\n    def __init__(self, base, variant, cut_pin=False, tab_linked=False):\n\n        footprint = variant['footprint']\n        device = variant['device']\n\n        # FROM KLC\n        self.fab_line_width_mm = 0.1\n        self.fab_text_size = [1.0, 1.0]\n        self.fab_text_thickness = 0.15\n        self.fab_reference_text_size = [0.5, 0.5]\n        self.fab_reference_text_thickness = 0.05\n        self.silk_line_width_mm = 0.12\n        self.silk_text_size = [1.0, 1.0]\n        self.silk_text_thickness = 0.15\n        self.courtyard_line_width_mm = 0.05\n        self.courtyard_clearance_mm = 0.25\n        self.courtyard_precision_mm = 0.01\n\n        # NAME\n        self.name = self._footprint_name(variant['manufacturer'], variant['series'])\n\n        # PADS\n        self.pad_offset_x_mm = (footprint['pad']['x_mm'] - footprint['x_mm']) / 2.0\n\n        # FAB OUTLINE\n        self.device_offset_x_mm = device['body']['x_mm'] / 2.0  # x coordinate of RHS of device\n        self.body_x_mm = device['body']['x_mm']\n        self.body_offset_y_mm = device['body']['y_mm'] / 2.0  # y coordinate of bottom of body\n        \n        # COURTYARD\n        self.biggest_x_mm = footprint['x_mm']\n        self.biggest_y_mm = device['body']['y_mm']\n        if 'top' in device['projection']['sides'] or 'bottom' in device['projection']['sides']:\n             self.biggest_y_mm += 2.0 * device['projection']['offset_mm']\n        self.courtyard_offset_x_mm = self._round_to(self.courtyard_clearance_mm + self.biggest_x_mm / 2.0,\n                                                   self.courtyard_precision_mm)\n        self.courtyard_offset_y_mm = self._round_to(self.courtyard_clearance_mm + self.biggest_y_mm / 2.0,\n                                                   self.courtyard_precision_mm)\n        # SILKSCREEN\n        self.label_centre_x_mm = 0\n        self.label_centre_y_mm = self.courtyard_offset_y_mm + 1\n        self.silk_offset_mm = (0.2, 0.2)  #  amount to shift silkscreen in X and Y directions to avoid overlapping fab lines\n\n\n    def _round_to(self, n, precision):\n        correction = 0.5 if n >= 0 else -0.5\n        return int(n / precision + correction) * precision\n\n\n    def _footprint_name(self, manufacturer, series):\n        name = 'C_Trimmer_{m:s}_{s:s}'.format(m=manufacturer, s=series)\n        return name\n\n\nclass CapacitorTrimmer(object):\n\n    def __init__(self, config_file):\n        self.FAMILY = None\n        self.config = None\n\n\n    def _load_config(self, config_file):\n        try:\n            devices = yaml.safe_load_all(open(config_file))\n        except FileNotFoundError as fnfe:\n            print(fnfe)\n            return\n        config = None\n        for dev in devices:\n            if dev['base']['family'] == self.FAMILY:\n                config = dev\n                break\n        return config\n\n\n    def _add_properties(self, m, variant):\n        m.setDescription('{bd:s}, {vd:s}'.format(bd=self.config['base']['description'], vd=variant['datasheet']))\n        m.setTags('{bk:s} {vk:s}'.format(bk=self.config['base']['keywords'], vk=variant['keywords']))\n        m.setAttribute('smd')\n        return m\n\n\n    def _add_labels(self, m, variant, dim):\n        m.append(Text(type='reference', text='REF**', size=dim.silk_text_size, thickness=dim.silk_text_thickness, at=[dim.label_centre_x_mm, -dim.label_centre_y_mm],\n                      layer='F.SilkS'))\n        m.append(Text(type='user', text='%R', size=dim.fab_reference_text_size, thickness=dim.fab_reference_text_thickness, at=[0, 0], layer='F.Fab'))\n        m.append(Text(type='value', text=dim.name, size=dim.fab_text_size, thickness=dim.fab_text_thickness, at=[dim.label_centre_x_mm, dim.label_centre_y_mm], layer='F.Fab'))\n        return m\n\n\n    def _draw_pads(self, m, variant, dim):\n        m.append(Pad(number=1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                             at=[dim.pad_offset_x_mm, 0],\n                             size=[variant['footprint']['pad']['x_mm'], variant['footprint']['pad']['y_mm']],\n                             layers=Pad.LAYERS_SMT))\n        m.append(Pad(number=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                             at=[-dim.pad_offset_x_mm, 0],\n                             size=[variant['footprint']['pad']['x_mm'], variant['footprint']['pad']['y_mm']],\n                             layers=Pad.LAYERS_SMT))\n        return m\n\n\n    def _draw_fab_outline(self, m, variant, dim, width, offset):\n        # draw body\n        right_x = dim.device_offset_x_mm\n        left_x = right_x - dim.body_x_mm\n        top_y = -dim.body_offset_y_mm\n        bottom_y = -top_y\n        if 'left' in variant['device']['chamfer']['sides']:\n            chamfers = [{'corner': 'topleft', 'size': variant['device']['chamfer']['size_mm']}, \n                        {'corner': 'bottomleft', 'size': variant['device']['chamfer']['size_mm']}]\n        elif 'right' in variant['device']['chamfer']['sides']:\n            chamfers = [{'corner': 'topright', 'size': variant['device']['chamfer']['size_mm']}, \n                        {'corner': 'bottomright', 'size': variant['device']['chamfer']['size_mm']}]\n        else:\n            chamfers = []\n        m = add_rect_chamfer(m, [left_x, top_y], [right_x, bottom_y], 'F.Fab', width, offset, chamfers)\n        m.append(Circle(center=[0, 0], radius=dim.body_offset_y_mm, layer='F.Fab', width=width))\n        # add frame extensions\n        p = variant['device']['projection']\n        if 'top' in p['sides']:\n            m = add_bump(m, [0, top_y], p['x_side_mm'], p['offset_mm'], 'up', 'F.Fab', width, offset)\n        if 'bottom' in p['sides']:\n            m = add_bump(m, [0, bottom_y], p['x_side_mm'], p['offset_mm'], 'down', 'F.Fab', width, offset)\n        if 'right' in p['sides']:\n            m = add_bump(m, [right_x, 0], p['y_side_mm'], p['offset_mm'], 'right', 'F.Fab', width, offset)\n        if 'left' in p['sides']:\n            m = add_bump(m, [left_x, 0], p['y_side_mm'], p['offset_mm'], 'left', 'F.Fab', width, offset)\n        return m\n\n\n    def _draw_silk_outline(self, m, variant, dim, width, offset):\n        right_x = dim.device_offset_x_mm\n        left_x = right_x - dim.body_x_mm\n        top_y = -dim.body_offset_y_mm\n        bottom_y = -top_y\n        if 'left' in variant['device']['chamfer']['sides']:\n            chamfers = ['topleft', 'bottomleft']\n        elif 'right' in variant['device']['chamfer']['sides']:\n            chamfers = ['topright', 'bottomright']\n        else:\n            chamfers = []\n        m = add_corners(m, [left_x, top_y], [right_x, bottom_y], 0.5, 0.5, 'F.SilkS', width, offset, chamfers)\n        return m\n\n\n    def _draw_courtyard(self, m ,dim):\n        m.append(RectLine(start=[-dim.courtyard_offset_x_mm, -dim.courtyard_offset_y_mm],\n                                  end=[dim.courtyard_offset_x_mm, dim.courtyard_offset_y_mm], layer='F.CrtYd',\n                                  width=dim.courtyard_line_width_mm))\n        return m\n\n\n    def _add_3D_model(self, m, base, dim):\n        m.append(\n            Model(filename=\"{p:s}/{n:s}.wrl\".format(p=base['3d_prefix'], n=dim.name), at=[0, 0, 0], scale=[1, 1, 1],\n                  rotate=[0, 0, 0]))\n        return m\n\n\n    def _build_footprint(self, base, variant, cut_pin=False, tab_linked=False, verbose=False):\n\n        # calculate dimensions and other attributes specific to this variant\n        dim = Dimensions(base, variant, cut_pin, tab_linked)\n\n        # initialise footprint\n        kicad_mod = Footprint(dim.name)\n        kicad_mod = self._add_properties(kicad_mod, variant)\n        kicad_mod = self._add_labels(kicad_mod, variant, dim)\n\n        # create pads\n        kicad_mod = self._draw_pads(kicad_mod, variant, dim)\n\n        # create fab outline\n        kicad_mod = self._draw_fab_outline(kicad_mod, variant, dim, dim.fab_line_width_mm, (0, 0))\n\n        # create silkscreen outline\n        kicad_mod = self._draw_silk_outline(kicad_mod, variant, dim, dim.silk_line_width_mm, dim.silk_offset_mm)\n\n        # create courtyard\n        kicad_mod = self._draw_courtyard(kicad_mod, dim)\n\n        # add 3D model\n        kicad_mod = self._add_3D_model(kicad_mod, base, dim)\n\n        # print render tree\n        if verbose:\n            print('\\r\\nMaking {n:s}'.format(n=dim.name))\n            print(kicad_mod.getRenderTree())\n\n        # write file\n        file_handler = KicadFileHandler(kicad_mod)\n        file_handler.writeFile('{:s}.kicad_mod'.format(dim.name))\n\n\n    def build_series(self, verbose=False):\n        print('Making {p:s}'.format(p=self.config['base']['description']))\n        base = self.config['base']\n        for variant in self.config['variants']:\n            self._build_footprint(base, variant, verbose=verbose)\n\n\nclass StyleA(CapacitorTrimmer):\n\n    def __init__(self, config_file):\n        self.FAMILY = 'STYLE-A'\n        self.config = self._load_config(config_file)\n\n\nclass StyleB(CapacitorTrimmer):\n\n    def __init__(self, config_file):\n        self.FAMILY = 'STYLE-B'\n        self.config = self._load_config(config_file)\n\n\nclass StyleC(CapacitorTrimmer):\n\n    def __init__(self, config_file):\n        self.FAMILY = 'STYLE-C'\n        self.config = self._load_config(config_file)\n\n\nclass StyleD(CapacitorTrimmer):\n\n    def __init__(self, config_file):\n        self.FAMILY = 'STYLE-D'\n        self.config = self._load_config(config_file)\n\n\nclass Factory(object):\n\n    def __init__(self, config_file):\n        self._config_file = config_file\n        self._parse_command_line()\n        self.verbose = self._args.verbose\n        self._create_build_list()\n\n    def _parse_command_line(self):\n        parser = argparse.ArgumentParser(description='Select which devices to make')\n        parser.add_argument('--family', help='device families to make: STYLE-A | STYLE-B | STYLE-C | STYLE-D  (default is all families)',\n                            type=str, nargs=1)\n        parser.add_argument('-v', '--verbose', help='show detailed information while making the footprints',\n                            action='store_true')\n        self._args = parser.parse_args()\n\n    def _create_build_list(self):\n        if not self._args.family:\n            self.build_list = [StyleA(self._config_file), StyleB(self._config_file), StyleC(self._config_file), StyleD(self._config_file)]\n        else:\n            self.build_list = []\n            if 'STYLE-A' in self._args.family:\n                self.build_list.append(StyleA(self._config_file))\n            if 'STYLE-B' in self._args.family:\n                self.build_list.append(StyleB(self._config_file))\n            if 'STYLE-C' in self._args.family:\n                self.build_list.append(StyleC(self._config_file))\n            if 'STYLE-D' in self._args.family:\n                self.build_list.append(StyleD(self._config_file))\n            if not self.build_list:\n                print('Family not recognised')\n\n"
  },
  {
    "path": "scripts/Capacitors_SMD/C_Trimmer_make.py",
    "content": "#!/usr/bin/env python\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\nimport argparse\nimport yaml\nimport pprint\n\nsys.path.append(os.path.join(sys.path[0], \"../..\"))  # enable package import from parent directory\n\nfrom KicadModTree import *  # NOQA\n\n\nif __name__ == '__main__':\n\n    print('Making DPAK footprints')\n\n    from C_Trimmer_factory import *\n\n    CONFIG = 'C_Trimmer_config.yaml' \n                \n    f = Factory(CONFIG)\n\n    for series in f.build_list:\n        series.build_series(verbose=f.verbose)\n\n"
  },
  {
    "path": "scripts/Capacitors_SMD/bump.py",
    "content": "from KicadModTree import *  # NOQA\n\ndef add_bump(m, anchor_pos, bump_length, bump_width, direction, layer, width, offset=(0, 0)):\n\n    if direction == 'up':\n        delta_x = bump_length\n        delta_y = -bump_width\n        start_x = anchor_pos[0]\n        start_y = anchor_pos[1] - offset[1]\n    elif direction == 'down':\n        delta_x = bump_length\n        delta_y = bump_width\n        start_x = anchor_pos[0]\n        start_y = anchor_pos[1] + offset[1]\n    elif direction == 'left':\n        delta_x = -bump_width\n        delta_y = bump_length\n        start_x = anchor_pos[0] - offset[0]\n        start_y = anchor_pos[1]\n    elif direction == 'right':\n        delta_x = bump_width\n        delta_y = bump_length\n        start_x = anchor_pos[0] + offset[0]\n        start_y = anchor_pos[1]\n    else:\n        return m\n\n    if direction in ['up', 'down']:\n        polygon_line = [\n                         {'x': start_x - delta_x / 2.0, 'y': start_y },\n                         {'x': start_x - delta_x / 2.0, 'y': start_y + delta_y},\n                         {'x': start_x + delta_x / 2.0, 'y': start_y + delta_y},\n                         {'x': start_x + delta_x / 2.0, 'y': start_y} ]\n    else:\n        polygon_line = [\n                         {'x': start_x, 'y': start_y - delta_y / 2.0 },\n                         {'x': start_x + delta_x, 'y': start_y - delta_y / 2.0},\n                         {'x': start_x + delta_x, 'y': start_y + delta_y / 2.0},\n                         {'x': start_x, 'y': start_y + delta_y / 2.0} ]\n    m.append(PolygoneLine(polygone=polygon_line, layer=layer, width=width))\n\n    return m\n"
  },
  {
    "path": "scripts/Capacitors_SMD/chamfers.py",
    "content": "from KicadModTree import *\n\ndef add_rect_chamfer(m, start_pos, end_pos, layer, width, offset=(0,0), chamfers=[]):\n\n    # For the offset and chamfer to work properly, start-pos must be top-left, and end-pos must be bottom-right\n    x1 = min(start_pos[0], end_pos[0])\n    x2 = max(start_pos[0], end_pos[0])\n    y1 = min(start_pos[1], end_pos[1])\n    y2 = max(start_pos[1], end_pos[1])\n\n    # Put the offset (if any) back in\n    start_pos[0] = x1 - offset[0]\n    start_pos[1] = y1 - offset[1]\n    end_pos[0] = x2 + offset[0]\n    end_pos[1] = y2 + offset[1]\n        \n    # Work out intermediate positions on each side to use later when drawing corners or chamfers\n    JOG = 0.01  # avoid coincident intermediate points on non-chamfered sides\n    top_left_mid_pos = Point([start_pos[0] + JOG, start_pos[1]])\n    top_right_mid_pos = Point([end_pos[0] - JOG, start_pos[1]])\n    bottom_left_mid_pos = Point([start_pos[0] + JOG, end_pos[1]])\n    bottom_right_mid_pos = Point([end_pos[0] - JOG, end_pos[1]])\n    left_top_mid_pos = Point([start_pos[0], start_pos[1] + JOG])\n    left_bottom_mid_pos = Point([start_pos[0], end_pos[1] - JOG])\n    right_top_mid_pos = Point([end_pos[0], start_pos[1] + JOG])\n    right_bottom_mid_pos = Point([end_pos[0], end_pos[1] - JOG])\n\n    # Set the positions of the corners\n    top_left_pos = Point([start_pos[0], start_pos[1]])\n    top_right_pos = Point([end_pos[0], start_pos[1]])\n    bottom_left_pos = Point([start_pos[0], end_pos[1]])\n    bottom_right_pos = Point([end_pos[0], end_pos[1]])\n\n    for c in chamfers:\n        # Need to shift chamfered edges so they maintain constant distance from non-offset line\n        # tan(22.5) = 0.414 works correctly when chamfer is at 45 degrees (same  and Y offset), \n        # and still looks OK when X and Y offsets are different\n        try:\n            x_delta = c['size'] + 0.414 * offset[0]\n            y_delta = c['size'] + 0.414 * offset[1]\n            if c['corner'] == 'topleft':\n                top_left_pos.x = start_pos[0] + (x_delta) / 2.0\n                top_left_pos.y = start_pos[1] + (y_delta) / 2.0\n                top_left_mid_pos.x = start_pos[0] + (x_delta)\n                left_top_mid_pos.y = start_pos[1] + (y_delta)\n            elif c['corner'] == 'topright':\n                top_right_pos.x = end_pos[0] - (x_delta) / 2.0\n                top_right_pos.y = start_pos[1] + (y_delta) / 2.0\n                top_right_mid_pos.x = end_pos[0] - (x_delta)\n                right_top_mid_pos.y = start_pos[1] + (y_delta)\n            elif c['corner'] == 'bottomleft':\n                bottom_left_pos.x = start_pos[0] + (x_delta) / 2.0\n                bottom_left_pos.y = end_pos[1] - (y_delta) / 2.0\n                bottom_left_mid_pos.x = start_pos[0] + (x_delta)\n                left_bottom_mid_pos.y = end_pos[1] - (y_delta)\n            elif c['corner'] == 'bottomright':\n                bottom_right_pos.x = end_pos[0] - (x_delta) / 2.0\n                bottom_right_pos.y = end_pos[1] - (y_delta) / 2.0\n                bottom_right_mid_pos.x = end_pos[0] - (x_delta)\n                right_bottom_mid_pos.y = end_pos[1] - (y_delta)\n            elif c['corner'] == 'all':\n                chamfers.append({'corner': 'topleft', 'size': c['size']})\n                chamfers.append({'corner': 'topright', 'size': c['size']})\n                chamfers.append({'corner': 'bottomleft', 'size': c['size']})\n                chamfers.append({'corner': 'bottomright', 'size': c['size']})\n            else:\n                pass\n        except Exception as e:\n            # print(e)\n            pass\n    polygon_line = [\n                     {'x': top_left_pos.x, 'y': top_left_pos.y},\n                     {'x': top_left_mid_pos.x, 'y': top_left_mid_pos.y},\n                     {'x': top_right_mid_pos.x, 'y': top_right_mid_pos.y},\n                     {'x': top_right_pos.x, 'y': top_right_pos.y},\n                     {'x': right_top_mid_pos.x, 'y': right_top_mid_pos.y},\n                     {'x': right_bottom_mid_pos.x, 'y': right_bottom_mid_pos.y},\n                     {'x': bottom_right_pos.x, 'y': bottom_right_pos.y},\n                     {'x': bottom_right_mid_pos.x, 'y': bottom_right_mid_pos.y},\n                     {'x': bottom_left_mid_pos.x, 'y': bottom_left_mid_pos.y},\n                     {'x': bottom_left_pos.x, 'y': bottom_left_pos.y},\n                     {'x': left_bottom_mid_pos.x, 'y': left_bottom_mid_pos.y},\n                     {'x': left_top_mid_pos.x, 'y': left_top_mid_pos.y},\n                     {'x': top_left_pos.x, 'y': top_left_pos.y} ]\n    m.append(PolygoneLine(polygone=polygon_line, layer=layer, width=width))\n    return m\n\n"
  },
  {
    "path": "scripts/Capacitors_SMD/corners.py",
    "content": "from KicadModTree import *  # NOQA\n\ndef add_corners(m, start_pos, end_pos, size_x, size_y, layer, width, offset=(0, 0), chamfers=[]):\n\n    # If specifed, an 'offset' can be applied to the corners.\n    # For example, creating corners around a given Rect of a specified size\n    # offset for the rect line\n\n    # For the offset to work properly, start-pos must be top-left, and end-pos must be bottom-right\n    x1 = min(start_pos[0], end_pos[0])\n    x2 = max(start_pos[0], end_pos[0])\n    y1 = min(start_pos[1], end_pos[1])\n    y2 = max(start_pos[1], end_pos[1])\n\n    # Put the offset (if any) back in\n    start_pos[0] = x1 - offset[0]\n    start_pos[1] = y1 - offset[1]\n    end_pos[0] = x2 + offset[0]\n    end_pos[1] = y2 + offset[1]\n\n    if 'topleft' in chamfers:\n        m.append(Line(start=[start_pos[0], start_pos[1] + size_y], end=[start_pos[0] + size_x, start_pos[1]], layer=layer, width=width))\n    else:\n        m.append(Line(start=[start_pos[0], start_pos[1]], end=[start_pos[0] + size_x, start_pos[1]], layer=layer, width=width))\n        m.append(Line(start=[start_pos[0], start_pos[1]], end=[start_pos[0], start_pos[1] + size_y], layer=layer, width=width))\n\n    if 'bottomleft' in chamfers:\n        m.append(Line(start=[start_pos[0], end_pos[1] - size_y], end=[start_pos[0] + size_x, end_pos[1]], layer=layer, width=width))\n    else:\n        m.append(Line(start=[start_pos[0], end_pos[1]], end=[start_pos[0] + size_x, end_pos[1]], layer=layer, width=width))\n        m.append(Line(start=[start_pos[0], end_pos[1]], end=[start_pos[0], end_pos[1] - size_y], layer=layer, width=width))\n\n    if 'topright' in chamfers:\n        m.append(Line(start=[end_pos[0], start_pos[1] + size_y], end=[end_pos[0] - size_x, start_pos[1]], layer=layer, width=width))\n    else:\n        m.append(Line(start=[end_pos[0], start_pos[1]], end=[end_pos[0] - size_x, start_pos[1]], layer=layer, width=width))\n        m.append(Line(start=[end_pos[0], start_pos[1]], end=[end_pos[0], start_pos[1] + size_y], layer=layer, width=width))\n\n    if 'bottomright' in chamfers:\n        m.append(Line(start=[end_pos[0], end_pos[1] - size_y], end=[end_pos[0] - size_x, end_pos[1]], layer=layer, width=width))\n    else:\n        m.append(Line(start=[end_pos[0], end_pos[1]], end=[end_pos[0] - size_x, end_pos[1]], layer=layer, width=width))\n        m.append(Line(start=[end_pos[0], end_pos[1]], end=[end_pos[0], end_pos[1] - size_y], layer=layer, width=width))\n\n    return m\n\n"
  },
  {
    "path": "scripts/Capacitors_SMD/ipc7351B_capae_crystal.yaml",
    "content": "# Dimensions taken from ipc7351b table 3-20\n\n# Aluminum Electrolytic Capacitor and 2-Pin Crystal\n#           | Minimum | Median    | Maximum |\n#           | (Most)  | (Nominal) | (Least) |\n#           | Density | Density   | Density | round\n# Lead Part | Level A | Level B   | Level C |  to\n# ----------+---------+-----------+---------+-\n# Toe (JT)  |  0.7    |  0.5      |  0.3    | 0.05\n# >=10mm    |  1.0    |  0.7      |  0.4\n# Heel (JH) |  0.0    |  -0.1     |  -0.2   | 0.05\n# >=10mm    |  0.0    |  -0.05    |  -0.1\n# Side (JS) |  0.5    |  0.4      |  0.03   | 0.05\n# >=10mm    |  0.6    |  0.5      |  0.4\n# Courtyard |  1.0    |  0.5      |  0.25   |\n\nipc_spec_capae_crystal:\n    most:\n        toe: 0.7\n        heel: 0\n        side: 0.5\n        courtyard: 1.0\n    most_10mm:\n        toe: 1.0\n        heel: 0.0\n        side: 0.6\n        courtyard: 1.0\n    nominal:\n        toe: 0.5\n        heel: -0.1\n        side: 0.4\n        courtyard: 0.5\n    nominal_10mm:\n        toe: 0.7\n        heel: -0.05\n        side: 0.5\n        courtyard: 0.5\n    least:\n        toe: 0.3\n        heel: -0.2\n        side: 0.03\n        courtyard: 0.25\n    least_10mm:\n        toe: 0.4\n        heel: -0.1\n        side: 0.4\n        courtyard: 0.25\n    round_base:\n        toe: 0.05\n        heel: 0.05\n        side: 0.05\n"
  },
  {
    "path": "scripts/Capacitors_SMD/tantal and normal smd generator found under SMD_chip_package_rlc-etc",
    "content": ""
  },
  {
    "path": "scripts/Capacitors_THT/make_Capacitors_THT.py",
    "content": "#!/usr/bin/env python\r\n\r\nimport sys\r\nimport os\r\nimport math\r\n\r\n# ensure that the kicad-footprint-generator directory is available\r\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\r\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\r\n\r\nfrom KicadModTree import *  # NOQA\r\nfrom drawing_tools import *\r\nfrom footprint_scripts_resistorlike import *\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nif __name__ == '__main__':\r\n    R_POW = 0\r\n    specialtags=[\"Capacitor\"]\r\n\r\n    ###########################################################\r\n    # rectangular capacitors\r\n    ###########################################################\r\n    type = \"simple\"\r\n    #       w    d    h     rm    ddrill               name_additions                 add_description\r\n    caps=[\r\n        [  13,   3,   10,     10,      1,              [\"FKS3\",\"FKP3\",\"MKS4\"],                      \"http://www.wima.com/EN/WIMA_FKS_3.pdf, http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  13,   4,   10,     10,      1,              [\"FKS3\",\"FKP3\",\"MKS4\"],                      \"http://www.wima.com/EN/WIMA_FKS_3.pdf, http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [13.5,   4,   10,     10,      1,              [\"FKS3\",\"FKP3\",\"MKS4\"],                      \"http://www.wima.com/EN/WIMA_FKS_3.pdf, http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  13,   5,   10,     10,      1,              [\"FKS3\",\"FKP3\",\"MKS4\"],                      \"http://www.wima.com/EN/WIMA_FKS_3.pdf, http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [13.5,   5,   10,     10,      1,              [\"FKS3\",\"FKP3\",\"MKS4\"],                      \"http://www.wima.com/EN/WIMA_FKS_3.pdf, http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  13,   6,   10,     10,      1,              [\"FKS3\",\"FKP3\",\"MKS4\"],                      \"http://www.wima.com/EN/WIMA_FKS_3.pdf, http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  13,   8,   10,     10,      1,              [\"FKS3\",\"FKP3\",\"MKS4\"],                      \"http://www.wima.com/EN/WIMA_FKS_3.pdf, http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n\r\n        [  10,   3,  8.5,    7.5,      1,              [\"FKS3\",\"FKP3\"],                      \"http://www.wima.com/EN/WIMA_FKS_3.pdf\"],\r\n        [  10,   4,  8.5,    7.5,      1,              [\"FKS3\",\"FKP3\"],                      \"http://www.wima.com/EN/WIMA_FKS_3.pdf\"],\r\n\r\n        [  18,   5,   15,     15,    1.2,              [\"FKS3\",\"FKP3\"],                          \"http://www.wima.com/EN/WIMA_FKS_3.pdf\"],\r\n        [  18,   6,   15,     15,    1.2,              [\"FKS3\",\"FKP3\"],                          \"http://www.wima.com/EN/WIMA_FKS_3.pdf\"],\r\n        [  18,   7,   15,     15,    1.2,              [\"FKS3\",\"FKP3\"],                          \"http://www.wima.com/EN/WIMA_FKS_3.pdf\"],\r\n        [  18,   8,   15,     15,    1.2,              [\"FKS3\",\"FKP3\"],                          \"http://www.wima.com/EN/WIMA_FKS_3.pdf\"],\r\n        [  18,   9,   15,     15,    1.2,              [\"FKS3\",\"FKP3\"],                          \"http://www.wima.com/EN/WIMA_FKS_3.pdf\"],\r\n        [  18,  11,   15,     15,    1.2,              [\"FKS3\",\"FKP3\"],                          \"http://www.wima.com/EN/WIMA_FKS_3.pdf\"],\r\n\r\n        [  19,   5,   15,     15,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  19,   6,   15,     15,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  19,   7,   15,     15,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  19,   8,   15,     15,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  19,   9,   15,     15,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  19,  11,   15,     15,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n\r\n        [26.5,   5,   21,   22.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [26.5,   6,   21,   22.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [26.5,   7,   21,   22.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [26.5, 8.5,   21,   22.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [26.5,10.5,   21,   22.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [26.5,11.5,   21,   22.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  28,   8,   21,   22.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  28,  10,   21,   22.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  28,  12,   21,   22.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n\r\n        [31.5,   9,   26,   27.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [31.5,  11,   26,   27.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [31.5,  13,   26,   27.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [31.5,  15,   26,   27.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [31.5,  17,   26,   27.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [31.5,  20,   26,   27.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n\r\n        [  33,  13,   26,   27.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  33,  15,   26,   27.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  33,  20,   26,   27.5,    1.2,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n\r\n        [41.5,   9,   44,   37.5,      1.4,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [41.5,  11,   44,   37.5,      1.4,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [41.5,  13,   44,   37.5,      1.4,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [41.5,  15,   44,   37.5,      1.4,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [41.5,  17,   44,   37.5,      1.4,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [41.5,  19,   44,   37.5,      1.4,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [41.5,  20,   44,   37.5,      1.4,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [41.5,  24,   44,   37.5,      1.4,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [41.5,  31,   44,   37.5,      1.4,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [41.5,  35,   44,   37.5,      1.4,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [41.5,  40,   44,   37.5,      1.4,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n\r\n\r\n\r\n\r\n        #[  56,  19, 48.5,      1.1,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        #[  56,  23, 48.5,      1.1,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        #[  56,  27, 48.5,      1.1,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        #[  56,  33, 48.5,      1.1,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        #[  56,  37, 48.5,      1.1,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n\r\n        #[  57,  25, 52.5,      1.1,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        #[  57,  45, 52.5,      1.1,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        #[  57,  50, 52.5,      1.1,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        #[  57,  55, 52.5,      1.1,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        #[  57,  65, 52.5,      1.1,            [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n\r\n        [  27,   9,   21,     22,      1.1,              [\"\"],                          \"\"],\r\n        [  27,   9,   21,     23,      1.1,              [\"\"],                          \"\"],\r\n        [  27,  11,   21,     22,      1.1,              [\"\"],                          \"\"],\r\n        [  32,  15,   26,     27,      1.1,              [\"\"],                          \"\"],\r\n        [   4, 2.5,   10,    2.5,      0.8,              [\"\"],                          \"\"],\r\n        [ 7.5, 6.5,   10,      5,      0.8,              [\"\"],                          \"\"],\r\n        [   7, 2.5,   10,      5,      0.8,              [\"\"],                          \"\"],\r\n        [   7,   2,   10,      5,      0.8,              [\"\"],                          \"\"],\r\n        [   7, 2.5,   10,      5,      0.8,              [\"\"],                          \"\"],\r\n        [   7, 3.5,   10,      5,      0.8,              [\"\"],                          \"\"],\r\n        [   7, 4.5,   10,      5,      0.8,              [\"\"],                          \"\"],\r\n        [   7,   6,   10,      5,      0.8,              [\"\"],                          \"\"],\r\n        [   7, 6.5,   10,      5,      0.9,              [\"\"],                          \"\"],\r\n\r\n        [ 4.6, 5.5,    7,    2.5,      0.7,              [\"MKS02\", \"FKP02\"],                     \"http://www.wima.de/DE/WIMA_MKS_02.pdf\"],\r\n        [ 4.6, 4.6,    7,    2.5,      0.7,              [\"MKS02\", \"FKP02\"],                     \"http://www.wima.de/DE/WIMA_MKS_02.pdf\"],\r\n        [ 4.6, 3.8,    7,    2.5,      0.7,              [\"MKS02\", \"FKP02\"],                     \"http://www.wima.de/DE/WIMA_MKS_02.pdf\"],\r\n        [ 4.6, 3.0,    7,    2.5,      0.7,              [\"MKS02\", \"FKP02\"],                     \"http://www.wima.de/DE/WIMA_MKS_02.pdf\"],\r\n        [ 4.6,   2,    7,    2.5,      0.7,              [\"MKS02\", \"FKP02\"],                     \"http://www.wima.de/DE/WIMA_MKS_02.pdf\"],\r\n\r\n        [ 7.2, 2.5,    9,      5,      0.8,              [\"FKS2\",\"FKP2\",\"MKS2\",\"MKP2\"],                      \"http://www.wima.com/EN/WIMA_FKS_2.pdf\"],\r\n        [ 7.2, 3.0,    9,      5,      0.8,              [\"FKS2\",\"FKP2\",\"MKS2\",\"MKP2\"],                      \"http://www.wima.com/EN/WIMA_FKS_2.pdf\"],\r\n        [ 7.2, 3.5,    9,      5,      0.8,              [\"FKS2\",\"FKP2\",\"MKS2\",\"MKP2\"],                      \"http://www.wima.com/EN/WIMA_FKS_2.pdf\"],\r\n        [ 7.2, 4.5,    9,      5,      0.8,              [\"FKS2\",\"FKP2\",\"MKS2\",\"MKP2\"],                      \"http://www.wima.com/EN/WIMA_FKS_2.pdf\"],\r\n        [ 7.2, 5.5,    9,      5,      0.8,              [\"FKS2\",\"FKP2\",\"MKS2\",\"MKP2\"],                      \"http://www.wima.com/EN/WIMA_FKS_2.pdf\"],\r\n        [ 7.2, 7.2,    9,      5,      0.8,              [\"FKS2\",\"FKP2\",\"MKS2\",\"MKP2\"],                      \"http://www.wima.com/EN/WIMA_FKS_2.pdf\"],\r\n        [ 7.2, 8.5,    9,      5,      0.8,              [\"FKP2\",\"FKP2\",\"MKS2\",\"MKP2\"],                      \"http://www.wima.com/EN/WIMA_FKS_2.pdf\"],\r\n        [ 7.2,  11,    9,      5,      0.8,              [\"FKS2\",\"FKP2\",\"MKS2\",\"MKP2\"],                      \"http://www.wima.com/EN/WIMA_FKS_2.pdf\"],\r\n        [ 7.2, 2.5,    9,      5,      0.8,              [\"FKS2\",\"FKP2\",\"MKS2\",\"MKP2\"],                      \"http://www.wima.com/EN/WIMA_FKS_2.pdf\"],\r\n\r\n        [  10, 2.5,    9,    7.5,        1,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  10, 3.0,    9,    7.5,        1,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [  10, 4.0,    9,    7.5,        1,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [10.3, 4.5,    9,    7.5,        1,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [10.3,   5,    9,    7.5,        1,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [10.3, 5.7,    9,    7.5,        1,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n        [10.3, 7.2,    9,    7.5,        1,              [\"MKS4\"],                          \"http://www.wima.com/EN/WIMA_MKS_4.pdf\"],\r\n\r\n    ]\r\n\r\n    for w in [2.5, 2.6, 2.7, 3.2, 3.3, 3.4, 3.6, 3.8, 3.9, 4.0, 4.2, 4.9, 5.1, 5.7, 6.4, 6.7, 7.7, 8.5, 9.5, 9.8]:\r\n        caps+=[   9, w,  8, 7.5,      0.8,            [\"MKT\"],                           \"https://en.tdk.eu/inf/20/20/db/fc_2009/MKT_B32560_564.pdf\"],\r\n\r\n    for w in [2.8,3.4,3.5,4.2,4.3,5.1,5.3,6.3,6.4,7.3,8.8]:\r\n        caps+=[11.0, w,  10,  10,      0.8,            [\"MKT\"],                           \"https://en.tdk.eu/inf/20/20/db/fc_2009/MKT_B32560_564.pdf\"],\r\n\r\n    for w in [2,5,2.6,2.8,3.2,3.5,3.6,4.0,4.3,4.5,5.1,5.2,5.6,6.4,6.6,6.9,7.3,7.5,7.8,8.0,8.8,9.5,9.8]:\r\n        caps+=[11.5, w,  10,  10,      0.8,            [\"MKT\"],                           \"https://en.tdk.eu/inf/20/20/db/fc_2009/MKT_B32560_564.pdf\"],\r\n\r\n    for w in [4.7,4.9,5,6,7,7.3,8.7,8.9,9,9.2,10.7,10.9,11.2,11.8,13.5,13.7,13.9]:\r\n        caps+=[16.5, w,  14,  15,      1.1,            [\"MKT\"],                           \"https://en.tdk.eu/inf/20/20/db/fc_2009/MKT_B32560_564.pdf\"],\r\n\r\n    for w in [7,8.3,8.6,10.1,10.3,10.9,12.2,12.6,12.8]:\r\n        caps+=[  24, w,  15, 22.5,      1.2,            [\"MKT\"],                           \"https://en.tdk.eu/inf/20/20/db/fc_2009/MKT_B32560_564.pdf\"],\r\n\r\n    for w in [7.6,7.8,7.9,9.1,9.6,11,11.9,12.2,13,13.8,14.2,16]:\r\n        caps+=[  29, w,  19, 27.5,      1.2,            [\"MKT\"],                           \"https://en.tdk.eu/inf/20/20/db/fc_2009/MKT_B32560_564.pdf\"],\r\n\r\n    script3rect=\"CQ_params_C_Rect.py\"\r\n    with open(script3rect, \"w\") as myfile:\r\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\r\n    for c in caps:\r\n        seriesname = \"Rect\";\r\n        w = c[0];\r\n        d = c[1];\r\n        h3d=c[2]\r\n        w2 = 0;\r\n        rm = c[3];\r\n        ddrill = c[4];\r\n        add_description = c[6];\r\n        name_additions = c[5]\r\n        scr=script3rect\r\n        makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=d, ddrill=ddrill, R_POW=R_POW,\r\n                                    type=type, w2=w2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                                    specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                                    specialtags=specialtags, classname=\"C\", lib_name=\"${KISYS3DMOD}/Capacitor_THT_Rectangular\", script3d=scr, height3d=h3d)\r\n\r\n\r\n    ###########################################################\r\n    # rectangular capacitors with 2 RMs\r\n    ###########################################################\r\n    caps=[]\r\n    #           w        h       rm     rm2     ddrill\r\n    caps+=[     7,     3.5,     2.5,      5,       0.8,            [\"\"],                           \"\"],\r\n    caps+=[    10,       5,       5,    7.5,       0.8,            [\"\"],                           \"\"],\r\n    caps+=[    13,     6.5,     7.5,     10,       0.8,            [\"\"],                           \"\"],\r\n\r\n    for c in caps:\r\n        seriesname = \"Rect\";\r\n        type=\"simple\"\r\n        w = c[0];\r\n        d = c[1];\r\n        w2 = 0;\r\n        rm = c[2];\r\n        rm2 = c[3];\r\n        ddrill = c[4];\r\n        add_description = c[6];\r\n        name_additions = c[5]\r\n        scr = script3rect\r\n        makeResistorRadial(seriesname=seriesname, rm=rm, rm2=rm2, w=w, h=d, ddrill=ddrill, R_POW=R_POW,\r\n                                    type=type, w2=w2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                                    specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                                    specialtags=specialtags, classname=\"C\", lib_name=\"${KISYS3DMOD}/Capacitor_THT_Rectangular\", script3d=scr, height3d=10)\r\n\r\n\r\n\r\n    ###########################################################\r\n    # disc capacitors\r\n    ###########################################################\r\n\r\n    #       d    w    rm    ddrill               name_additions                 add_description\r\n    caps = [\r\n        [  12, 4.4, 7.75,      1.2,                          [],                              \"\"],\r\n        [   3,   2,  2.5,      0.8,                          [],                              \"\"],\r\n        [   6, 4.4,    5,      0.8,                          [],                              \"\"],\r\n        [ 7.5, 4.4,    5,      0.8,                          [],                              \"\"],\r\n        [   5, 2.5,  2.5,      0.8,                          [],                              \"http://cdn-reichelt.de/documents/datenblatt/B300/DS_KERKO_TC.pdf\"],\r\n        [   5, 2.5,    5,      0.8,                          [],                              \"http://cdn-reichelt.de/documents/datenblatt/B300/DS_KERKO_TC.pdf\"],\r\n        [   6, 2.5,    5,      0.8,                          [],                              \"http://cdn-reichelt.de/documents/datenblatt/B300/DS_KERKO_TC.pdf\"],\r\n        [   7, 2.5,    5,      0.8,                          [],                              \"http://cdn-reichelt.de/documents/datenblatt/B300/DS_KERKO_TC.pdf\"],\r\n        [   8, 2.5,    5,      0.8,                          [],                              \"http://cdn-reichelt.de/documents/datenblatt/B300/DS_KERKO_TC.pdf\"],\r\n        [   9, 2.5,    5,      0.8,                          [],                              \"http://cdn-reichelt.de/documents/datenblatt/B300/DS_KERKO_TC.pdf\"],\r\n        [  10, 2.5,    5,      0.8,                          [],                              \"http://cdn-reichelt.de/documents/datenblatt/B300/DS_KERKO_TC.pdf\"],\r\n        [  3.0,1.6,  2.5,      0.8,                          [],                              \"http://www.vishay.com/docs/45233/krseries.pdf\"],\r\n        [  3.4,2.1,  2.5,      0.8,                          [],                              \"http://www.vishay.com/docs/45233/krseries.pdf\"],\r\n        [  3.8,2.6,  2.5,      0.8,                          [],                              \"http://www.vishay.com/docs/45233/krseries.pdf\"],\r\n        [  4.3,1.9,    5,      0.8,                          [],                              \"http://www.vishay.com/docs/45233/krseries.pdf\"],\r\n        [  4.7,2.5,    5,      0.8,                          [],                              \"http://www.vishay.com/docs/45233/krseries.pdf\"],\r\n        [  5.1,3.2,    5,      0.8,                          [],                              \"http://www.vishay.com/docs/45233/krseries.pdf\"],\r\n\r\n        [  7.5,2.5,    5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [  7.5,5.0,    5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [  7.5,5.0,  7.5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [  7.5,5.0,   10,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [    8,5.0,    5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [    8,5.0,  7.5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [    8,5.0,   10,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [    9,5.0,    5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [    9,5.0,  7.5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [    9,5.0,   10,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [ 10.5,5.0,    5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [ 10.5,5.0,  7.5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [ 10.5,5.0,   10,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [   11,5.0,    5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [   11,5.0,  7.5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [   11,5.0,   10,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n\r\n        [ 12.5,5.0,  7.5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [ 12.5,5.0,   10,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [ 14.5,5.0,  7.5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [ 14.5,5.0,   10,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [ 16.0,5.0,  7.5,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n        [ 16.0,5.0,   10,        1,                          [],                              \"http://www.vishay.com/docs/28535/vy2series.pdf\"],\r\n    ]\r\n\r\n    script3mkt=\"CQ_params_C_Disc.py\"\r\n\r\n    for c in caps:\r\n        seriesname = \"Disc\";\r\n        type = \"disc\"\r\n        w = c[0];\r\n        d = c[1];\r\n        w2 = 0;\r\n        rm = c[2];\r\n        ddrill = c[3];\r\n        add_description = c[5];\r\n        name_additions = c[4]\r\n        makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=d, ddrill=ddrill, R_POW=R_POW,\r\n                           type=type, w2=w2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                           specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                           specialtags=specialtags, classname=\"C\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", script3d=script3mkt)\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n    ###########################################################\r\n    # axial capacitors\r\n    ###########################################################\r\n    scriptaxh=\"CQ_params_C_Axial.py\"\r\n    with open(scriptaxh, \"w\") as myfile:\r\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\r\n\r\n    d2=0\r\n    seriesname = \"Axial\"; w = 3.8; d = 2.6; ddrill = 0.8; R_POW = 0; add_description = \"http://www.vishay.com/docs/45231/arseries.pdf\"; name_additions = []\r\n    for rm in [7.5, 10, 12.5, 15]:\r\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW,\r\n                                    type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                                    specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                                    specialtags=name_additions, classname=\"C\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", script3d=scriptaxh)\r\n\r\n    seriesname = \"Axial\"; w = 5.1; d = 3.1; ddrill = 0.8; R_POW = 0; add_description = \"http://www.vishay.com/docs/45231/arseries.pdf\"; name_additions = []\r\n    for rm in [7.5, 10, 12.5, 15]:\r\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW,\r\n                                    type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                                    specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                                    specialtags=name_additions, classname=\"C\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", script3d=scriptaxh)\r\n    for w in [12,17,19,22]:\r\n        if w == 12:\r\n            rms = [15, 20]\r\n            ds=[6.5,7.5,8.5,9.5,10.5]\r\n        if w == 17:\r\n            rms = [20, 25]\r\n            ds=[6.5,7.0]\r\n        if w == 19:\r\n            rms = [25]\r\n            ds=[7.5, 8.0, 9, 9.5]\r\n        if w == 22:\r\n            rms = [27.5]\r\n            ds=[9.5,10.5]\r\n        for d in ds:\r\n            for rm in rms:\r\n                seriesname = \"Axial\"; ddrill = 0.8; R_POW = 0; add_description = \"http://cdn-reichelt.de/documents/datenblatt/B300/STYROFLEX.pdf\"; name_additions = []\r\n                makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW,\r\n                                            type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                                            specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                                            specialtags=name_additions, classname=\"C\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", script3d=scriptaxh)\r\n    seriesname = \"Axial\"; w = 12; d = 6.5; ddrill = 0.8; R_POW = 0; add_description = \"http://cdn-reichelt.de/documents/datenblatt/B300/STYROFLEX.pdf\"; name_additions = []\r\n    for rm in [15,20]:\r\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW,\r\n                                    type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                                    specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                                    specialtags=name_additions, classname=\"C\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", script3d=scriptaxh)\r\n    seriesname = \"Axial\"; w = 12; d = 7.5; ddrill = 0.8; R_POW = 0; add_description = \"http://cdn-reichelt.de/documents/datenblatt/B300/STYROFLEX.pdf\"; name_additions = []\r\n    for rm in [15,20]:\r\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW,\r\n                                    type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                                    specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                                    specialtags=name_additions, classname=\"C\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", script3d=scriptaxh)\r\n    seriesname = \"Axial\"; w = 12; d = 8.5; ddrill = 0.8; R_POW = 0; add_description = \"http://cdn-reichelt.de/documents/datenblatt/B300/STYROFLEX.pdf\"; name_additions = []\r\n    for rm in [15,20]:\r\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW,\r\n                                    type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                                    specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                                    specialtags=name_additions, classname=\"C\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", script3d=scriptaxh)\r\n    seriesname = \"Axial\"; w = 12; d = 9.5; ddrill = 0.8; R_POW = 0; add_description = \"http://cdn-reichelt.de/documents/datenblatt/B300/STYROFLEX.pdf\"; name_additions = []\r\n    for rm in [15,20]:\r\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW,\r\n                                    type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                                    specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                                    specialtags=name_additions, classname=\"C\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", script3d=scriptaxh)\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n    ###########################################################\r\n    # tantal polarized capacitors\r\n    ###########################################################\r\n    specialtags=[\"Tantal Electrolytic Capacitor\"]\r\n    #            d           rm    ddrill               name_additions                 add_description\r\n    caps = [\r\n        [      4.5,         2.5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      4.5,           5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      5.0,         2.5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      5.0,           5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      5.5,         2.5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      5.5,           5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      6.0,         2.5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      6.0,           5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      7.0,         2.5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      7.0,           5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      8.0,         2.5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      8.0,           5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      9.0,         2.5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [      9.0,           5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [     10.5,         2.5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n        [     10.5,           5,      0.8,                          [],                \"http://cdn-reichelt.de/documents/datenblatt/B300/TANTAL-TB-Serie%23.pdf\"],\r\n\r\n    ]\r\n\r\n    scripttan=\"CQ_params_CP_Tantal.py\"\r\n    with open(scripttan, \"w\") as myfile:\r\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\r\n\r\n    for c in caps:\r\n        seriesname = \"Radial_Tantal\";\r\n        type = \"round\"\r\n        deco=\"tantal\"\r\n        d = c[0];\r\n        w2 = 0;\r\n        rm = c[1];\r\n        ddrill = c[2];\r\n        add_description = c[4];\r\n        name_additions = c[3]\r\n        makeResistorRadial(seriesname=seriesname, rm=rm, w=d, h=d, ddrill=ddrill, R_POW=R_POW,\r\n                           type=type, w2=w2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                           specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                           specialtags=specialtags, classname=\"CP\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", deco=deco, script3d=scripttan)\r\n\r\n    ###########################################################\r\n    # radial electrolytic capacitors\r\n    ###########################################################\r\n    specialtags = [\"Electrolytic Capacitor\"]\r\n    #            d          h,      rm    rm2,   ddrill               name_additions                specialtags                  add_description\r\n    caps = [\r\n        [4, 7, 1.5, 0, 0.6, [], [], \"\"],\r\n        [4, 7, 2, 0, 0.6, [], [], \"\"],\r\n        [5, 7, 2, 0, 0.8, [], [], \"\"],\r\n        [5, 7, 2.5, 0, 0.8, [], [], \"\"],\r\n        [6.3, 7, 2.5, 0, 0.8, [], [], \"\"],\r\n        [7.5, 8, 2.5, 0, 0.8, [], [], \"\"],\r\n        [8, 10, 2.5, 0, 0.8, [], [], \"\"],\r\n        [8, 12, 3.5, 0, 0.8, [], [], \"\"],\r\n        [8, 14, 3.8, 0, 0.8, [], [], \"\"],\r\n        [8, 16, 5, 0, 0.8, [], [], \"\"],\r\n        [10, 16, 3.5, 0, 1, [], [], \"\"],\r\n        [10, 16, 3.8, 0, 1, [], [], \"\"],\r\n        [10, 16, 5, 0, 1, [], [], \"\"],\r\n        [10, 16, 5, 7.5, 1, [], [], \"\"],\r\n        [10, 20, 7.5, 0, 1, [], [], \"\"],\r\n        [10, 12, 2.5, 0, 0.8, [], [], \"\"],\r\n        [10, 12, 2.5, 5, 0.8, [], [], \"\"],\r\n        [12.5, 20, 5, 0, 1.2, [], [], \"\"],\r\n        [12.5, 24, 7.5, 0, 1.2, [], [], \"\"],\r\n        [12.5, 16, 2.5, 0, 1.2, [], [], \"\"],\r\n        [13, 20, 5, 0, 1.2, [], [], \"\"],\r\n        [13, 24, 7.5, 0, 1.2, [], [], \"\"],\r\n        [13, 16, 2.5, 0, 1.2, [], [], \"\"],\r\n        [14, 20, 5, 0, 1.2, [], [], \"\"],\r\n        [14, 20, 7.5, 0, 1.2, [], [], \"\"],\r\n        [16, 25, 7.5, 0, 1.2, [], [], \"\"],\r\n        [17, 30, 7.5, 0, 1.2, [], [], \"\"],\r\n        [18, 35, 7.5, 0, 1.2, [], [], \"\"],\r\n        [22, 40, 10, 0, 2, [\"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n        [24, 40, 10, 0, 2, [\"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n        [25, 45, 10, 0, 2, [\"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n        [26, 50, 10, 0, 2, [\"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n        [30, 50, 10, 0, 2, [\"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n        [35, 50, 10, 0, 2, [\"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n        [40, 50, 10, 0, 2, [\"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n    ]\r\n    scriptcprad = \"CQ_params_CP_Radial.py\"\r\n    with open(scriptcprad, \"w\") as myfile:\r\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\r\n\r\n    for c in caps:\r\n        seriesname = \"Radial\";\r\n        type = \"round\"\r\n        deco = \"elco\"\r\n        d = c[0];\r\n        h3d = c[1]\r\n        w2 = 0;\r\n        rm = c[2];\r\n        rm2 = c[3]\r\n        ddrill = c[4];\r\n        add_description = c[7];\r\n        name_additions = c[5]\r\n        special_tags = specialtags + c[6]\r\n        makeResistorRadial(seriesname=seriesname, rm=rm, rm2=rm2, w=d, h=d, ddrill=ddrill, R_POW=R_POW,\r\n                           type=type, w2=w2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                           specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                           specialtags=special_tags, classname=\"CP\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", deco=deco,\r\n                           script3d=scriptcprad, height3d=h3d)\r\n\r\n    ###########################################################\r\n    # radial nonpolar electrolytic capacitors\r\n    \r\n    # package sizes taken from:\r\n    # http://nichicon-us.com/english/products/pdfs/e-ump.pdf\r\n    # http://nichicon-us.com/english/products/pdfs/e-usp.pdf\r\n    # http://nichicon-us.com/english/products/pdfs/e-uvp.pdf\r\n    # http://nichicon-us.com/english/products/pdfs/e-ues.pdf\r\n    ###########################################################\r\n    specialtags = [\"Non-Polar Electrolytic Capacitor\"]\r\n    #            d          h,      rm    rm2,   ddrill               name_additions                specialtags                  add_description\r\n    caps = [\r\n        [4, 5, 1.5, 0, 0.6, [], [], \"\"],\r\n        [4, 7, 1.5, 0, 0.6, [], [], \"\"],\r\n        [5, 5, 2, 0, 0.6, [], [], \"\"],\r\n        [5, 7, 2, 0, 0.6, [], [], \"\"],\r\n        [5, 11, 2, 0, 0.8, [], [], \"\"],\r\n        [6.3, 5, 2.5, 0, 0.8, [], [], \"\"],\r\n        [6.3, 7, 2.5, 0, 0.8, [], [], \"\"],\r\n        [6.3, 11, 2.5, 0, 0.8, [], [], \"\"],\r\n        [8, 7, 3.5, 0, 0.8, [], [], \"\"],\r\n        [8, 11.5, 3.5, 0, 0.8, [], [], \"\"],\r\n        [10, 12.5, 5, 0, 0.8, [], [], \"\"],\r\n        [10, 16, 5, 0, 0.8, [], [], \"\"],\r\n        [10, 20, 5, 0, 0.8, [], [], \"\"],\r\n        [12.5, 20, 5, 0, 0.8, [], [], \"\"],\r\n        [12.5, 25, 5, 0, 0.8, [], [], \"\"],\r\n        [16, 25, 7.5, 0, 1, [], [], \"\"],\r\n        [16, 31.5, 7.5, 0, 1, [], [], \"\"],\r\n        [18, 35.5, 7.5, 0, 1, [], [], \"\"]\r\n    ]\r\n    scriptcprad = \"CQ_params_C_Radial.py\"\r\n    with open(scriptcprad, \"w\") as myfile:\r\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\r\n\r\n    for c in caps:\r\n        seriesname = \"Radial\";\r\n        type = \"round\"\r\n        deco = \"electrolytic nonpolar\"\r\n        d = c[0];\r\n        h3d = c[1]\r\n        w2 = 0;\r\n        rm = c[2];\r\n        rm2 = c[3]\r\n        ddrill = c[4];\r\n        add_description = c[7];\r\n        name_additions = c[5]\r\n        special_tags = specialtags + c[6]\r\n        makeResistorRadial(seriesname=seriesname, rm=rm, rm2=rm2, w=d, h=d, ddrill=ddrill, R_POW=R_POW,\r\n                           type=type, w2=w2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                           specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                           specialtags=special_tags, classname=\"C\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", deco=deco,\r\n                           script3d=scriptcprad, height3d=h3d)\r\n\r\n                           \r\n    ###########################################################\r\n    # radial electrolytic capacitors, 3 pins\r\n    ###########################################################\r\n    specialtags = [\"Electrolytic Capacitor\"]\r\n    #   p3= [pinid, posx, posy, ddrill]\r\n    #            d          h,          rm                     p3,   ddrill               name_additions                specialtags                  add_description\r\n    caps = [\r\n\r\n        [       22,         40,         10,     [2,10-3.3,-4.75,2.5],        2, [\"3pin\", \"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n        [       24,         40,         10,     [2,10-3.3,-4.75,2.5],        2, [\"3pin\", \"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n        [       25,         45,         10,     [2,10-3.3,-4.75,2.5],        2, [\"3pin\", \"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n        [       26,         45,         10,     [2,10-3.3,-4.75,2.5],        2, [\"3pin\", \"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n        [       30,         45,         10,     [2,10-3.3,-4.75,2.5],        2, [\"3pin\", \"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n        [       35,         50,         10,     [2,10-3.3,-4.75,2.5],        2, [\"3pin\", \"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n        [       40,         50,         10,     [2,10-3.3,-4.75,2.5],        2, [\"3pin\", \"SnapIn\"], [], \", http://www.vishay.com/docs/28342/058059pll-si.pdf\"],\r\n\r\n    ]\r\n    scriptcprad3p = \"CQ_params_CP_Radial_3Pin.py\"\r\n    with open(scriptcprad3p, \"w\") as myfile:\r\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\r\n\r\n    for c in caps:\r\n        seriesname = \"Radial\";\r\n        type = \"round\"\r\n        deco = \"elco\"\r\n        d = c[0];\r\n        h3d = c[1]\r\n        w2 = 0;\r\n        rm = c[2];\r\n        rm2 = 0\r\n        ddrill = c[4];\r\n        add_description = c[7];\r\n        name_additions = c[5]\r\n        special_tags = specialtags + c[6]\r\n        ap=[c[3]]\r\n        makeResistorRadial(seriesname=seriesname, rm=rm, rm2=rm2, w=d, h=d, ddrill=ddrill, R_POW=R_POW,\r\n                           type=type, w2=w2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                           specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                           specialtags=special_tags, classname=\"CP\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", deco=deco,\r\n                           script3d=scriptcprad3p, height3d=h3d, additionalPins=ap)\r\n\r\n\r\n\r\n    ###########################################################\r\n    # axial electrolytic capacitors\r\n    ###########################################################\r\n    specialtags = [\"Electrolytic Capacitor\"]\r\n    #            d          l           rm          ddrill               name_additions                specialtags                  add_description\r\n    caps = [\r\n        [      4.5,        10,          15,              1,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [        6,        10,          15,              1,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [        8,        11,          15,              1,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [      6.5,        18,          25,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [        8,        18,          25,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [       10,        18,          25,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [       10,        25,          30,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [       10,        30,          35,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [     12.5,        30,          35,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [       15,        30,          35,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [       18,        30,          35,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [       18,        38,          44,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [       21,        38,          44,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/28325/021asm.pdf\"],\r\n        [     23.0,      42,          45,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     23.0,      55,          60,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     23.0,      67,          75,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     23.0,      80,          85,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     23.0,      93,         100,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     26,        42,          45,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     26,        55,          60,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     26,        67,          75,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     26,        80,          85,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     26,        93,         100,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     29.0,      42,          45,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     29.0,      55,          60,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     29.0,      67,          75,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     29.0,      80,          85,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     29.0,      93,         100,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     32.0,      42,          45,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     32.0,      55,          60,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     32.0,      67,          75,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     32.0,      80,          85,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     32.0,      93,         100,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     35.0,      42,          45,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     35.0,      55,          60,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     35.0,      67,          75,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     35.0,      80,          85,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [     35.0,      93,         100,            1.2,                          [],                        [],                 \", http://www.vishay.com/docs/42037/53d.pdf\"],\r\n        [       10,        20,          26,            1.2,                          [],                        [],                 \", http://www.kemet.com/Lists/ProductCatalog/Attachments/424/KEM_AC102.pdf\"],\r\n        [       10,        29,          35,            1.2,                          [],                        [],                 \", http://www.kemet.com/Lists/ProductCatalog/Attachments/424/KEM_AC102.pdf\"],\r\n        [       13,        20,          26,            1.2,                          [],                        [],                 \", http://www.kemet.com/Lists/ProductCatalog/Attachments/424/KEM_AC102.pdf\"],\r\n        [       13,        29,          35,            1.2,                          [],                        [],                 \", http://www.kemet.com/Lists/ProductCatalog/Attachments/424/KEM_AC102.pdf\"],\r\n        [       13,        37,          43,            1.2,                          [],                        [],                 \", http://www.kemet.com/Lists/ProductCatalog/Attachments/424/KEM_AC102.pdf\"],\r\n        [       16,        29,          35,            1.2,                          [],                        [],                 \", http://www.kemet.com/Lists/ProductCatalog/Attachments/424/KEM_AC102.pdf\"],\r\n        [       16,        37,          43,            1.2,                          [],                        [],                 \", http://www.kemet.com/Lists/ProductCatalog/Attachments/424/KEM_AC102.pdf\"],\r\n        [       16,        40,          48,            1.2,                          [],                        [],                              \"\"],\r\n        [       20,      26.5,          33,            1.4,                          [],                        [],                 \", http://www.kemet.com/Lists/ProductCatalog/Attachments/424/KEM_AC102.pdf\"],\r\n        [       20,        29,          35,            1.4,                          [],                        [],                 \", http://www.kemet.com/Lists/ProductCatalog/Attachments/424/KEM_AC102.pdf\"],\r\n        [       20,      34.5,          41,            1.4,                          [],                        [],                 \", http://www.kemet.com/Lists/ProductCatalog/Attachments/424/KEM_AC102.pdf\"],\r\n        [       20,        37,          43,            1.4,                          [],                        [],                 \", http://www.kemet.com/Lists/ProductCatalog/Attachments/424/KEM_AC102.pdf\"],\r\n        [       20,      42.5,          49,            1.4,                          [],                        [],                              \"\"],\r\n        [       20,        46,          52,            1.4,                          [],                        [],                              \"\"],\r\n        [        5,        11,          18,            1.2,                          [],                        [],                              \"\"],\r\n        [        6,        11,          18,            1.2,                          [],                        [],                              \"\"],\r\n        [        8,        21,          28,            1.2,                          [],                        [],                              \"\"],\r\n    ]\r\n    scriptcpax=\"CQ_params_CP_Axial.py\"\r\n    with open(scriptcpax, \"w\") as myfile:\r\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\r\n\r\n    for c in caps:\r\n        seriesname = \"Axial\";\r\n        type = \"cyl\"\r\n        deco = \"elco\"\r\n        d = c[0];\r\n        l = c[1];\r\n        rm = c[2]\r\n        ddrill = c[3];\r\n        add_description = c[6];\r\n        name_additions = c[4]\r\n        special_tags = specialtags + c[5]\r\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=l, d=d, ddrill=ddrill, R_POW=R_POW,\r\n                           type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1,\r\n                           specialfpname=\"\", add_description=add_description, name_additions=name_additions,\r\n                           specialtags=special_tags, classname=\"CP\", lib_name=\"${KISYS3DMOD}/Capacitor_THT\", deco=deco, script3d=scriptcpax)\r\n"
  },
  {
    "path": "scripts/Chokes_THT/make_Chokes_THT.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom drawing_tools import *\nfrom footprint_scripts_resistorlike import *\n\n\n\n\nif __name__ == '__main__':\n    # standard resistors: http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf\n    type = \"cyl\"\n    d2=0\n    script3d=\"L_Choke_axial_cyl_hor.py\"\n    with open(script3d, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3dv=\"L_Choke_axial_cyl_ver.py\"\n    with open(script3dv, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n\n    # axial Chokes\n    classname=\"L\"\n    libname = \"${KISYS3DMOD}/Inductor_THT\"\n    seriesname = \"Axial\"; w = 9.5; d = 4; ddrill = 1; R_POW = 0; add_description=\"http://cdn-reichelt.de/documents/datenblatt/B400/DS_SMCC_NEU.pdf, http://cdn-reichelt.de/documents/datenblatt/B400/LEADEDINDUCTORS.pdf\"; name_additions=[\"Fastron\",\"SMCC\"]\n    for rm in [12.7,15.24]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [2.54,5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 7; d = 3.3; ddrill = 0.8; R_POW = 0; add_description=\"http://www.fastrongroup.com/image-show/70/MICC.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\",\"MICC\"]\n    for rm in [10.16,12.7]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [2.54,5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 24; d = 7.5; ddrill = 1.2; R_POW = 0; add_description=\"http://cdn-reichelt.de/documents/datenblatt/B400/DS_MESC.pdf\"; name_additions=[\"Fastron\",\"MESC\"]\n    for rm in [27.94]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 16; d = 7.5; ddrill = 1.1; R_POW = 0; add_description=\"http://www.fastrongroup.com/image-show/26/XHBCC.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\",\"XHBCC\"]\n    for rm in [20.32,25.4]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 16; d = 6.3; ddrill = 1.1; R_POW = 0; add_description=\"http://www.fastrongroup.com/image-show/25/VHBCC.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\",\"VHBCC\"]\n    for rm in [20.32,25.4]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 14.5; d = 5.8; ddrill = 1.1; R_POW = 0; add_description=\"http://www.fastrongroup.com/image-show/18/HBCC.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\",\"HBCC\"]\n    for rm in [20.32,25.4]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 12.8; d = 5.8; ddrill = 1.1; R_POW = 0; add_description=\"http://www.fastrongroup.com/image-show/18/HBCC.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\",\"HBCC\"]\n    for rm in [20.32,25.4]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 12; d = 5; ddrill = 1.2; R_POW = 0; add_description=\"http://cdn-reichelt.de/documents/datenblatt/B400/DS_MISC.pdf\"; name_additions=[\"Fastron\",\"MISC\"]\n    for rm in [15.24]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 11; d = 4.5; ddrill = 1.0; R_POW = 0; add_description=\"http://www.fastrongroup.com/image-show/21/MECC.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\",\"MECC\"]\n    for rm in [15.24]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 13; d = 4.5; ddrill = 1.2; R_POW = 0; add_description=\"http://www.fastrongroup.com/image-show/19/HCCC.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\",\"HCCC\"]\n    for rm in [15.24]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 14; d = 4.5; ddrill = 1.0; R_POW = 0; add_description=\"http://www.fastrongroup.com/image-show/20/LACC.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\",\"LACC\"]\n    for rm in [15.24]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 20; d = 8; ddrill = 1.2; R_POW = 0; add_description=\"\"; name_additions=[]\n    for rm in [25.4]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 30; d = 8; ddrill = 1.4; R_POW = 0; add_description=\"http://cdn-reichelt.de/documents/datenblatt/B400/DS_77A.pdf\"; name_additions=[\"Fastron\",\"77A\"]\n    for rm in [35.56]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 26; d = 9; ddrill = 1.2; R_POW = 0; add_description=\"http://cdn-reichelt.de/documents/datenblatt/B400/DS_77A.pdf\"; name_additions=[\"Fastron\",\"77A\"]\n    for rm in [30.48]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 26; d = 10; ddrill = 1.2; R_POW = 0; add_description=\"http://cdn-reichelt.de/documents/datenblatt/B400/DS_77A.pdf\"; name_additions=[\"Fastron\",\"77A\"]\n    for rm in [30.48]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 26; d = 11; ddrill = 1.2; R_POW = 0; add_description=\"http://cdn-reichelt.de/documents/datenblatt/B400/DS_77A.pdf\"; name_additions=[\"Fastron\",\"77A\"]\n    for rm in [30.48]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 5.3; d = 2.2; ddrill = 0.8; R_POW = 0; add_description=\"http://www.vishay.com/docs/34030/im.pdf\"; name_additions=[\"Vishay\",\"IM-1\"]\n    for rm in [7.62,10.16]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [2.54]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 6.6; d = 2.7; ddrill = 0.8; R_POW = 0; add_description=\"http://www.vishay.com/docs/34030/im.pdf\"; name_additions=[\"Vishay\",\"IM-2\"]\n    for rm in [10.16]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [2.54]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 24; d = 7.1; ddrill = 1.0; R_POW = 0; add_description=\"http://www.vishay.com/docs/34035/im10.pdf\"; name_additions=[\"Vishay\",\"IM-10-28\"]\n    for rm in [30.48]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 24; d = 7.1; ddrill = 1.0; R_POW = 0; add_description=\"http://www.vishay.com/docs/34035/im10.pdf\"; name_additions=[\"Vishay\",\"IM-10-28\"]\n    for rm in [30.48]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 16; d = 9.5; ddrill = 1; R_POW = 0; add_description=\"http://www.vishay.com/docs/34030/im10.pdf\"; name_additions=[\"Vishay\",\"IM-10-37\"]\n    for rm in [20.32]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 17.5; d = 12; ddrill = 1; R_POW = 0; add_description=\"http://www.vishay.com/docs/34030/im10.pdf\"; name_additions=[\"Vishay\",\"IM-10-46\"]\n    for rm in [20.32]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 20.32; d = 12.07; ddrill = 1.2; R_POW = 0; add_description=\"http://www.vishay.com/docs/34014/iha.pdf\"; name_additions=[\"Vishay\",\"IHA-101\"]\n    for rm in [28.5]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 26.67; d = 12.07; ddrill = 1.2; R_POW = 0; add_description=\"http://www.vishay.com/docs/34014/iha.pdf\"; name_additions=[\"Vishay\",\"IHA-103\"]\n    for rm in [35]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 26.67; d = 13.97; ddrill = 1.2; R_POW = 0; add_description=\"http://www.vishay.com/docs/34014/iha.pdf\"; name_additions=[\"Vishay\",\"IHA-104\"]\n    for rm in [35]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 29.85; d = 13.97; ddrill = 1.2; R_POW = 0; add_description=\"http://www.vishay.com/docs/34014/iha.pdf\"; name_additions=[\"Vishay\",\"IHA-105\"]\n    for rm in [38]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 23.37; d = 12.7; ddrill = 1.2; R_POW = 0; add_description=\"http://www.vishay.com/docs/34014/iha.pdf\"; name_additions=[\"Vishay\",\"IHA-203\"]\n    for rm in [32]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n    seriesname = \"Axial\"; w = 20.32; d = 12.7; ddrill = 1.2; R_POW = 0; add_description=\"http://www.vishay.com/docs/34014/iha.pdf\"; name_additions=[\"Vishay\",\"IHA-201\"]\n    for rm in [25.4]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3d)\n    for rm in [7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=name_additions, classname=classname, lib_name=libname, script3d=script3dv)\n\n    # radial Chokes\n    rm2=0; w2=0\n    type = \"round\"; seriesname = \"Radial\";\n    classname = \"L\"\n    libname = \"${KISYS3DMOD}/Inductor_THT\"\n    script3drbox=\"L_Choke_radial_box.py\"\n    with open(script3drbox, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3drrs=\"L_Choke_radial_round_simple.py\"\n    with open(script3drrs, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3drro=\"L_Choke_radial_round_open.py\"\n    with open(script3drro, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    w = 12.5; w2=w; h = w; ddrill = 1.2; rm=9.0; rm2=0; R_POW=0; add_description = \"http://cdn-reichelt.de/documents/datenblatt/B400/DS_09HCP.pdf\"; name_additions=[\"Fastron\", \"09HCP\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.8, script3d=script3drro)\n    w = 12.5; w2=w; h = w; ddrill = 1.2; rm=7.0; rm2=0; R_POW=0; add_description = \"http://cdn-reichelt.de/documents/datenblatt/B400/DS_09HCP.pdf\"; name_additions=[\"Fastron\", \"09HCP\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.8, script3d=script3drro)\n    w = 13.5; w2=w; h = w; ddrill = 1.2; rm=7.0; rm2=0; R_POW=0; add_description = \"http://cdn-reichelt.de/documents/datenblatt/B400/DS_09HCP.pdf\"; name_additions=[\"Fastron\", \"09HCP\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.8, script3d=script3drro)\n    w = 12.0; w2=w; h = w; ddrill = 1.3; rm=5.0; rm2=0; R_POW=0; add_description = \"http://cdn-reichelt.de/documents/datenblatt/B400/DS_11P.pdf\"; name_additions=[\"Fastron\", \"11P\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=16, script3d=script3drrs)\n    w = 12.0; w2=w; h = w; ddrill = 1.6; rm=6.0; rm2=0; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_1900r.pdf\"; name_additions=[\"MuRATA\", \"1900R\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21, script3d=script3drrs)\n    w = 7.2; w2=w; h = w; ddrill = 1.2; rm=3.0; rm2=0; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_1700.pdf\"; name_additions=[\"MuRATA\", \"1700\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=8.5, script3d=script3drrs)\n    w = 10.5; w2=w; h = w; ddrill = 1.3; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.abracon.com/Magnetics/radial/AISR-01.pdf\"; name_additions=[\"Abacron\", \"AISR-01\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.5, script3d=script3drrs)\n    w = 10; w2=w; h = w; ddrill = 1.3; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.fastrongroup.com/image-show/37/07M.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\", \"07M\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=12.7, script3d=script3drro)\n    w = 8.7; w2=w; h = w; ddrill = 1.3; rm=5.0; rm2=0; R_POW=0; add_description = \"http://cdn-reichelt.de/documents/datenblatt/B400/DS_07HCP.pdf\"; name_additions=[\"Fastron\", \"07HCP\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10, script3d=script3drro)\n    w = 7.8; w2=w; h = w; ddrill = 1.3; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.abracon.com/Magnetics/radial/AISR875.pdf\"; name_additions=[\"Fastron\", \"07HCP\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=7.5, script3d=script3drrs)\n    w = 7.5; w2=w; h = w; ddrill = 1.3; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.fastrongroup.com/image-show/39/07P.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\", \"07P\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=12.5, script3d=script3drro)\n    w = 7.5; w2=w; h = w; ddrill = 1.3; rm=3.5; rm2=0; R_POW=0; add_description = \"http://www.fastrongroup.com/image-show/39/07P.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\", \"07P\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=12.5, script3d=script3drro)\n    w = 9.5; w2=w; h = w; ddrill = 1.3; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.fastrongroup.com/image-show/107/07HVP%2007HVP_T.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\", \"07HVP\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10, script3d=script3drro)\n    w = 10; w2=w; h = w; ddrill = 1.3; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.fastrongroup.com/image-show/37/07M.pdf?type=Complete-DataSheet&productType=series\"; name_additions=[\"Fastron\", \"07P\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=12.5, script3d=script3drro)\n    w = 7; w2=w; h = w; ddrill = 1.3; rm=3.0; rm2=0; R_POW=0; add_description = \"http://www.abracon.com/Magnetics/radial/AIUR-16.pdf\"; name_additions=[]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=9.5, script3d=script3drro)\n    w = 6.0; w2=w; h = w; ddrill = 1; rm=4.0; rm2=0; R_POW=0; add_description = \"http://www.abracon.com/Magnetics/radial/AIUR-07.pdf\"; name_additions=[]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=4.6, script3d=script3drro)\n    w = 18; w2=w; h = w; ddrill = 1; rm=10.0; rm2=0; R_POW=0; add_description = \"http://www.abracon.com/Magnetics/radial/AIUR-15.pdf\"; name_additions=[]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=1.5*w, script3d=script3drrs)\n    w = 21; w2=w; h = w; ddrill = 1; rm=19.0; rm2=0; R_POW=0; add_description = \"http://www.abracon.com/Magnetics/radial/AIRD02.pdf\"; name_additions=[]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21, script3d=script3drrs)\n    w = 24; w2=w; h = w; ddrill = 1.5; rm=24.0; rm2=0; R_POW=0; add_description = \"\"; name_additions=[]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=24, script3d=script3drrs)\n    w = 28; w2=w; h = w; ddrill = 1.5; rm=29.2; rm2=0; R_POW=0; add_description = \"\"; name_additions=[]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=28, script3d=script3drrs)\n\n    type = \"concentric\";\n    script3drconc=\"L_Choke_radial_concentric.py\"\n    with open(script3drconc, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    w = 24.4; w2=5.5; h = w; ddrill = 2.6; rm=23.9; rm2=0; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_1400.pdf\"; name_additions=[\"muRATA\", \"1400series\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.5, script3d=script3drconc)\n    w = 24.4; w2=5.5; h = w; ddrill = 2.1; rm=23.7; rm2=0; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_1400.pdf\"; name_additions=[\"muRATA\", \"1400series\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.5, script3d=script3drconc)\n    w = 24.4; w2=5.5; h = w; ddrill = 1.5; rm=23.4; rm2=0; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_1400.pdf\"; name_additions=[\"muRATA\", \"1400series\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.5, script3d=script3drconc)\n    w = 24.4; w2=5.5; h = w; ddrill = 1.0; rm=23.1; rm2=0; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_1400.pdf\"; name_additions=[\"muRATA\", \"1400series\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.5, script3d=script3drconc)\n    w = 24.4; w2=5.5; h = w; ddrill = 0.8; rm=22.9; rm2=0; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_1400.pdf\"; name_additions=[\"muRATA\", \"1400series\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.5, script3d=script3drconc)\n    w = 29.8; w2=5.1; h = w; ddrill = 2.6; rm=29.3; rm2=0; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_1400.pdf\"; name_additions=[\"muRATA\", \"1400series\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.5, script3d=script3drconc)\n    w = 29.8; w2=5.1; h = w; ddrill = 2.0; rm=29; rm2=0; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_1400.pdf\"; name_additions=[\"muRATA\", \"1400series\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.5, script3d=script3drconc)\n    w = 29.8; w2=5.1; h = w; ddrill = 1.5; rm=28.8; rm2=0; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_1400.pdf\"; name_additions=[\"muRATA\", \"1400series\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.5, script3d=script3drconc)\n    w = 29.8; w2=5.1; h = w; ddrill = 1; rm=28.5; rm2=0; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_1400.pdf\"; name_additions=[\"muRATA\", \"1400series\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.5, script3d=script3drconc)\n    w = 29.8; w2=5.1; h = w; ddrill = 0.8; rm=28.3; rm2=0; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_1400.pdf\"; name_additions=[\"muRATA\", \"1400series\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.5, script3d=script3drconc)\n    w = 16.8; w2=2.92; h = w; ddrill = 1.4; rm=11.43; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-1\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21.34, script3d=script3drconc)\n    w = 16.8; w2=2.92; h = w; ddrill = 1.0; rm=12.07; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-1\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21.34, script3d=script3drconc)\n    w = 16.8; w2=2.92; h = w; ddrill = 1.0; rm=12.70; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-1\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21.34, script3d=script3drconc)\n    w = 21; w2=2.92; h = w; ddrill = 1.6; rm=15.75; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-2\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21.34, script3d=script3drconc)\n    w = 21; w2=2.92; h = w; ddrill = 1.3; rm=14.61; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-2\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21.34, script3d=script3drconc)\n    w = 21; w2=2.92; h = w; ddrill = 1.2; rm=15.24; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-2\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21.34, script3d=script3drconc)\n    w = 21; w2=2.92; h = w; ddrill = 0.8; rm=15; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-2\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21.34, script3d=script3drconc)\n    w = 27.9; w2=2.92; h = w; ddrill = 2.1; rm=20.07; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-3\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21.34, script3d=script3drconc)\n    w = 27.9; w2=2.92; h = w; ddrill = 1.8; rm=19.05; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-3\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21.34, script3d=script3drconc)\n    w = 27.9; w2=2.92; h = w; ddrill = 1.8; rm=18.29; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-3\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21.34, script3d=script3drconc)\n    w = 40.64; w2=4.45; h = w; ddrill = 2.2; rm=27.94; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-4\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=26.16, script3d=script3drconc)\n    w = 40.64; w2=4.45; h = w; ddrill = 1; rm=27.18; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-4\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=26.16, script3d=script3drconc)\n    w = 40.64; w2=4.45; h = w; ddrill = 2.4; rm=28.70; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-5\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=36.83, script3d=script3drconc)\n    w = 40.64; w2=4.45; h = w; ddrill = 2.2; rm=27.94; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-5\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=36.83, script3d=script3drconc)\n    w = 40.64; w2=4.45; h = w; ddrill = 1.3; rm=26.16; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-5\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=36.83, script3d=script3drconc)\n    w = 50.80; w2=4.45; h = w; ddrill = 2.9; rm=36.32; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-6\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=38.10, script3d=script3drconc)\n    w = 50.80; w2=6.10; h = w; ddrill = 2.9; rm=38.86; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-6\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=38.10, script3d=script3drconc)\n    w = 50.80; w2=6.10; h = w; ddrill = 2.1; rm=35.81; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-6\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=38.10, script3d=script3drconc)\n    w = 50.80; w2=6.10; h = w; ddrill = 1.9; rm=34.29; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-6\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=38.10, script3d=script3drconc)\n    w = 50.80; w2=6.10; h = w; ddrill = 1.6; rm=33.27; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34015/ihb.pdf\"; name_additions=[\"Vishay\", \"IHB-6\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=38.10, script3d=script3drconc)\n\n    type = \"simplesymm45\";\n    w = 9.14; w2=w; h = w; ddrill = 1; rm=6.35; rm2=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-54044NL-Pulse-datasheet-5313493.pdf\"; name_additions=[\"Pulse\", \"LP-25\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=7.87, script3d=script3drbox)\n    w = 10.16; w2=w; h = w; ddrill = 1; rm=7.62; rm2=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-54044NL-Pulse-datasheet-5313493.pdf\"; name_additions=[\"Pulse\", \"LP-30\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=7.62, script3d=script3drbox)\n    w = 12.57; w2=w; h = w; ddrill = 1; rm=9.52; rm2=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-54044NL-Pulse-datasheet-5313493.pdf\"; name_additions=[\"Pulse\", \"LP-37\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=9.52, script3d=script3drbox)\n    w = 16.13; w2=w; h = w; ddrill = 1; rm=7.62; rm2=12.7; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-54044NL-Pulse-datasheet-5313493.pdf\"; name_additions=[\"Pulse\", \"LP-44\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=9.27, script3d=script3drbox)\n\n\n\n    rm2=0; w2=0\n    type = \"round\";\n    classname = \"L_Toroid\"\n    libname = \"${KISYS3DMOD}/Inductor_THT\"\n    deco=\"chokewire\"\n    type = \"concentric\" ;seriesname = \"Horizontal\";\n    script3dtoroidhor=\"L_Choke_toroid_hor.py\"\n    with open(script3dtoroidhor, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    w = 40; w2=w/3; h = w; ddrill = 1.5; rm=48.26; rm2=0; R_POW=0; add_description = \"\"; name_additions=[]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=4, script3d=script3dtoroidhor)\n    w = 0.125*25.4; w2=0.062*25.4; h = w; ddrill = 1; rm=6.4; rm2=0; R_POW=0; add_description = \"\"; name_additions=[\"Diameter3-5mm\",\"Amidon-T12\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=4, script3d=script3dtoroidhor)\n    w = 0.160*25.4; w2=0.078*25.4; h = w; ddrill = 1; rm=8; rm2=0; R_POW=0; add_description = \"\"; name_additions=[\"Diameter4-5mm\",\"Amidon-T16\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=4, script3d=script3dtoroidhor)\n    w = 0.200*25.4; w2=0.088*25.4; h = w; ddrill = 1; rm=9; rm2=0; R_POW=0; add_description = \"\"; name_additions=[\"Diameter6-5mm\",\"Amidon-T20\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=4.5, script3d=script3dtoroidhor)\n    w = 0.255*25.4; w2=0.120*25.4; h = w; ddrill = 1; rm=10; rm2=0; R_POW=0; add_description = \"\"; name_additions=[\"Diameter7-5mm\",\"Amidon-T25\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=5, script3d=script3dtoroidhor)\n    w = 0.307*25.4; w2=0.151*25.4; h = w; ddrill = 1.2; rm=13; rm2=0; R_POW=0; add_description = \"\"; name_additions=[\"Diameter9-5mm\",\"Amidon-T30\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=5.5, script3d=script3dtoroidhor)\n    w = 0.375*25.4; w2=0.205*25.4; h = w; ddrill = 1.2; rm=15; rm2=0; R_POW=0; add_description = \"\"; name_additions=[\"Diameter10-5mm\",\"Amidon-T37\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=6, script3d=script3dtoroidhor)\n    w = 0.440*25.4; w2=0.229*25.4; h = w; ddrill = 1.2; rm=17; rm2=0; R_POW=0; add_description = \"\"; name_additions=[\"Diameter12-5mm\",\"Amidon-T44\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=6.5, script3d=script3dtoroidhor)\n    w = 0.500*25.4; w2=0.303*25.4; h = w; ddrill = 1.2; rm=20; rm2=0; R_POW=0; add_description = \"\"; name_additions=[\"Diameter14-5mm\",\"Amidon-T50\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=7, script3d=script3dtoroidhor)\n    w = 16.8; w2=w/3; h = w; ddrill = 1.5; rm=14.7; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ3\", \"BigPads\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=8.2, script3d=script3dtoroidhor)\n    w = 16.8; w2=w/3; h = w; ddrill = 1.2; rm=14.7; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ3\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=8.2, script3d=script3dtoroidhor)\n    w = 17.3; w2=w/3; h = w; ddrill = 1.8; rm=15.24; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/2000_series.pdf?sfvrsn=5\"; name_additions=[\"Bourns\", \"2000\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.4, script3d=script3dtoroidhor)\n    w = 21.8; w2=w/3; h = w; ddrill = 1.8; rm=19.6; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/2100_series.pdf?sfvrsn=3\"; name_additions=[\"Bourns\", \"2100\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.4, script3d=script3dtoroidhor)\n    w = 21.8; w2=w/3; h = w; ddrill = 1.8; rm=19.1; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/2100_series.pdf?sfvrsn=3\"; name_additions=[\"Bourns\", \"2100\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=11.4, script3d=script3dtoroidhor)\n    w = 22.4; w2=w/3; h = w; ddrill = 1.5; rm=19.8; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ4\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.2, script3d=script3dtoroidhor)\n    w = 24.1; w2=w/3; h = w; ddrill = 1.8; rm=21.8; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/2100_series.pdf?sfvrsn=3\"; name_additions=[\"Bourns\", \"2200\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=14, script3d=script3dtoroidhor)\n    w = 24.1; w2=w/3; h = w; ddrill = 1.8; rm=23.1; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/2100_series.pdf?sfvrsn=3\"; name_additions=[\"Bourns\", \"2200\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=14, script3d=script3dtoroidhor)\n    w = 25.4; w2=w/3; h = w; ddrill = 1.5; rm=22.9; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ5\", \"BigPads\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=11.4, script3d=script3dtoroidhor)\n    w = 25.4; w2=w/3; h = w; ddrill = 1.2; rm=22.9; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ5\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=11.4, script3d=script3dtoroidhor)\n    w = 28; w2=w/3; h = w; ddrill = 1.5; rm=26.67; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/2100_series.pdf?sfvrsn=3\"; name_additions=[\"Bourns\", \"2200\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=14, script3d=script3dtoroidhor)\n    w = 28; w2=w/3; h = w; ddrill = 1.3; rm=25.1; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/2100_series.pdf?sfvrsn=3\"; name_additions=[\"Bourns\", \"2200\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=14, script3d=script3dtoroidhor)\n    w = 32.5; w2=w/3; h = w; ddrill = 2; rm=30; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/2300_series.pdf?sfvrsn=3\"; name_additions=[\"Bourns\", \"2300\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=16.5, script3d=script3dtoroidhor)\n    w = 32.5; w2=w/3; h = w; ddrill = 1.5; rm=28.9; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/2300_series.pdf?sfvrsn=3\"; name_additions=[\"Bourns\", \"2300\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=16.5, script3d=script3dtoroidhor)\n    w = 35.1; w2=w/3; h = w; ddrill = 1.5; rm=31.0; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ6\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=21.1, script3d=script3dtoroidhor)\n    w = 41.9; w2=w/3; h = w; ddrill = 1.5; rm=37.6; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ7\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=19.1, script3d=script3dtoroidhor)\n    w = 49.3; w2=w/3; h = w; ddrill = 1.7; rm=44.6; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ8\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=25.4, script3d=script3dtoroidhor)\n    w = 69.1; w2=w/3; h = w; ddrill = 2; rm=63.2; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ9\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=36.1, script3d=script3dtoroidhor)\n\n    type = \"simple90\" ;seriesname = \"Vertical\"; deco=\"chokewire\";\n    script3dtoroidver=\"L_Choke_toroid_ver.py\"\n    with open(script3dtoroidver, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3dtoroidverbox=\"L_Choke_toroid_ver_box.py\"\n    with open(script3dtoroidverbox, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n\n    w = 10; w2=w/3; h = 5; ddrill = 1.0; rm=5.08; rm2=0; iw=w*0.8; ih=rm; R_POW=0; add_description = \"\"; name_additions=[]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidverbox)\n    w = 13; w2=w/3; h = 6.5; ddrill = 1.3; rm=5.6; rm2=0; iw=w*0.8; ih=rm; R_POW=0; add_description = \"\"; name_additions=[]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidverbox)\n    w = 16; w2=w/3; h = 8; ddrill = 1.5; rm=7.62; rm2=0; iw=w*0.8; ih=rm; R_POW=0; add_description = \"\"; name_additions=[]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidverbox)\n    w = 14.73; w2=w/3; h = 8.64; ddrill = 1.8; rm=2.79*2; rm2=0; iw=w*0.8; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"KM-1\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidverbox)\n    w = 16.51; w2=w/3; h = 11.43; ddrill = 1.8; rm=3.81*2; rm2=0; iw=w*0.8; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"KM-2\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidverbox)\n    w = 21.59; w2=w/3; h = 11.43; ddrill = 1.8; rm=3.81*2; rm2=0; iw=w*0.8; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"KM-3\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidverbox)\n    w = 24.64; w2=w/3; h = 15.5; ddrill = 1.8; rm=5.72*2; rm2=0; iw=w*0.8; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"KM-4\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidverbox)\n    w = 33.02; w2=w/3; h = 17.78; ddrill = 1.8; rm=6.35*2; rm2=0; iw=w*0.8; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"KM-5\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidverbox)\n    w = 13.97; w2 = w / 3; h = 6.35; ddrill = 1.5; rm = 4.57; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"A\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 17.78; w2 = w / 3; h = 9.65; ddrill = 1.5; rm = 7.11; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"B\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 21.59; w2 = w / 3; h = 9.53; ddrill = 1.8; rm = 7.11; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"C\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 26.67; w2 = w / 3; h = 13.97; ddrill = 1.8; rm = 10.16; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"D\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 35.56; w2 = w / 3; h = 17.78; ddrill = 1.8; rm = 12.7; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"E\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 41.91; w2 = w / 3; h = 17.78; ddrill = 1.8; rm = 12.7; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"F\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 21.59; w2 = w / 3; h = 8.38; ddrill = 1.5; rm = 8.38; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"G\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 16.26; w2 = w / 3; h = 7.11; ddrill = 1.5; rm = 7.11; R_POW=0; add_description = \"http://datasheet.octopart.com/PE-92112KNL-Pulse-datasheet-17853305.pdf\"; name_additions=[\"Pulse\", \"H\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 16.4; w2=w/3; h = 7.6; ddrill = 1.2; rm=6.6; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ3\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 16.8; w2=w/3; h = 9.2; ddrill = 1.5; rm=7.1; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ3\", \"BigPads\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 16.8; w2=w/3; h = 9.2; ddrill = 1.2; rm=7.1; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ3\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 22.4; w2=w/3; h = 10.2; ddrill = 1.5; rm=7.9; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ4\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 25.4; w2=w/3; h = 14.7; ddrill = 1.5; rm=12.2; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ5\", \"BigPads\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 25.4; w2=w/3; h = 14.7; ddrill = 1.2; rm=12.2; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ5\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 35.1; w2=w/3; h = 21.1; ddrill = 1.5; rm=18.5; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ6\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 41.9; w2=w/3; h = 19.1; ddrill = 1.5; rm=15.8; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ7\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 48.8; w2=w/3; h = 25.4; ddrill = 1.7; rm=20.8; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ8\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 67.6; w2=w/3; h = 36.1; ddrill = 2; rm=31.8; rm2=0; R_POW=0; add_description = \"http://www.vishay.com/docs/34079/tj.pdf\"; name_additions=[\"Vishay\", \"TJ9\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n\n    w = 28.6; w2=w/3; h = 14.3; ddrill = 1.8; rm=11.43; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/5700_series.pdf\"; name_additions=[\"Bourns\", \"5700\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 31.8; w2=w/3; h = 15.9; ddrill = 1.8; rm=13.5; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/5700_series.pdf\"; name_additions=[\"Bourns\", \"5700\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 46; w2=w/3; h = 19.1; ddrill = 1.9; rm=21.8; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/5700_series.pdf\"; name_additions=[\"Bourns\", \"5700\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 54; w2=w/3; h = 23.8; ddrill = 1.8; rm=20.1; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/5700_series.pdf\"; name_additions=[\"Bourns\", \"5700\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 14; w2=w/3; h = 5.6; ddrill = 0.8; rm=5.3; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/5700_series.pdf\"; name_additions=[\"Bourns\", \"5700\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 17.8; w2=w/3; h = 8.1; ddrill = 0.9; rm=7.62; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/5700_series.pdf\"; name_additions=[\"Bourns\", \"5700\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 19.1; w2=w/3; h = 8.1; ddrill = 0.8; rm=7.1; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/5700_series.pdf\"; name_additions=[\"Bourns\", \"5700\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n    w = 21.6; w2=w/3; h = 9.1; ddrill = 1.1; rm=8.4; rm2=0; R_POW=0; add_description = \"http://www.bourns.com/docs/Product-Datasheets/5700_series.pdf\"; name_additions=[\"Bourns\", \"5700\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=w, script3d=script3dtoroidver)\n\n\n\n    type = \"simple\"; classname = \"L_CommonMode_Toroid\"\n    script3dtoroidver4pin = \"L_Choke_toroid_ver_box_4pin.py\"\n    with open(script3dtoroidver4pin, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    w = 0.76*25.4; w2=w/3; h = 0.425*25.4; ddrill = 1.5; rm=0.25*25.4; rm2=0.6*25.4; iw=w; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/8120-RC-Bourns-datasheet-10228452.pdf\"; name_additions=[\"Bourns\", \"8100\"]\n    makeResistorRadial(pins=4, seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=31, script3d=script3dtoroidver4pin)\n    w = 1.2*25.4; w2=w/3; h = 0.6*25.4; ddrill = 1.5; rm=0.4*25.4; rm2=0.8*25.4; iw=w; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/8120-RC-Bourns-datasheet-10228452.pdf\"; name_additions=[\"Bourns\", \"8100\"]\n    makeResistorRadial(pins=4, seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=31, script3d=script3dtoroidver4pin)\n    w = 1.35*25.4; w2=w/3; h = 0.8*25.4; ddrill = 1.5; rm=0.6*25.4; rm2=0.9*25.4; iw=w; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/8120-RC-Bourns-datasheet-10228452.pdf\"; name_additions=[\"Bourns\", \"8100\"]\n    makeResistorRadial(pins=4, seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=31, script3d=script3dtoroidver4pin)\n    w = 1.45*25.4; w2=w/3; h = 0.8*25.4; ddrill = 1.5; rm=0.6*25.4; rm2=0.9*25.4; iw=w; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/8120-RC-Bourns-datasheet-10228452.pdf\"; name_additions=[\"Bourns\", \"8100\"]\n    makeResistorRadial(pins=4, seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=31, script3d=script3dtoroidver4pin)\n    w = 1.50*25.4; w2=w/3; h = 0.8*25.4; ddrill = 1.8; rm=0.6*25.4; rm2=0.9*25.4; iw=w; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/8120-RC-Bourns-datasheet-10228452.pdf\"; name_additions=[\"Bourns\", \"8100\"]\n    makeResistorRadial(pins=4, seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=31, script3d=script3dtoroidver4pin)\n    w = 1.55*25.4; w2=w/3; h = 0.8*25.4; ddrill = 1.5; rm=0.6*25.4; rm2=0.9*25.4; iw=w; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/8120-RC-Bourns-datasheet-10228452.pdf\"; name_additions=[\"Bourns\", \"8100\"]\n    makeResistorRadial(pins=4, seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=31, script3d=script3dtoroidver4pin)\n    w = 1.65*25.4; w2=w/3; h = 0.8*25.4; ddrill = 1.5; rm=0.6*25.4; rm2=0.9*25.4; iw=w; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/8120-RC-Bourns-datasheet-10228452.pdf\"; name_additions=[\"Bourns\", \"8100\"]\n    makeResistorRadial(pins=4, seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=31, script3d=script3dtoroidver4pin)\n    w = 1.7*25.4; w2=w/3; h = 0.9*25.4; ddrill = 2.2; rm=0.7*25.4; rm2=1.2*25.4; iw=w; ih=rm; R_POW=0; add_description = \"http://datasheet.octopart.com/8120-RC-Bourns-datasheet-10228452.pdf\"; name_additions=[\"Bourns\", \"8100\"]\n    makeResistorRadial(pins=4, seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=31, script3d=script3dtoroidver4pin)\n    w = 21; w2=w/3; h = 10; ddrill = 1.1; rm=5.08; rm2=12.7; iw=w; ih=rm; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_5100.pdf\"; name_additions=[\"muRATA\", \"5100\"]\n    makeResistorRadial(pins=4, seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=31, script3d=script3dtoroidver4pin)\n    w = 24; w2=w/3; h = 16.3; ddrill = 1.1; rm=10.16; rm2=20.32; iw=w; ih=rm; R_POW=0; add_description = \"http://www.murata-ps.com/data/magnetics/kmp_5200.pdf\"; name_additions=[\"muRATA\", \"5200\"]\n    makeResistorRadial(pins=4, seriesname=seriesname, rm=rm, w=w, h=h, innerw=iw, innerh=ih, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, deco=deco, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=31, script3d=script3dtoroidver4pin)\n\n\n\n    rm2=0; w2=0\n    type = \"round\"; seriesname = \"Radial\";\n    deco=\"\"\n    classname = \"L\"\n    libname = \"${KISYS3DMOD}/Inductor_THT\"\n    w = 12.0; w2=w; h = w; ddrill = 1.2; rm=10.0; rm2=0; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_Sd12k.pdf\"; name_additions=[\"Neosid\", \"SD12k\", \"style1\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=13, script3d=script3drrs)\n    w = 12.0; w2=w; h = w; ddrill = 1.2; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_Sd12k.pdf\"; name_additions=[\"Neosid\", \"SD12k\", \"style2\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=13, script3d=script3drrs)\n    w = 10.0; w2=w; h = w; ddrill = 1.2; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_Sd12k.pdf\"; name_additions=[\"Neosid\", \"SD12k\", \"style3\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=12.5, script3d=script3drrs)\n    w = 12.0; w2=w; h = w; ddrill = 1.2; rm=10.0; rm2=0; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_Sd12.pdf\"; name_additions=[\"Neosid\", \"SD12\", \"style1\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=20, script3d=script3drrs)\n    w = 12.0; w2=w; h = w; ddrill = 1.2; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_Sd12.pdf\"; name_additions=[\"Neosid\", \"SD12\", \"style2\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=20, script3d=script3drrs)\n    w = 10.0; w2=w; h = w; ddrill = 1.2; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_Sd12.pdf\"; name_additions=[\"Neosid\", \"SD12\", \"style3\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=19.5, script3d=script3drrs)\n    w = 14.2; w2=w; h = w; ddrill = 1.2; rm=10.0; rm2=0; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_Sd14.pdf\"; name_additions=[\"Neosid\", \"SD14\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=24.5, script3d=script3drrs)\n\n    type = \"simple\";\n    w = 7.5; w2=w; h = 4.6; ddrill = 0.8; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_Sd75.pdf\"; name_additions=[\"Neosid\", \"SD75\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=10.5, script3d=script3drbox)\n    w = 8; w2=w; h = 8; ddrill = 0.8; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_Sd8.pdf\"; name_additions=[\"Neosid\", \"SD8\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=9.6, script3d=script3drbox)\n    w = 8; w2=w; h = 8; ddrill = 1.2; rm=5.0; rm2=0; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_NE_CPB07E.pdf\"; name_additions=[\"Neosid\", \"NE-CPB-07E\"]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=7.5, script3d=script3drbox)\n    type = \"simplesymm45\";\n    w = 11.5; w2=w; h = 11.5; ddrill = 1.8; rm=6.0; rm2=6; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_NE_CPB11EN.pdf\"; name_additions=[\"Neosid\", \"NE-CPB-11EN\", \"Drill{0:0.1f}mm\".format(ddrill)]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=9.6, script3d=script3drbox)\n    w = 11.5; w2=w; h = 11.5; ddrill = 1.7; rm=6.0; rm2=6; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_NE_CPB11EN.pdf\"; name_additions=[\"Neosid\", \"NE-CPB-11EN\", \"Drill{0:0.1f}mm\".format(ddrill)]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=9.6, script3d=script3drbox)\n    w = 11.5; w2=w; h = 11.5; ddrill = 1.5; rm=6.0; rm2=6; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_NE_CPB11EN.pdf\"; name_additions=[\"Neosid\", \"NE-CPB-11EN\", \"Drill{0:0.1f}mm\".format(ddrill)]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=9.6, script3d=script3drbox)\n    w = 11.5; w2=w; h = 11.5; ddrill = 1.3; rm=6.0; rm2=6; R_POW=0; add_description = \"http://www.neosid.de/produktblaetter/neosid_Festinduktivitaet_NE_CPB11EN.pdf\"; name_additions=[\"Neosid\", \"NE-CPB-11EN\", \"Drill{0:0.1f}mm\".format(ddrill)]\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=name_additions, add_description=add_description, classname=classname, lib_name=libname, height3d=9.6, script3d=script3drbox)\n"
  },
  {
    "path": "scripts/Connector/Connector_Audio/Jack_3.5mm_Switronic_ST-005-G_horizontal.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))\n\nfrom KicadModTree import *\n\ndatasheet = \"http://akizukidenshi.com/download/ds/switronic/ST-005-G.pdf\"\nfootprint_name = \"Jack_3.5mm_Switronic_ST-005-G_horizontal\"\n\nbaseWidth = 11.5\nbaseHeight = 6.5\noutletHeight = 5.0\noutletWidth = 2.5\n\npadHoleSize = 1.2\nmountingHoleSize = 1.0\n\nfrontPadOffset = 3.5\nfrontPadSpacing = 5.8\nmountingHoleOffset = 7.0\nmountingHoleSpacing = 5.0\nbackPadOffset = 11.0\nbackPadSpacing = 4.5\n\nf = Footprint(footprint_name)\nf.setDescription(datasheet)\nf.setTags(\"Connector Audio Switronic ST-005-G\")\nf.append(Model(filename=\"${KISYS3DMOD}/Connector_Audio.3dshapes/\" + footprint_name + \".wrl\",\n               at=[0.0, 0.0, 0.0],\n               scale=[1.0, 1.0, 1.0],\n               rotate=[0.0, 0.0, 0.0]))\n\ns = [1.0, 1.0]\nsFabRef = [0.7, 0.7]\n\nt1 = 0.1\nt2 = 0.15\n\nwCrtYd = 0.05\nwFab = 0.1\nwSilkS = 0.12\ncrtYdClearance = 0.5\nsilkClearance = 0.2\n\npadSizeDiffFromHole = 0.7\npadSize = [padHoleSize + padSizeDiffFromHole, padHoleSize + padSizeDiffFromHole]\npadDrill = [padHoleSize, padHoleSize]\n\nxCenter = 0.0\nxFabBaseLeft = outletWidth - ((baseWidth + outletWidth) / 2)\nxFrontPad = xFabBaseLeft + frontPadOffset\nxMountingHole = xFabBaseLeft + mountingHoleOffset\nxBackPad = xFabBaseLeft + backPadOffset\nxFabRight = (outletWidth + baseWidth) / 2\nxSilkRight = xFabRight + silkClearance\nxSilkFrontPadRight = xFrontPad + padHoleSize\nxRightCrtYd = xBackPad + padSize[0] / 2 + crtYdClearance\n\nxFabLeft = -xFabRight\nxLeftCrtYd = xFabLeft - crtYdClearance\nxSilkBaseLeft = xFabBaseLeft - silkClearance\nxSilkLeft = -xSilkRight\nxSilkFrontPadLeft = xFrontPad - padHoleSize\nxSilkBackPadLeft = xBackPad - padHoleSize\n\nyCenter = 0.0\nyFrontPadBottom = frontPadSpacing / 2\nyMountingHoleBottom = mountingHoleSpacing / 2\nyBackPadBottom = backPadSpacing / 2\nyFabOutletBottom = outletHeight / 2\nyFabBottom = baseHeight / 2\nySilkBottom = yFabBottom + silkClearance\nySilkOutletBottom = yFabOutletBottom + silkClearance\nySilkBackPadBottom = yBackPadBottom - padHoleSize\nyBottomCrtYd = yFrontPadBottom + padSize[0] / 2 + crtYdClearance\n\nyFrontPadTop = -yFrontPadBottom\nyMountingHoleTop = -yMountingHoleBottom\nyBackPadTop = -yBackPadBottom\nyFabTop = -yFabBottom\nyFabOutletTop = -yFabOutletBottom\nySilkTop = -ySilkBottom\nySilkOutletTop = -ySilkOutletBottom\nySilkBackPadTop = -ySilkBackPadBottom\nyTopCrtYd = -yBottomCrtYd\n\nyValue = yFabBottom + 1.25\nyRef = yFabTop - 1.25\n\nf.append(Text(type=\"reference\", text=\"REF**\", at=[xCenter, yRef],\n              layer=\"F.SilkS\", size=s, thickness=t2))\nf.append(Text(type=\"value\", text=footprint_name, at=[xCenter, yValue],\n              layer=\"F.Fab\", size=s, thickness=t2))\nf.append(Text(type=\"user\", text=\"%R\", at=[xCenter, yCenter],\n              layer=\"F.Fab\", size=sFabRef, thickness=t1))\n\nf.append(RectLine(start=[xLeftCrtYd, yTopCrtYd],\n                  end=[xRightCrtYd, yBottomCrtYd],\n                  layer=\"F.CrtYd\", width=wCrtYd))\n\nf.append(Circle(center=[xBackPad, ySilkBackPadTop], radius=0.3, layer=\"F.Fab\"))\nf.append(PolygoneLine(polygone=[[xFabLeft, yFabOutletTop],\n                                [xFabBaseLeft, yFabOutletTop],\n                                [xFabBaseLeft, yFabTop],\n                                [xFabRight, yFabTop],\n                                [xFabRight, yFabBottom],\n                                [xFabBaseLeft, yFabBottom],\n                                [xFabBaseLeft, yFabOutletBottom],\n                                [xFabLeft, yFabOutletBottom],\n                                [xFabLeft, yFabOutletTop]],\n                      layer=\"F.Fab\", width=wFab))\n\nf.append(PolygoneLine(polygone=[[xSilkFrontPadLeft, ySilkBottom],\n                                [xSilkBaseLeft, ySilkBottom],\n                                [xSilkBaseLeft, ySilkOutletBottom]],\n                      layer=\"F.SilkS\", width=wSilkS))\nf.append(PolygoneLine(polygone=[[xSilkBaseLeft, ySilkOutletTop],\n                                [xSilkBaseLeft, ySilkTop],\n                                [xSilkFrontPadLeft, ySilkTop]],\n                      layer=\"F.SilkS\", width=wSilkS))\nf.append(Line(start=[xSilkFrontPadRight, ySilkTop],\n              end=[xSilkBackPadLeft, ySilkTop],\n              layer=\"F.SilkS\", width=wSilkS))\nf.append(Line(start=[xSilkFrontPadRight, ySilkBottom],\n              end=[xSilkRight, ySilkBottom],\n              layer=\"F.SilkS\", width=wSilkS))\nf.append(Line(start=[xSilkRight, ySilkBackPadTop],\n              end=[xSilkRight, ySilkBackPadBottom],\n              layer=\"F.SilkS\", width=wSilkS))\n\nf.append(Pad(number=\"T\", type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n             at=[xFrontPad, yFrontPadTop], size=padSize,\n             drill=padDrill, layers=['*.Cu', '*.Mask']))\nf.append(Pad(number=\"T\", type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n             at=[xFrontPad, yFrontPadBottom], size=padSize,\n             drill=padDrill, layers=['*.Cu', '*.Mask']))\nf.append(Pad(number=\"R\", type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n             at=[xBackPad, yBackPadTop], size=padSize,\n             drill=padDrill, layers=['*.Cu', '*.Mask']))\nf.append(Pad(number=\"S\", type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n             at=[xBackPad, yBackPadBottom], size=padSize,\n             drill=padDrill, layers=['*.Cu', '*.Mask']))\nf.append(Pad(type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n             at=[xMountingHole, yMountingHoleBottom], size=mountingHoleSize,\n             drill=mountingHoleSize, layers=Pad.LAYERS_NPTH))\nf.append(Pad(type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n             at=[xMountingHole, yMountingHoleTop], size=mountingHoleSize,\n             drill=mountingHoleSize, layers=Pad.LAYERS_NPTH))\n\nfile_handler = KicadFileHandler(f)\nfile_handler.writeFile(footprint_name + \".kicad_mod\")\n"
  },
  {
    "path": "scripts/Connector/Connector_Harwin/conn_harwin_m20-781xx45_smd_top_dual_row.py",
    "content": "#!/usr/bin/env python3\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\n#from helpers import *\nfrom KicadModTree import *\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = 'M20'\nseries_long = 'Female Vertical Surface Mount Double Row 2.54mm (0.1 inch) Pitch PCB Connector'\nmanufacturer = 'Harwin'\ndatasheet = 'https://cdn.harwin.com/pdfs/M20-781.pdf'\n# https://cdn.harwin.com/pdfs/Harwin_Product_Catalog_page_225.pdf\npn = 'M20-781{n:02}45'\nnumber_of_rows = 2\norientation = 'V'\n\npitch = 2.54\npeg_drill_tht = 1.02\nmount_drill = 1.8\npad_size = [1.78, 1.02]\n\npincount_range = [2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20]\n\ndef generate_footprint(pins, configuration):\n\n    mpn = pn.format(n=pins)\n    pins_per_row = pins\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    print(footprint_name)\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Harwin {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    kicad_mod.setAttribute('smd')\n\n    ########################## Dimensions ##############################\n\n    A = 2.54 * pins\n    B = 2.54 * (pins-1)\n    C = B - 2.54\n\n    body_edge={\n        'left': -2.54,\n        'right': 2.54,\n        'top': -A/2,\n        'bottom': A/2\n    }\n\n    ############################# Pads ##################################\n    #\n    # Mount Pegs\n    #\n    if pins == 2:\n        kicad_mod.append(Pad(at=[0, 0], number=\"\",\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=mount_drill,\n            drill=mount_drill, layers=Pad.LAYERS_NPTH))\n    else:\n        kicad_mod.append(Pad(at=[0, -C/2], number=\"\",\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=mount_drill,\n            drill=mount_drill, layers=Pad.LAYERS_NPTH))\n        kicad_mod.append(Pad(at=[0, C/2], number=\"\",\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=mount_drill,\n            drill=mount_drill, layers=Pad.LAYERS_NPTH))\n\n    for pin in range(pins):\n        for x_pitch in [1.27, -1.27]:\n            kicad_mod.append(Pad(at=[x_pitch, -B/2 + pin*pitch], number=\"\",\n                type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n                size=peg_drill_tht, drill=peg_drill_tht, layers=Pad.LAYERS_NPTH))\n\n    #\n    # Add pads\n    #\n    kicad_mod.append(PadArray(start=[-2.91, -B/2], initial=1,\n        pincount=pins, increment=1,  y_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(start=[2.91, -B/2], initial=pins+1,\n        pincount=pins, increment=1,  y_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=Pad.LAYERS_SMT))\n\n    ######################## Fabrication Layer ###########################\n    main_body_poly= [\n        {'x': body_edge['left'], 'y': body_edge['top']},\n        {'x': body_edge['right'], 'y': body_edge['top']},\n        {'x': body_edge['right'], 'y': body_edge['bottom']},\n        {'x': body_edge['left'], 'y': body_edge['bottom']},\n        {'x': body_edge['left'], 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_body_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    main_arrow_poly= [\n        {'x': -2.54, 'y': body_edge['top'] + 1.27 - .4},\n        {'x': -1.9, 'y': body_edge['top'] + 1.27},\n        {'x': -2.54, 'y': body_edge['top'] + 1.27 + .4},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_arrow_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    ######################## SilkS Layer ###########################\n    poly_s_top= [\n        {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': body_edge['top'] - configuration['silk_fab_offset'] + .7},\n        {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': body_edge['top'] - configuration['silk_fab_offset']},\n        {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': body_edge['top'] - configuration['silk_fab_offset']},\n        {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': body_edge['top'] - configuration['silk_fab_offset'] + .7},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_s_top,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    poly_s_bot= [\n        {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': body_edge['bottom'] + configuration['silk_fab_offset'] - .7},\n        {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': body_edge['bottom'] + configuration['silk_fab_offset']},\n        {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': body_edge['bottom'] + configuration['silk_fab_offset']},\n        {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': body_edge['bottom'] + configuration['silk_fab_offset'] - .7},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_s_bot,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    ######################## CrtYd Layer ###########################\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n\n    poly_yd = [\n        {'x': -3.8 - CrtYd_offset, 'y': body_edge['top'] - CrtYd_offset},\n        {'x': 3.8 + CrtYd_offset, 'y': body_edge['top'] - CrtYd_offset},\n        {'x': 3.8 + CrtYd_offset, 'y': body_edge['bottom'] + CrtYd_offset},\n        {'x': -3.8 - CrtYd_offset, 'y': body_edge['bottom'] + CrtYd_offset},\n        {'x': -3.8 - CrtYd_offset, 'y': body_edge['top'] - CrtYd_offset}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_yd,\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    cy1 = body_edge['top'] - configuration['courtyard_offset']['connector']\n    cy2 = body_edge['bottom'] + configuration['courtyard_offset']['connector'] + 0.2\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Write to File and 3D ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pincount_range:\n        generate_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Harwin/m20-89xx.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\n\nfrom footprint_text_fields import addTextFields\nimport argparse\nimport yaml\nfrom KicadModTree import *\n\nseries = 'M20-890'\nseries_long = 'Male Horizontal Surface Mount Single Row 2.54mm (0.1 inch) Pitch PCB Connector'\nmanufacturer = 'Harwin'\npitch = 2.54\ndatasheet = 'https://cdn.harwin.com/pdfs/M20-890.pdf'\npin_min = 3\npin_max = 20\nmpn = 'M20-890{pincount:02g}xx'\npadsize = [2.5, 1]\n\ndef roundToBase(value, base):\n    if base == 0:\n        return value\n    return round(value/base) * base\n\ndef gen_fab_pins(origx, origy, kicad_mod, configuration):\n    poly_f_back = [\n        {'x': origx+3.8, 'y': origy-0.64/2},\n        {'x': origx-0.9, 'y': origy-0.64/2},\n        {'x': origx-0.9, 'y': origy+0.64/2},\n        {'x': origx+3.8, 'y': origy+0.64/2},\n    ]\n    poly_f_front = [\n        {'x': origx+6.3, 'y': origy-0.64/2},\n        {'x': origx+12.3, 'y': origy-0.64/2},\n        {'x': origx+12.3, 'y': origy+0.64/2},\n        {'x': origx+6.3, 'y': origy+0.64/2},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_f_back,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n    kicad_mod.append(PolygoneLine(polygone=poly_f_front,\n       width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\ndef gen_silk_pins(origx, origy, kicad_mod, configuration, fill):\n    poly_s_back1 = [\n        {'x': origx+2.5/2+configuration['silk_pad_clearance']+configuration['silk_line_width'], 'y': origy-0.64/2-configuration['silk_line_width']},\n        {'x': origx+3.8-configuration['silk_line_width'], 'y': origy-0.64/2-configuration['silk_line_width']},\n    ]\n    poly_s_back2 = [\n        {'x': origx+2.5/2+configuration['silk_pad_clearance']+configuration['silk_line_width'], 'y': origy+0.64/2+configuration['silk_line_width']},\n        {'x': origx+3.8-configuration['silk_line_width'], 'y': origy+0.64/2+configuration['silk_line_width']},\n    ]\n    poly_s_front = [\n        {'x': origx+6.3+configuration['silk_line_width'], 'y': origy-0.64/2-configuration['silk_line_width']},\n        {'x': origx+12.3+configuration['silk_line_width'], 'y': origy-0.64/2-configuration['silk_line_width']},\n        {'x': origx+12.3+configuration['silk_line_width'], 'y': origy+0.64/2+configuration['silk_line_width']},\n        {'x': origx+6.3+configuration['silk_line_width'], 'y': origy+0.64/2+configuration['silk_line_width']},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_s_back1,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    kicad_mod.append(PolygoneLine(polygone=poly_s_back2,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    kicad_mod.append(PolygoneLine(polygone=poly_s_front,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    if fill:\n        kicad_mod.append(Pad(type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, at=[origx+configuration['silk_line_width']+(6.3+12.3)/2, origy], size=[6, 0.64+configuration['silk_line_width']], layers=[\"F.SilkS\"]))\n\ndef gen_footprint(pinnum, manpart, configuration):\n    orientation_str = configuration['orientation_options']['H']\n    footprint_name = configuration['fp_name_format_string'].format(\n        man=manufacturer,\n        series='',\n        mpn=manpart,\n        num_rows=1,\n        pins_per_row=pinnum,\n        mounting_pad=\"\",\n        pitch=pitch,\n        orientation=orientation_str)\n    footprint_name = footprint_name.replace('__','_')\n\n    print(footprint_name)\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"{manufacturer} {series}, {mpn}{alt_mpn}, {pins_per_row} Pins per row ({datasheet}), generated with kicad-footprint-generator\".format(\n        manufacturer = manufacturer,\n        series = series_long,\n        mpn = manpart, \n        alt_mpn = '', \n        pins_per_row = pinnum,\n        datasheet = datasheet))\n        \n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry='horizontal'))\n\n    kicad_mod.setAttribute('smd')\n    \n    # Pads\n    kicad_mod.append(PadArray(start=[-6.775+padsize[0]/2, -(pitch*(pinnum-1))/2], initial=1,\n        pincount=pinnum, increment=1,  y_spacing=pitch, size=padsize,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=Pad.LAYERS_SMT, drill=None))\n\n    # Fab\n    for y in range(0, pinnum):\n        gen_fab_pins(-6.775+padsize[0]/2, -(pitch*(pinnum-1))/2+pitch+(y-1)*2.54, kicad_mod, configuration)\n    poly_f_body = [\n        {'x': -6.775+padsize[0]/2+3.8, 'y': -(pitch*(pinnum-1))/2-pitch-2.54/2+0.4+2.54},\n        {'x': -6.775+padsize[0]/2+3.8+0.4, 'y': -(pitch*(pinnum-1))/2-pitch-2.54/2+2.54},\n        {'x': -6.775+padsize[0]/2+6.3, 'y': -(pitch*(pinnum-1))/2-pitch-2.54/2+2.54},\n        {'x': -6.775+padsize[0]/2+6.3, 'y': -(pitch*(pinnum-1))/2-pitch-2.54/2+2.54*pinnum+2.54},\n        {'x': -6.775+padsize[0]/2+3.8, 'y': -(pitch*(pinnum-1))/2-pitch-2.54/2+2.54*pinnum+2.54},\n        {'x': -6.775+padsize[0]/2+3.8, 'y': -(pitch*(pinnum-1))/2-pitch-2.54/2+0.4+2.54},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_f_body,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    # SilkS\n    silkslw = configuration['silk_line_width']\n    s_body = [\n        {'x': -6.775+padsize[0]/2+3.8-silkslw, 'y': -(pitch*(pinnum-1))/2-pitch-2.54/2-silkslw+2.54},\n        {'x': -6.775+padsize[0]/2+6.3+silkslw, 'y': -(pitch*(pinnum-1))/2-pitch-2.54/2-silkslw+2.54},\n        {'x': -6.775+padsize[0]/2+6.3+silkslw, 'y': -(pitch*(pinnum-1))/2-pitch-2.54/2+2.54*pinnum+silkslw+2.54},\n        {'x': -6.775+padsize[0]/2+3.8-silkslw, 'y': -(pitch*(pinnum-1))/2-pitch-2.54/2+2.54*pinnum+silkslw+2.54},\n        {'x': -6.775+padsize[0]/2+3.8-silkslw, 'y': -(pitch*(pinnum-1))/2-pitch-2.54/2-silkslw+2.54},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=s_body,\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    for y in range(0, pinnum):\n        gen_silk_pins(-6.775+padsize[0]/2, -(pitch*(pinnum-1))/2+pitch+(y-1)*2.54, kicad_mod, configuration, y==0)\n    s_pin1 = [\n        {'x': -6.775+padsize[0]/2-(2.5/2+configuration['silk_pad_clearance']+configuration['silk_line_width']), 'y': -(pitch*(pinnum-1))/2},\n        {'x': -6.775+padsize[0]/2-(2.5/2+configuration['silk_pad_clearance']+configuration['silk_line_width']), 'y': -(pitch*(pinnum-1))/2-1/2-configuration['silk_line_width']-configuration['silk_pad_clearance']},\n        {'x': -6.775+padsize[0]/2, 'y': -(pitch*(pinnum-1))/2-1/2-configuration['silk_line_width']-configuration['silk_pad_clearance']},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=s_pin1,\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    \n    \n    # CrtYd\n    cy_offset = configuration['courtyard_offset']['connector']\n    cy_grid = configuration['courtyard_grid']\n    bounding_box={\n        'left': -6.775+padsize[0]/2-2.5/2,\n        'right': -6.775+padsize[0]/2+12.3,\n        'top': -(pitch*(pinnum-1))/2-pitch-2.54/2+2.54,\n        'bottom': -(pitch*(pinnum-1))/2-pitch-2.54/2+2.54*pinnum+2.54,\n    }\n    cy_top = roundToBase(bounding_box['top'] - cy_offset, cy_grid)\n    cy_bottom = roundToBase(bounding_box['bottom'] + cy_offset, cy_grid)\n    cy_left = roundToBase(bounding_box['left'] - cy_offset, cy_grid)\n    cy_right = roundToBase(bounding_box['right'] + cy_offset, cy_grid)\n    poly_cy = [\n        {'x': cy_left, 'y': cy_top},\n        {'x': cy_right, 'y': cy_top},\n        {'x': cy_right, 'y': cy_bottom},\n        {'x': cy_left, 'y': cy_bottom},\n        {'x': cy_left, 'y': cy_top},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_cy,\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    # Text Fields\n    body_edge={\n        'left': -6.775+padsize[0]/2+3.8,\n        'right': -6.775+padsize[0]/2+6.3,\n        'top': -(pitch*(pinnum-1))/2-pitch-2.54/2-silkslw+2.54,\n        'bottom': -(pitch*(pinnum-1))/2-pitch-2.54/2+2.54*pinnum+silkslw+2.54,\n    }\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy_top, 'bottom':cy_bottom}, fp_name=footprint_name, text_y_inside_position='center', allow_rotation=True)\n\n    # 3D model\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n    \n    # Output\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\ndef gen_family(configuration):\n    for x in range(pin_min, pin_max+1):\n        gen_footprint(x, mpn.format(pincount=x), configuration)\n\nif __name__ == \"__main__\":\n\tparser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n\tparser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n\tparser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n\targs = parser.parse_args()\n\n\twith open(args.global_config, 'r') as config_stream:\n\t\ttry:\n\t\t\tconfiguration = yaml.safe_load(config_stream)\n\t\texcept yaml.YAMLError as exc:\n\t\t\tprint(exc)\n\n\twith open(args.series_config, 'r') as config_stream:\n\t\ttry:\n\t\t\tconfiguration.update(yaml.safe_load(config_stream))\n\t\texcept yaml.YAMLError as exc:\n\t\t\tprint(exc)\n\n\tgen_family(configuration)"
  },
  {
    "path": "scripts/Connector/Connector_Hirose/00-SMD footprint generators can be found in Connector_SMD_single_row_plus_mounting_pad.md",
    "content": "The following connector footprints are generated in the generic scirpt located in ../Connector_SMD_single_row_plus_mounting_pad/\n\n- DF52\n"
  },
  {
    "path": "scripts/Connector/Connector_Hirose/conn_ffc_hirose_fh12_smd_side.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\nfrom footprint_keepout_area import addRectangularKeepout\n\nseries = 'FH12'\nseries_long = 'FH12, FFC/FPC connector'\nmanufacturer = 'Hirose'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'https://www.hirose.com/product/en/products/FH12/FH12-24S-0.5SH(55)/'\n\nconn_category = \"FFC-FPC\"\n\nlib_by_conn_category = True\n\n#pins_per_row per row\npins_per_row_range = [6,8,10,11,12,13,14,15,16,17,18,19,20,22,24,25,26,28,30,32,33,34,35,36,40,45,50,53]\n\npart_code = \"FH12-{n:d}S-0.5SH\"\n\n# x position mounting inner mounting pad edge relative to nearest pad center\ncenter_pad_to_mounting_pad_edge = 1\n# y dimensions for pad given relative to mounting pad edge\nrel_pad_y_outside_edge = 5\nrel_pad_y_inside_edge = 3.7\npad_size_x = 0.3\n# y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\nrel_body_edge_y = 1.9\nbody_size_y = 5.6\n# body_fin_protrusion: 1.6\n# body_fin_width: 0.8\n# x body edge relative to nearest pin\nrel_body_edge_x = 1.8\n\n\npitch = 0.5\npad_size = [pad_size_x, rel_pad_y_outside_edge - rel_pad_y_inside_edge]\nmp_size = [1.8, 2.2]\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_code.format(n=pins)\n    pad_silk_off = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n    off = configuration['silk_fab_offset']\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_no_series_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"-1MP\",\n        pitch=pitch, orientation=orientation_str)\n\n    footprint_name = footprint_name.replace(\"__\",'_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setAttribute('smd')\n    kicad_mod.setDescription(\"{:s} {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(manufacturer, series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    A = (pins - 1) * pitch\n    B = A + 2*rel_body_edge_x\n    pad_y = -rel_pad_y_outside_edge/2 + pad_size[1]/2\n    mpad_y = rel_pad_y_outside_edge/2 - mp_size[1]/2\n    mpad_x = A/2 + center_pad_to_mounting_pad_edge + mp_size[0]/2\n\n    kicad_mod.append(Pad(number=configuration['mounting_pad_number'], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                        at=[mpad_x, mpad_y], size=mp_size, layers=Pad.LAYERS_SMT))\n    kicad_mod.append(Pad(number=configuration['mounting_pad_number'], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                        at=[-mpad_x, mpad_y], size=mp_size, layers=Pad.LAYERS_SMT))\n\n    # create pads\n    #createNumberedPadsTHT(kicad_mod, pincount, pitch, drill, {'x':x_dia, 'y':y_dia})\n    kicad_mod.append(PadArray(center=[0,pad_y], pincount=pins, x_spacing=pitch,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=pad_size, layers=Pad.LAYERS_SMT))\n\n\n    x1 = -B/2\n    x2 = x1 + B\n    y2 = mpad_y + mp_size[1]/2 + rel_body_edge_y\n    y1 = y2 - body_size_y\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n\n    bounding_box = body_edge.copy()\n    bounding_box['top'] = pad_y - pad_size[1]/2\n    bb_x = mpad_x + mp_size[0]/2\n    if  bb_x > x2:\n        bounding_box['left'] = -bb_x\n        bounding_box['right'] = bb_x\n\n\n    main_body_bottom = body_edge['top'] + 4.6\n    gap_body_hatch = 0.3\n    gab_body_hatch_depth = 0.6\n    hatch_reduced_width = 0.2\n\n    poly_outline = [\n        {'x': 0, 'y':  body_edge['top']},\n        {'x': body_edge['left'], 'y':  body_edge['top']},\n        {'x': body_edge['left'], 'y':  main_body_bottom},\n        {'x': body_edge['left'] + gab_body_hatch_depth, 'y':  main_body_bottom},\n        {'x': body_edge['left'] + gab_body_hatch_depth, 'y':  main_body_bottom + gap_body_hatch},\n        {'x': body_edge['left'] + hatch_reduced_width/2, 'y':  main_body_bottom + gap_body_hatch},\n        {'x': body_edge['left'] + hatch_reduced_width/2, 'y':  body_edge['bottom']},\n        {'x': 0, 'y':  body_edge['bottom']}\n    ]\n    kicad_mod.append(PolygoneLine(\n        polygone=poly_outline,\n        layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(\n        polygone=poly_outline, x_mirror = 0.0000000001,\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    #line offset\n    off = 0.1\n\n    x1 -= off\n    y1 -= off\n\n    x2 += off\n    y2 += off\n\n    #draw the main outline around the footprint\n    silk_pad_x_left = -A/2 - pad_size[0]/2 - pad_silk_off\n    silk_mp_top = mpad_y - mp_size[1]/2 - pad_silk_off\n    silk_mp_bottom = mpad_y + mp_size[1]/2 + pad_silk_off\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': silk_pad_x_left,'y':y1},\n            {'x': x1,'y':y1},\n            {'x': x1,'y':silk_mp_top}\n        ],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': -silk_pad_x_left,'y':y1},\n            {'x': x2,'y':y1},\n            {'x': x2,'y':silk_mp_top}\n        ],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': x1,'y':silk_mp_bottom},\n            {'x': x1,'y':y2},\n            {'x': x2,'y':y2},\n            {'x': x2,'y':silk_mp_bottom}\n        ],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n    #add pin-1 marker\n\n    kicad_mod.append(Line(\n        start=[silk_pad_x_left, y1], end=[silk_pad_x_left, pad_y - pad_size[1]/2],\n                layer='F.SilkS', width=configuration['silk_line_width']))\n\n    sl=1\n    pin = [\n        {'y': body_edge['top'], 'x': -A/2-sl/2},\n        {'y': body_edge['top'] + sl/sqrt(2), 'x': -A/2},\n        {'y': body_edge['top'], 'x': -A/2+sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n\n    ########################### KEEPOUT #################################\n\n    # k_top = pad_y + pad_size[1]/2 + 0.1\n    # k_size = [A + pad_size[0], 2.37]\n    # addRectangularKeepout(kicad_mod, [0, k_top+k_size[1]/2], k_size)\n\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n\n    if lib_by_conn_category:\n        lib_name = configuration['lib_name_specific_function_format_string'].format(category=conn_category)\n    else:\n        lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Hirose/conn_hirose_df11_tht_top.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = 'DF11'\nseries_long = 'DF11 through hole'\nmanufacturer = 'Hirose'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'https://www.hirose.com/product/document?clcode=&productname=&series=DF11&documenttype=Catalog&lang=en&documentid=D31688_en'\n\n# pins_per_row per row\npins_per_row_range = range(2,17)\n\n# Part number\n# n = number of circuits total\npart_code = \"DF11-{n}DP-2DSA\"\n\npitch = 2\ndrill = 0.85\n\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.4\nmin_annular_ring = 0.15\n\n\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\n\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_code.format(n=pins*2)\n    pad_silk_off = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_no_series_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    footprint_name = footprint_name.replace(\"__\",'_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"{:s} {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(manufacturer, series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    A = (pins - 1) * pitch\n    B = A + 4\n\n    # create pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for initial, initial_y in zip([1, 2], [0, pitch]):\n        kicad_mod.append(PadArray(start=[0, initial_y], initial=initial, increment=2, pincount=pins, x_spacing=pitch,\n            type=Pad.TYPE_THT, shape=pad_shape, size=pad_size,\n            drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    x1 = -(B-A) / 2\n    y1 = -1.5\n    x2 = x1 + B\n    y2 = 1.5 + pitch\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n\n    # Fab\n    kicad_mod.append(RectLine(\n        start={'x': x1,'y': y1}, end={'x': x2,'y': y2},\n        layer='F.Fab', width=configuration['fab_line_width']))\n    sl=1\n    pin = [\n        {'y': body_edge['top'], 'x': -sl/2},\n        {'y': body_edge['top'] + sl/sqrt(2), 'x': 0},\n        {'y': body_edge['top'], 'x': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    #line offset\n    off = 0.1\n\n    x1 -= off\n    y1 -= off\n\n    x2 += off\n    y2 += off\n\n    #draw the main outline around the footprint\n    kicad_mod.append(RectLine(start={'x':x1,'y':y1},end={'x':x2,'y':y2},\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add pin-1 marker\n    p1_off = configuration['silk_fab_offset'] + 0.3\n    L = 1.5\n    pin = [\n        {'y': body_edge['top'] + L, 'x': body_edge['left'] - p1_off},\n        {'y': body_edge['top'] - p1_off, 'x': body_edge['left'] - p1_off},\n        {'y': body_edge['top'] - p1_off, 'x': body_edge['left'] + L}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #side-wall thickness S\n    S = 0.4\n\n    #bottom line\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x':x1,'y':2},\n            {'x':x1+S,'y':2},\n            {'x':x1+S,'y':y2-S},\n            {'x':x2-S,'y':y2-S},\n            {'x':x2-S,'y':2},\n            {'x':x2,'y':2}],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    \n    #left mark\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x':x1,'y':1},\n            {'x':x1+S,'y':1},\n            {'x':x1+S,'y':y1+S},\n            {'x':0.5,'y':y1+S},\n            {'x':0.5,'y':y1}],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #right mark\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x':x2,'y':1},\n            {'x':x2-S,'y':1},\n            {'x':x2-S,'y':y1+S},\n            {'x':x2-2.5-off,'y':y1+S},\n            {'x':x2-2.5-off,'y':y1}],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #middle line\n    if pins > 2:\n        kicad_mod.append(PolygoneLine(\n            polygone=[\n                {'x':1.5,'y':y1},\n                {'x':1.5,'y':y1+S},\n                {'x':x2-3.5-off,'y':y1+S},\n                {'x':x2-3.5-off,'y':y1}],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Hirose/conn_hirose_df12c_ds_smd_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = 'DF12'\nseries_long = 'DF12C SMD'\nmanufacturer = 'Hirose'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'https://www.hirose.com/product/document?clcode=CL0537-0694-9-81&productname=DF12C(3.0)-50DS-0.5V(81)&series=DF12&documenttype=2DDrawing&lang=en&documentid=0000994748'\n\n#Hirose part number\npart_code = \"DF12C3.0-{n:02}DS-0.5V\"\n\npitch = 0.5\npad_size = [0.3, 1.6]\npad_size_paste = [0.28,1.2]\n\npins_per_row_range = [10,20,30,40,50,60,14,32,36]\n\ndef generate_one_footprint(idx, pins, configuration):\n\n    mpn = part_code.format(n=pins)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=int(pins/2), mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setAttribute('smd')\n    kicad_mod.setDescription(\"{:s} {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(manufacturer, series_long, mpn, pins, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    ########################## Dimensions ##############################\n    if(idx == 6):       #14 Pins\n        A = 5.6\n        B = 3.0\n    elif (idx == 7):    #32 Pins\n        A = 10.1\n        B = 7.5\n    elif (idx == 8):    #36 Pins\n        A = 11.1\n        B = 8.5\n    else:\n        A = 4.6 + (idx * 2.5)\n        B = A - 2.6\n\n    body_edge_out={\n        'left': round(-A/2 ,2),\n        'right': round(A/2 ,2),\n        'top': -1.8,\n        'bottom': 1.8\n        }\n\n    D = A - 1.5\n\n    body_edge_in={\n        'left': round(-D/2 ,2),\n        'right': round(D/2 ,2),\n        'top': -1.2,\n        'bottom': 1.2\n        }\n\n    ############################# Pads ##################################\n    #\n    # Add pads\n    #\n    #Pad only with F.Cu and F.Mask\n    CPins=int(pins / 2)\n    kicad_mod.append(PadArray(start=[-B/2, -1.8], initial=1,\n        pincount=CPins, increment=1,  x_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=[\"F.Cu\", \"F.Mask\"]))\n\n    kicad_mod.append(PadArray(start=[-B/2, 1.8], initial=CPins + 1,\n        pincount=CPins, increment=1,  x_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=[\"F.Cu\", \"F.Mask\"]))\n\n    #F.Paste\n    kicad_mod.append(PadArray(start=[-B/2, -2], initial='', increment=0,\n        pincount=CPins,  x_spacing=pitch, size=pad_size_paste,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=[\"F.Paste\"]))\n\n    kicad_mod.append(PadArray(start=[-B/2, 2], initial='', increment=0,\n        pincount=CPins,  x_spacing=pitch, size=pad_size_paste,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=[\"F.Paste\"]))\n\n    ######################## Fabrication Layer ###########################\n    main_body_out_poly= [\n        {'x': body_edge_out['left'], 'y': body_edge_out['bottom']},\n        {'x': body_edge_out['left'], 'y': body_edge_out['top']},\n        {'x': body_edge_out['right'], 'y': body_edge_out['top']},\n        {'x': body_edge_out['right'], 'y': body_edge_out['bottom']},\n        {'x': body_edge_out['left'], 'y': body_edge_out['bottom']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_body_out_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    main_body_in_poly= [\n        {'x': body_edge_in['left'], 'y': body_edge_in['bottom']},\n        {'x': body_edge_in['left'], 'y': body_edge_in['top']},\n        {'x': body_edge_in['right'], 'y': body_edge_in['top']},\n        {'x': body_edge_in['right'], 'y': body_edge_in['bottom']},\n        {'x': body_edge_in['left'], 'y': body_edge_in['bottom']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_body_in_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    main_arrow_poly= [\n        {'x': (-B/2)-0.2, 'y': body_edge_out['top'] - 0.75},\n        {'x': -B/2, 'y': -1.8},\n        {'x': (-B/2)+0.2, 'y': body_edge_out['top'] - 0.75},\n        {'x': (-B/2)-0.2, 'y': body_edge_out['top'] - 0.75}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_arrow_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    ######################## SilkS Layer ###########################\n    offset = (pad_size[0]/2)+0.2+.06\n\n    poly_left= [\n        {'x': -(B/2) - offset, 'y': body_edge_out['bottom'] + configuration['silk_fab_offset']},\n        {'x': -(A/2) - configuration['silk_fab_offset'], 'y': body_edge_out['bottom'] + configuration['silk_fab_offset']},\n        {'x': body_edge_out['left'] - configuration['silk_fab_offset'], 'y': body_edge_out['top'] - configuration['silk_fab_offset']},\n        {'x': -(B/2) - offset, 'y': body_edge_out['top'] - configuration['silk_fab_offset']},\n        {'x': -(B/2) - offset, 'y': body_edge_out['top'] - (pad_size[1]/3)}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_left,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    poly_right= [\n        {'x': (B/2) + offset, 'y': body_edge_out['bottom'] + configuration['silk_fab_offset']},\n        {'x': (A/2) + configuration['silk_fab_offset'], 'y': body_edge_out['bottom'] + configuration['silk_fab_offset']},\n        {'x': body_edge_out['right'] + configuration['silk_fab_offset'], 'y': body_edge_out['top'] - configuration['silk_fab_offset']},\n        {'x': (B/2) + offset, 'y': body_edge_out['top'] - configuration['silk_fab_offset']}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_right,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    ######################## CrtYd Layer ###########################\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n\n    poly_yd = [\n        {'x': roundToBase(body_edge_out['left'] - CrtYd_offset, CrtYd_grid), 'y': roundToBase(-2.6 - CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(body_edge_out['left'] - CrtYd_offset, CrtYd_grid), 'y': roundToBase(2.6 + CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(body_edge_out['right'] + CrtYd_offset, CrtYd_grid), 'y': roundToBase(2.6 + CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(body_edge_out['right'] + CrtYd_offset, CrtYd_grid), 'y': roundToBase(-2.6 - CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(body_edge_out['left'] - CrtYd_offset, CrtYd_grid), 'y': roundToBase(-2.6 - CrtYd_offset, CrtYd_grid)}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_yd,\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    cy1 = roundToBase(body_edge_out['top'] -1 - configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(body_edge_out['bottom'] + 1 + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge_out,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Write to File and 3D ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    idx = 0\n    for pincount in pins_per_row_range:\n        generate_one_footprint(idx, pincount, configuration)\n        idx += 1\n"
  },
  {
    "path": "scripts/Connector/Connector_Hirose/conn_hirose_df12e_dp_smd_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = 'DF12'\nseries_long = 'DF12E SMD'\nmanufacturer = 'Hirose'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'https://www.hirose.com/product/document?clcode=CL0537-0834-6-81&productname=DF12E(3.0)-50DP-0.5V(81)&series=DF12&documenttype=2DDrawing&lang=en&documentid=0000992393'\n\n#Hirose part number\npart_code = \"DF12E3.0-{n:02}DP-0.5V\"\n\npitch = 0.5\npad_size = [0.3, 1.6]\npad_size_paste = [0.28,1.2]\n\npins_per_row_range = [10,20,30,40,50,60,80,14,32,36]\n\ndef generate_one_footprint(idx, pins, configuration):\n\n    mpn = part_code.format(n=pins)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=int(pins/2), mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setAttribute('smd')\n    kicad_mod.setDescription(\"{:s} {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(manufacturer, series_long, mpn, pins, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    ########################## Dimensions ##############################\n    if(idx == 6):       #80 Pins\n        A = 22.2\n        B = 19.5\n    elif(idx == 7):     #14 Pins\n        A = 5.7\n        B = 3.0\n    elif (idx == 8):    #32 Pins\n        A = 10.2\n        B = 7.5\n    elif (idx == 9):    #36 Pins\n        A = 11.2\n        B = 8.5\n    else:\n        A = 4.7 + (idx * 2.5)\n        B = A - 2.7\n\n    body_edge_out={\n        'left': round(-A/2 ,2),\n        'right': round(A/2 ,2),\n        'top': -1.9,\n        'bottom': 1.9\n        }\n\n    D = A - 1.5\n\n    body_edge_in={\n        'left': round(-D/2 ,2),\n        'right': round(D/2 ,2),\n        'top': -1.225,\n        'bottom': 1.225\n        }\n\n    ############################# Pads ##################################\n    #\n    # Add pads\n    #\n    #Pad only with F.Cu and F.Mask\n    CPins=int(pins / 2)\n    kicad_mod.append(PadArray(start=[-B/2, 1.8], initial=1,\n        pincount=CPins, increment=1,  x_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=[\"F.Cu\", \"F.Mask\"]))\n\n    kicad_mod.append(PadArray(start=[-B/2, -1.8], initial=CPins + 1,\n        pincount=CPins, increment=1,  x_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=[\"F.Cu\", \"F.Mask\"]))\n\n    #F.Paste\n    kicad_mod.append(PadArray(start=[-B/2, 2], initial='', increment=0,\n        pincount=CPins,  x_spacing=pitch, size=pad_size_paste,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=[\"F.Paste\"]))\n\n    kicad_mod.append(PadArray(start=[-B/2, -2], initial='', increment=0,\n        pincount=CPins,  x_spacing=pitch, size=pad_size_paste,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=[\"F.Paste\"]))\n\n    ######################## Fabrication Layer ###########################\n    main_body_out_poly= [\n        {'x': body_edge_out['left'], 'y': body_edge_out['bottom']},\n        {'x': body_edge_out['left'], 'y': body_edge_out['top']},\n        {'x': body_edge_out['right'], 'y': body_edge_out['top']},\n        {'x': body_edge_out['right'], 'y': body_edge_out['bottom']},\n        {'x': body_edge_out['left'], 'y': body_edge_out['bottom']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_body_out_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    main_body_in_poly= [\n        {'x': body_edge_in['left'], 'y': body_edge_in['bottom']},\n        {'x': body_edge_in['left'], 'y': body_edge_in['top']},\n        {'x': body_edge_in['right'], 'y': body_edge_in['top']},\n        {'x': body_edge_in['right'], 'y': body_edge_in['bottom']},\n        {'x': body_edge_in['left'], 'y': body_edge_in['bottom']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_body_in_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    main_arrow_poly= [\n        {'x': (-B/2)-0.2, 'y': body_edge_out['bottom'] + 0.75},\n        {'x': -B/2, 'y': 1.8},\n        {'x': (-B/2)+0.2, 'y': body_edge_out['bottom'] + 0.75},\n        {'x': (-B/2)-0.2, 'y': body_edge_out['bottom'] + 0.75}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_arrow_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    ######################## SilkS Layer ###########################\n    offset = (pad_size[0]/2)+0.2+.06\n\n    poly_left= [\n        {'x': -(B/2) - offset, 'y': body_edge_out['bottom'] + (pad_size[1]/3)},\n        {'x': -(B/2) - offset, 'y': body_edge_out['bottom'] + configuration['silk_fab_offset']},\n        {'x': -(A/2) - configuration['silk_fab_offset'], 'y': body_edge_out['bottom'] + configuration['silk_fab_offset']},\n        {'x': body_edge_out['left'] - configuration['silk_fab_offset'], 'y': body_edge_out['top'] - configuration['silk_fab_offset']},\n        {'x': -(B/2) - offset, 'y': body_edge_out['top'] - configuration['silk_fab_offset']}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_left,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    poly_right= [\n        {'x': (B/2) + offset, 'y': body_edge_out['bottom'] + configuration['silk_fab_offset']},\n        {'x': (A/2) + configuration['silk_fab_offset'], 'y': body_edge_out['bottom'] + configuration['silk_fab_offset']},\n        {'x': body_edge_out['right'] + configuration['silk_fab_offset'], 'y': body_edge_out['top'] - configuration['silk_fab_offset']},\n        {'x': (B/2) + offset, 'y': body_edge_out['top'] - configuration['silk_fab_offset']}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_right,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    ######################## CrtYd Layer ###########################\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n\n    poly_yd = [\n        {'x': roundToBase(body_edge_out['left'] - CrtYd_offset, CrtYd_grid), 'y': roundToBase(-2.6 - CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(body_edge_out['left'] - CrtYd_offset, CrtYd_grid), 'y': roundToBase(2.6 + CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(body_edge_out['right'] + CrtYd_offset, CrtYd_grid), 'y': roundToBase(2.6 + CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(body_edge_out['right'] + CrtYd_offset, CrtYd_grid), 'y': roundToBase(-2.6 - CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(body_edge_out['left'] - CrtYd_offset, CrtYd_grid), 'y': roundToBase(-2.6 - CrtYd_offset, CrtYd_grid)}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_yd,\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    cy1 = roundToBase(body_edge_out['top'] -1 - configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(body_edge_out['bottom'] + 1 + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge_out,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Write to File and 3D ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    idx = 0\n    for pincount in pins_per_row_range:\n        generate_one_footprint(idx, pincount, configuration)\n        idx += 1\n"
  },
  {
    "path": "scripts/Connector/Connector_Hirose/conn_hirose_df13_tht_side.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = 'DF13'\nseries_long = 'DF13 through hole'\nmanufacturer = 'Hirose'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'https://www.hirose.com/product/en/products/DF13/DF13-4P-1.25DS%2820%29/'\n\n#pins_per_row per row\npins_per_row_range = [2,3,4,5,6,7,8,9,10,11,12,14,15]\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"DF13-{n:02}P-1.25DS\"\n\npitch = 1.25\ndrill = 0.6\n\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.4\nmin_annular_ring = 0.15\n\n\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\n\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_code.format(n=pins)\n    pad_silk_off = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_no_series_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    footprint_name = footprint_name.replace(\"__\",'_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"{:s} {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(manufacturer, series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n    # create pads\n    #createNumberedPadsTHT(kicad_mod, pincount, pitch, drill, {'x':x_dia, 'y':y_dia})\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(start=[0,0], pincount=pins, x_spacing=pitch,\n        type=Pad.TYPE_THT, shape=pad_shape, size=pad_size,\n        drill=drill, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    A = (pins - 1) * pitch\n    B = A + 2.9\n\n    x1 = -(B-A) / 2\n    y1 = -4.5\n    x2 = x1 + B\n    y2 = y1 + 5.4\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n\n    #draw the connector outline on the F.Fab layer\n    kicad_mod.append(RectLine(\n        start={'x': x1,'y': y1}, end={'x': x2,'y': y2},\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    #line offset\n    off = configuration['silk_fab_offset']\n\n    x1 -= off\n    y1 -= off\n\n    x2 += off\n    y2 += off\n\n    #y offset from pins 'q'\n    q = -0.3\n\n    #x offset from border w\n    w = 0.55\n\n    #outline size o\n    o = 0.15\n\n    #draw the main outline around the footprint\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x':-0.2*pitch,'y':pad_size[1]/2+pad_silk_off},\n            {'x':-0.2*pitch,'y':y2},\n            {'x':x1,'y':y2},\n            {'x':x1,'y':y1},\n            {'x':x2,'y':y1},\n            {'x':x2,'y':y2},\n            {'x':(pins -1 + 0.2) * pitch,'y':y2},\n            {'x':(pins -1 + 0.2) * pitch,'y':pad_size[1]/2+pad_silk_off}],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #line across the middle\n    py = -2.5\n    kicad_mod.append(Line(start={'x':x1+w,'y':py},end={'x':x2-w,'y':py},\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start={'x':x1+w,'y':py+1.5},end={'x':x2-w,'y':py+1.5},\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    kicad_mod.append(Line(start={'x':x1+w,'y':y1},end={'x':x1+w,'y':y2},\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start={'x':x2-w,'y':y1},end={'x':x2-w,'y':y2},\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    #add picture of pins\n\n     #add pictures of pins\n    #pin-width w\n    #pin-length l\n    w = 0.15\n    l = 1.5\n\n    for p in range(pins):\n\n        px = p * pitch\n\n        kicad_mod.append(PolygoneLine(\n            polygone=[\n                {'x': px-w,'y': py},\n                {'x': px-w,'y': py-l+0.25*w},\n                {'x': px,'y': py-l},\n                {'x': px+w,'y': py-l+0.25*w},\n                {'x': px+w,'y': py}],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n        #add outline around pins\n\n        if p > 0:\n            kicad_mod.append(PolygoneLine(\n                polygone=[\n                    {'x':px-0.8*pitch,'y':pad_size[1]/2+pad_silk_off},\n                   {'x':px-0.8*pitch,'y':y2},\n                   {'x':px-0.2*pitch,'y':y2},\n                   {'x':px-0.2*pitch,'y':pad_size[1]/2+pad_silk_off}],\n                layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add pin-1 marker\n\n    xm = 0\n    ym = 1.5\n\n    m = 0.3\n\n    kicad_mod.append(PolygoneLine(\n            polygone=[\n                {'x':xm,'y':ym},\n                {'x':xm - m,'y':ym + 2 * m},\n                {'x':xm + m,'y':ym + 2 * m},\n                {'x':xm,'y':ym}],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    sl=1\n    pin = [\n        {'y': body_edge['bottom'], 'x': -sl/2},\n        {'y': body_edge['bottom'] - sl/sqrt(2), 'x': 0},\n        {'y': body_edge['bottom'], 'x': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Hirose/conn_hirose_df13_tht_top.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = 'DF13'\nseries_long = 'DF13 through hole'\nmanufacturer = 'Hirose'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'https://www.hirose.com/product/en/products/DF13/DF13-2P-1.25DSA%2850%29/'\n\n#pins_per_row per row\npins_per_row_range = range(2,16)\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"DF13-{n:02}P-1.25DSA\"\n\npitch = 1.25\ndrill = 0.6\n\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.4\nmin_annular_ring = 0.15\n\n\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\n\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_code.format(n=pins)\n    pad_silk_off = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_no_series_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    footprint_name = footprint_name.replace(\"__\",'_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"{:s} {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(manufacturer, series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    A = (pins - 1) * pitch\n    B = A + 2.9\n\n    # create pads\n    #createNumberedPadsTHT(kicad_mod, pincount, pitch, drill, {'x':x_dia, 'y':y_dia})\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(start=[0,0], pincount=pins, x_spacing=pitch,\n        type=Pad.TYPE_THT, shape=pad_shape, size=pad_size,\n        drill=drill, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n\n    x1 = -(B-A) / 2\n    y1 = -2.2\n    x2 = x1 + B\n    y2 = 1.2\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n\n    kicad_mod.append(RectLine(\n        start={'x': x1,'y': y1}, end={'x': x2,'y': y2},\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    #line offset\n    off = 0.1\n\n    x1 -= off\n    y1 -= off\n\n    x2 += off\n    y2 += off\n\n    #draw the main outline around the footprint\n    kicad_mod.append(RectLine(start={'x':x1,'y':y1},end={'x':x2,'y':y2},\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add pin-1 marker\n    p1_off = configuration['silk_fab_offset'] + 0.3\n    L = 1.5\n    pin = [\n        {'y': body_edge['bottom'] - L, 'x': body_edge['left'] - p1_off},\n        {'y': body_edge['bottom'] + p1_off, 'x': body_edge['left'] - p1_off},\n        {'y': body_edge['bottom'] + p1_off, 'x': body_edge['left'] + L}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    sl=1\n    pin = [\n        {'y': body_edge['bottom'], 'x': -sl/2},\n        {'y': body_edge['bottom'] - sl/sqrt(2), 'x': 0},\n        {'y': body_edge['bottom'], 'x': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    #side-wall thickness S\n\n    S = 0.3\n\n    #bottom line\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x':x1,'y':0},\n            {'x':x1+S,'y':0},\n            {'x':x1+S,'y':y2-S},\n            {'x':x2-S,'y':y2-S},\n            {'x':x2-S,'y':0},\n            {'x':x2,'y':0}],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #left mark\n\n    #gap g\n    g = 0.75\n\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x':x1,'y':-g},\n            {'x':x1+S,'y':-g},\n            {'x':x1+S,'y':y1+S*1.5},\n            {'x':x1+2*S,'y':y1+S*1.5},\n            {'x':x1+2*S,'y':y1}],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x':x2,'y':-g},\n            {'x':x2-S,'y':-g},\n            {'x':x2-S,'y':y1+S*1.5},\n            {'x':x2-2*S,'y':y1+S*1.5},\n            {'x':x2-2*S,'y':y1}],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #middle line\n    if pins == 2:\n        polygone=[{'x':x1+2*S,'y':y1+1.5*S},\n            {'x':0.2*pitch,'y':y1+1.5*S},\n            {'x':0.2*pitch,'y':y1+0.5*S},\n            {'x':0.8*pitch,'y':y1+0.5*S},\n            {'x':0.8*pitch,'y':y1+1.5*S},\n            {'x':x2-2*S,'y':y1+1.5*S}]\n    else:\n        polygone=[\n            {'x':x1+2*S,'y':y1+1.5*S},\n            {'x':0.2*pitch,'y':y1+1.5*S},\n            {'x':0.2*pitch,'y':y1+0.5*S},\n            {'x':0.8*pitch,'y':y1+0.5*S},\n            {'x':0.8*pitch,'y':y1+1.5*S},\n            {'x':A-0.8*pitch,'y':y1+1.5*S},\n            {'x':A-0.8*pitch,'y':y1+0.5*S},\n            {'x':A-0.2*pitch,'y':y1+0.5*S},\n            {'x':A-0.2*pitch,'y':y1+1.5*S},\n            {'x':x2-2*S,'y':y1+1.5*S}]\n    kicad_mod.append(PolygoneLine(polygone=polygone, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Hirose/conn_hirose_df13c_smd_top.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\nfrom footprint_keepout_area import addRectangularKeepout\n\nseries = 'DF13C'\nseries_long = 'DF13C SMD'\nmanufacturer = 'Hirose'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'https://www.hirose.com/product/en/products/DF13/DF13C-10P-1.25V%2851%29/'\n\n#pins_per_row per row\npins_per_row_range = [2,3,4,5,6,7,8,9,10,11,12,14,15]\nmpn_param_1 = ['2','5','8','0','3','6','9','1','4','3','6','1','4']\n\npart_code = \"CL535-04{n:02d}-{param_1:s}-51\"\n\n# x position mounting inner mounting pad edge relative to nearest pad center\ncenter_pad_to_mounting_pad_edge = 1.45\n# y dimensions for pad given relative to mounting pad edge\nrel_pad_y_outside_edge = 4.7\nrel_pad_y_inside_edge = 2.9\npad_size_x = 0.7\n# y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\nrel_body_edge_y = 0.6\nbody_size_y = 3.4\n# body_fin_protrusion: 1.6\n# body_fin_width: 0.8\n# x body edge relative to nearest pin\nrel_body_edge_x = 2.2\n\n\npitch = 1.25\npad_size = [pad_size_x, rel_pad_y_outside_edge - rel_pad_y_inside_edge]\nmp_size = [1.6, 2.2]\n\ndef generate_one_footprint(idx, pins, configuration):\n    mpn = part_code.format(n=pins, param_1=mpn_param_1[idx])\n    pad_silk_off = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n    off = configuration['silk_fab_offset']\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"-1MP\",\n        pitch=pitch, orientation=orientation_str)\n\n    footprint_name = footprint_name.replace(\"__\",'_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setAttribute('smd')\n    kicad_mod.setDescription(\"{:s} {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(manufacturer, series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    A = (pins - 1) * pitch\n    B = A + 2*rel_body_edge_x\n    pad_y = -rel_pad_y_outside_edge/2 + pad_size[1]/2\n    mpad_y = rel_pad_y_outside_edge/2 - mp_size[1]/2\n    mpad_x = A/2 + center_pad_to_mounting_pad_edge + mp_size[0]/2\n\n    kicad_mod.append(Pad(number = configuration['mounting_pad_number'], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                        at=[mpad_x, mpad_y], size=mp_size, layers=Pad.LAYERS_SMT))\n    kicad_mod.append(Pad(number = configuration['mounting_pad_number'], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                        at=[-mpad_x, mpad_y], size=mp_size, layers=Pad.LAYERS_SMT))\n\n    # create pads\n    #createNumberedPadsTHT(kicad_mod, pincount, pitch, drill, {'x':x_dia, 'y':y_dia})\n    kicad_mod.append(PadArray(center=[0,pad_y], pincount=pins, x_spacing=pitch,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=pad_size, layers=Pad.LAYERS_SMT))\n\n\n    x1 = -B/2\n    x2 = x1 + B\n    y2 = mpad_y + mp_size[1]/2 + rel_body_edge_y\n    y1 = y2 - body_size_y\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n\n    bounding_box = body_edge.copy()\n    bounding_box['top'] = pad_y - pad_size[1]/2\n    bb_x = mpad_x + mp_size[0]/2\n    if  bb_x > x2:\n        bounding_box['left'] = -bb_x\n        bounding_box['right'] = bb_x\n\n\n    kicad_mod.append(RectLine(\n        start={'x': x1,'y': y1}, end={'x': x2,'y': y2},\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    #line offset\n    off = 0.1\n\n    x1 -= off\n    y1 -= off\n\n    x2 += off\n    y2 += off\n\n    #draw the main outline around the footprint\n    silk_pad_x_left = -A/2 - pad_size[0]/2 - pad_silk_off\n    silk_mp_top = mpad_y - mp_size[1]/2 - pad_silk_off\n    silk_mp_bottom = mpad_y + mp_size[1]/2 + pad_silk_off\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': silk_pad_x_left,'y':y1},\n            {'x': x1,'y':y1},\n            {'x': x1,'y':silk_mp_top}\n        ],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': -silk_pad_x_left,'y':y1},\n            {'x': x2,'y':y1},\n            {'x': x2,'y':silk_mp_top}\n        ],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': x1,'y':silk_mp_bottom},\n            {'x': x1,'y':y2},\n            {'x': x2,'y':y2},\n            {'x': x2,'y':silk_mp_bottom}\n        ],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n    #add pin-1 marker\n\n    kicad_mod.append(Line(\n        start=[silk_pad_x_left, y1], end=[silk_pad_x_left, pad_y - pad_size[1]/2],\n                layer='F.SilkS', width=configuration['silk_line_width']))\n\n    sl=1\n    pin = [\n        {'y': body_edge['top'], 'x': -A/2-sl/2},\n        {'y': body_edge['top'] + sl/sqrt(2), 'x': -A/2},\n        {'y': body_edge['top'], 'x': -A/2+sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n\n    ########################### KEEPOUT #################################\n\n    k_top = pad_y + pad_size[1]/2 + 0.1\n    k_size = [A + pad_size[0], 2.37]\n    addRectangularKeepout(kicad_mod, [0, k_top+k_size[1]/2], k_size)\n\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n    idx = 0\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(idx, pins_per_row, configuration)\n        idx += 1\n"
  },
  {
    "path": "scripts/Connector/Connector_Hirose/conn_hirose_df63_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\n\"\"\"\nfootprint specific details to go here\n\nHirose DF63\n\nURL:\nhttps://www.hirose.com/product/en/products/DF63/\n\nDatasheet:\nhttps://www.hirose.com/product/document?clcode=&productname=&series=DF63&documenttype=Catalog&lang=en&documentid=D31622_en\n\"\"\"\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = 'DF63'\nseries_long = 'DF63 through hole'\nmanufacturer = 'Hirose'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'https://www.hirose.com/product/en/products/DF63/'\n\n#pins_per_row per row\npins_per_row_range = [1,2,3,4,5,6]\n\ntypes = ['M', 'R']\n\n#Hirose part number\n#n = number of circuits per row\npart_code = \"DF63{f:s}-{n:d}P-3.96DSA\"\n\npitch = 3.96\ndrill = 1.8\nmount_size = 1.6\n\npad_to_pad_clearance = 1.5\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\n\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\n\n\ndef generate_one_footprint(pins, form_type, configuration):\n    mpn = part_code.format(n=pins, f=form_type)\n    off = configuration['silk_fab_offset']\n    pad_silk_off = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n\n    pad_silk_off = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_no_series_format_string'].format(man=manufacturer,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"{:s} {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(manufacturer, series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n\n    #vertical center of connector\n    y2 = 3.25 + mount_size / 2\n    y1 = y2 - 7.05\n    yt = y2 - 8\n\n    #Major dimensions\n    B = ( pins - 1 ) * pitch\n    A = B + 4.7\n    if pins == 1:\n        A = 6.2\n\n    #calculate major dimensions\n    x1 = (B - A) / 2\n    x2 = x1 + A\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n    bounding_box['top'] = yt\n\n    #pins\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(\n        PadArray(\n                pincount=pins,\n                initial = 1,\n                start = [0, 0],\n                x_spacing = pitch,\n                type = Pad.TYPE_THT,\n                layers = Pad.LAYERS_THT,\n                shape = pad_shape,\n                size = pad_size,\n                drill = drill,\n                **optional_pad_params\n                )\n    )\n\n    #mounting hole\n    if form_type in ['M', '']:\n        peg_location = [-1.5, 3.25]\n    else:\n        peg_location = [B+1.5, 3.25]\n    kicad_mod.append(Pad(at=peg_location,type=Pad.TYPE_NPTH,layers=Pad.LAYERS_NPTH,shape=Pad.SHAPE_CIRCLE,size=mount_size,drill=mount_size))\n\n    #connector outline\n\n    #tab thickness\n    t = 1.2\n\n    def outline(offset=0):\n        outline = [\n        {'x': B/2, 'y': y2 + offset},\n        {'x': x1 - offset, 'y': y2 + offset},\n        {'x': x1 - offset, 'y': yt - offset},\n        {'x': x1 + t + offset, 'y': yt - offset},\n        {'x': x1 + t + offset, 'y': y1 - offset},\n        {'x': B/2, 'y': y1 - offset},\n        ]\n\n        return outline\n\n    kicad_mod.append(PolygoneLine(polygone=outline(),layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=outline(),x_mirror=B/2,\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    kicad_mod.append(PolygoneLine(polygone=outline(offset=off),\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=outline(offset=off),x_mirror=B/2,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #draw lines between pads on F.Fab\n    for i in range(pins - 1):\n        x = (i + 0.5) * pitch\n\n        kicad_mod.append(Line(start=[x,y1], end=[x,y2],\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n    #pin-1 indicator\n    kicad_mod.append(Circle(center=[0,-3.75], radius=0.25,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    sl=2\n    pin = [\n        {'y': body_edge['top'], 'x': -sl/2},\n        {'y': body_edge['top'] + sl/sqrt(2), 'x': 0},\n        {'y': body_edge['top'], 'x': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position=-3.75)\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        for form_type in types:\n            if form_type is 'R' and pins_per_row is 6:\n                continue\n            if form_type is 'M' and pins_per_row in [5,6]:\n                form_type = ''\n            generate_one_footprint(pins_per_row, form_type, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Hirose/helpers.py",
    "content": "def roundToBase(value, base):\n    if base == 0:\n        return value\n    return round(value/base) * base\n"
  },
  {
    "path": "scripts/Connector/Connector_Hirose/not_in_official_lib/df33_straight_pth.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\"))\n\nfrom kicad_mod import KicadMod, createNumberedPadsTHT\n\n# http://www.jst-mfg.com/product/pdf/eng/ePH.pdf\n\npitch = 3.3\n\nmanu = \"Hirose\"\n\nsuffix = \"Straight\"\n\ndesc = \"Hirose DF33 series connector, 3.30mm pitch, top entry PTH\"\ntags = \"connector hirose df33 top straight vertical through thru hole\"\n\nfor pincount in range(2,16):\n\n    part = \"DF33C-{pincount:02}P-125DSA\".format(pincount=pincount)\n\n    footprint_name = \"{0}_{1}_{2:02}x{3:.2f}mm_{4}\".format(manu,part,pincount,pitch,suffix)\n\n    kicad_mod = KicadMod(footprint_name)\n    kicad_mod.setDescription(desc)\n    kicad_mod.setTags(tags)\n\n    # set general values\n    kicad_mod.addText('reference', 'REF**', {'x':0, 'y':2.5}, 'F.SilkS')\n    kicad_mod.addText('value', footprint_name, {'x':0, 'y':4}, 'F.Fab')\n\n    drill = 0.6\n\n    x_dia = 0.95\n    y_dia = 1.25\n\n    # create pads\n    createNumberedPadsTHT(kicad_mod, pincount, pitch, drill, {'x':x_dia, 'y':y_dia})\n\n    A = (pincount - 1) * pitch\n    B = A + 2.9\n\n    x1 = -(B-A) / 2\n    y1 = -2.2\n    x2 = x1 + B\n    y2 = 1.2\n\n    #line offset\n    off = 0.1\n\n    x1 -= off\n    y1 -= off\n\n    x2 += off\n    y2 += off\n\n    #draw the main outline around the footprint\n    kicad_mod.addRectLine({'x':x1,'y':y1},{'x':x2,'y':y2})\n\n    #add pin-1 marker\n\n    xm = 0\n    ym = -2.8\n\n    m = 0.3\n\n    kicad_mod.addPolygoneLine([{'x':xm,'y':ym},\n                               {'x':xm - m,'y':ym - 2 * m},\n                               {'x':xm + m,'y':ym - 2 * m},\n                               {'x':xm,'y':ym}])\n\n    #side-wall thickness S\n\n    S = 0.5\n\n    #bottom line\n    kicad_mod.addPolygoneLine([{'x':x1,'y':0},\n                               {'x':x1+S,'y':0},\n                               {'x':x1+S,'y':y2-S},\n                               {'x':x2-S,'y':y2-S},\n                               {'x':x2-S,'y':0},\n                               {'x':x2,'y':0}])\n\n    #left mark\n\n    #gap g\n    g = 0.75\n\n    kicad_mod.addPolygoneLine([{'x':x1,'y':-g},\n                               {'x':x1+S,'y':-g},\n                               {'x':x1+S,'y':y1+S*1.5},\n                               {'x':x1+2*S,'y':y1+S*1.5},\n                               {'x':x1+2*S,'y':y1}])\n\n    kicad_mod.addPolygoneLine([{'x':x2,'y':-g},\n                               {'x':x2-S,'y':-g},\n                               {'x':x2-S,'y':y1+S*1.5},\n                               {'x':x2-2*S,'y':y1+S*1.5},\n                               {'x':x2-2*S,'y':y1}])\n\n    #middle line\n    kicad_mod.addPolygoneLine([{'x':x1+2*S,'y':y1+1.5*S},\n                               {'x':0.2*pitch,'y':y1+1.5*S},\n                               {'x':0.2*pitch,'y':y1+0.5*S},\n                               {'x':0.8*pitch,'y':y1+0.5*S},\n                               {'x':0.8*pitch,'y':y1+1.5*S},\n                               {'x':A-0.8*pitch,'y':y1+1.5*S},\n                               {'x':A-0.8*pitch,'y':y1+0.5*S},\n                               {'x':A-0.2*pitch,'y':y1+0.5*S},\n                               {'x':A-0.2*pitch,'y':y1+1.5*S},\n                               {'x':x2-2*S,'y':y1+1.5*S}])\n\n    \"\"\"\n    #add pictures of pins\n    #pin-width w\n    #pin-length l\n    w = 0.32\n    l = 3.5\n\n    py = -2.5\n\n    kicad_mod.addLine({'x':x1+T,'y':py},{'x':x2-T,'y':py})\n\n    kicad_mod.addLine({'x':x1+T,'y':py+1},{'x':x2-T,'y':py+1})\n\n    for p in range(pincount):\n\n        px = p * pitch\n\n        kicad_mod.addPolygoneLine([{'x': px,'y': py},\n                                   {'x': px-w,'y': py},\n                                   {'x': px-w,'y': py-l+0.25*w},\n                                   {'x': px,'y': py-l},\n                                   {'x': px+w,'y': py-l+0.25*w},\n                                   {'x': px+w,'y': py},\n                                   {'x': px,'y': py}])\n\n\n    \"\"\"\n    #add a courtyard\n    cy = 0.5\n\n    kicad_mod.addRectLine({'x':x1-cy,'y':y1-cy},{'x':x2+cy,'y':y2+cy},\"F.CrtYd\",0.05)\n\n    kicad_mod.model = \"Connectors_Hirose.3dshapes/\" + footprint_name + \".wrl\"\n\n    #shift the model along\n\n    if pincount % 2 == 0: #even\n        xOff = (pincount / 2 - 0.5) * pitch\n    else:\n        xOff = (pincount / 2) * pitch\n\n    kicad_mod.model_pos['x'] = xOff / 25.4\n    kicad_mod.model_rot['z'] = 180\n\n    # output kicad model\n    f = open(footprint_name + \".kicad_mod\",\"w\")\n\n    f.write(kicad_mod.__str__())\n\n    f.close()\n"
  },
  {
    "path": "scripts/Connector/Connector_Hirose/not_in_official_lib/df63_angled.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\noutput_dir = os.getcwd()\n\n#if specified as an argument, extract the target directory for output footprints\nif len(sys.argv) > 1:\n    out_dir = sys.argv[1]\n\n    if os.path.isabs(out_dir) and os.path.isdir(out_dir):\n        output_dir = out_dir\n    else:\n        out_dir = os.path.join(os.getcwd(),out_dir)\n        if os.path.isdir(out_dir):\n            output_dir = out_dir\n\nif output_dir and not output_dir.endswith(os.sep):\n    output_dir += os.sep\n\n#import KicadModTree files\nsys.path.append(\"..\\\\..\")\nfrom KicadModTree import *\nfrom KicadModTree.nodes.specialized.PadArray import PadArray\n\n\"\"\"\nfootprint specific details to go here\n\nHirose DF63\n\nURL:\nhttps://www.hirose.com/product/en/products/DF63/\n\nDatasheet:\nhttps://www.hirose.com/product/en/download_file/key_name/DF63/category/Catalog/doc_file_id/51104/?file_category_id=4&item_id=47&is_series=1\n\"\"\"\n\nmanu = \"Hirose\"\n\nseries = \"DF63\"\n\npitch = 3.96\n\ndrill = 1.8\n\npad_size = 3\n\nmount_size = 1.6\n\n#vertical center of connector\ny2 = 3.25 + mount_size / 2\ny1 = y2 - 7.05\nyt = y2 - 8\n\ndesc = \"{manu} {series} connector, {code}, {p}mm pitch, side entry THT\"\ntags = \"connector hirose df63 horizontal through hole\"\n\npins = [2,3]\n\nfor pincount in pins:\n\n    part = \"DF63-{pincount}P-3.96DS\".format(series=series,pincount=pincount)\n\n    footprint_name = \"{manu}_{pn}_{n:02}x{pitch:.2f}mm_Angled\".format(\n        manu = manu,\n        pn = part,\n        n = pincount,\n        pitch = pitch\n    )\n\n    print(footprint_name)\n\n    fp = Footprint(footprint_name)\n\n    #description\n    fp.setDescription(desc.format(manu=manu, series=series, p=pitch, code=part))\n    fp.setTags(tags)\n\n    # text\n    fp.append(Text(type='reference', text='REF**', at=[0, -5.2], layer='F.SilkS'))\n    fp.append(Text(type='value', text=footprint_name, at=[0,5.4 ], layer='F.Fab'))\n\n    #Major dimensions\n    B = ( pincount - 1 ) * pitch\n    A = B + 4.7\n\n    #pins\n    fp.append(\n        PadArray(\n                pincount=pincount,\n                initial = 1,\n                start = [0, 0],\n                x_spacing = pitch,\n                type = Pad.TYPE_THT,\n                layers = Pad.LAYERS_THT,\n                shape = Pad.SHAPE_CIRCLE,\n                size = pad_size,\n                drill = drill,\n                )\n    )\n\n    #calculate major dimensions\n    x1 = (B - A) / 2\n    x2 = x1 + A\n\n    #courtyard\n    fp.append(RectLine(start=[x1,yt],end=[x2,y2],layer='F.CrtYd',width=0.05,grid=0.05,offset=0.5))\n\n    #mounting hole\n    if pincount > 1:\n        fp.append(Pad(at=[-1.5,3.25],type=Pad.TYPE_NPTH,layers=Pad.LAYERS_NPTH,shape=Pad.SHAPE_CIRCLE,size=mount_size,drill=mount_size))\n\n    #connector outline\n\n    #tab thickness\n    t = 1.2\n\n    def outline(offset=0):\n        outline = [\n        {'x': B/2, 'y': y2 + offset},\n        {'x': x1 - offset, 'y': y2 + offset},\n        {'x': x1 - offset, 'y': yt - offset},\n        {'x': x1 + t + offset, 'y': yt - offset},\n        {'x': x1 + t + offset, 'y': y1 - offset},\n        {'x': B/2, 'y': y1 - offset},\n        ]\n\n        return outline\n\n    fp.append(PolygoneLine(polygone=outline(),layer='F.Fab'))\n    fp.append(PolygoneLine(polygone=outline(),layer='F.Fab',x_mirror=B/2))\n\n    fp.append(PolygoneLine(polygone=outline(offset=0.15)))\n    fp.append(PolygoneLine(polygone=outline(offset=0.15),x_mirror=B/2))\n\n    #draw lines between pads on F.Fab\n    for i in range(pincount - 1):\n        x = (i + 0.5) * pitch\n\n        fp.append(Line(start=[x,y1],end=[x,y2],layer='F.Fab'))\n\n    \"\"\"\n\n    #connector outline (f.fab layer)\n    #y-top\n    yt = yp - ph / 2 + 0.3\n    #y-bottom\n    yb = yt + 2.77\n    #y-notch\n    yn = 0.5\n\n    outline = [\n    {'x': 0,'y': yt},\n    {'x': -B/2 - pitch,'y': yt},\n    {'x': -B/2 - pitch,'y': yt},\n    {'x': -B/2 - pitch,'y': yt + yn},\n    {'x': -A/2,'y': yt + yn},\n    {'x': -A/2,'y': yb},\n    {'x': 0,'y': yb},\n    ]\n\n    fp.append(PolygoneLine(polygone=outline,layer='F.Fab'))\n    fp.append(PolygoneLine(polygone=outline,layer='F.Fab',x_mirror=0))\n\n    #draw pin-1 indicator on F.Fab\n    #size of arrow a\n    a = 0.6\n    fp.append(PolygoneLine(polygone=[\n        {'x': -B/2, 'y': yt + a},\n        {'x': -B/2 - a/2, 'y': yt},\n        {'x': -B/2 + a/2, 'y': yt},\n        {'x': -B/2, 'y': yt + a}], layer='F.Fab'))\n\n    #draw pin-1 indicator on Silk.S\n    ya = -2\n    fp.append(PolygoneLine(polygone=[\n        {'x': -B/2, 'y': ya},\n        {'x': -B/2 - a/2, 'y': ya - a},\n        {'x': -B/2 + a/2, 'y': ya - a},\n        {'x': -B/2, 'y': ya},\n        ]))\n\n    #silkscreen\n    #offset from pads\n    op = 0.3\n    #offset from F.fab\n    of = 0.15\n\n    #Sides\n    silk = [\n    {'x': -B/2 - pw/2 - op, 'y': yt - of},\n    {'x': -B/2 - of - pitch, 'y': yt - of},\n    {'x': -B/2 - of - pitch, 'y': yt - of + yn},\n    {'x': -A/2 - of, 'y': yt - of + yn},\n    {'x': -A/2 - of, 'y': ym - mh / 2 - op},\n    ]\n\n    fp.append(PolygoneLine(polygone = silk))\n    fp.append(PolygoneLine(polygone = silk, x_mirror = 0))\n\n    #bottom line\n    fp.append(Line(\n        start=[-xm + mw/2 + op, yb + of],\n        end  =[ xm - mw/2 - op, yb + of]))\n\n    #courtyard\n    y1 = yp - ph / 2\n    y2 = ym + mh / 2\n    x1 = xm + mw / 2\n\n    fp.append(RectLine(start=[-x1,y1],end=[x1,y2],layer='F.CrtYd',width=0.05,grid=0.05,offset=0.5))\n\n    \"\"\"\n\n    #add a 3D model reference\n    fp.append(Model(filename=\"Connectors_Hirose.3dshapes/\" + footprint_name + \".wrl\"))\n\n    #filename\n    filename = output_dir + footprint_name + \".kicad_mod\"\n\n    file_handler = KicadFileHandler(fp)\n    file_handler.writeFile(filename)\n"
  },
  {
    "path": "scripts/Connector/Connector_IEC_DIN/generate_din41612.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nimport math\n\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"..\")) # for KicadModTree\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"tools\")) # for drawing_tools\n\nfrom KicadModTree import *\nfrom drawing_tools import *\n\n# According to IEC 60603-2 §3 and DIN 41612-1 §2 connector names should be like\n# this:\n# \"${STANDARD}${TYPE}${PINCOUNT}${GENDER}${METHOD}-${FURTHER_INFO}\"\n# with:\n# STANDARD: either \"IEC 60603-2 \" or \"DIN 41 612-\"\n# TYPE: B, C, D, E, F, G, H, M, Q, R, S, T, U, V, W\n# PINCOUNT: Number of populated pins, 3 digits\n# SEX: M: male, F: female\n# METHOD: A: screws, C (DIN) crimp (IEC), D: insulation displacement (IEC),\n#         K: clamps (DIN), P: press fit (DIN) S: solder, T: blade receptacle,\n#         W: wire wrap\n# FURTHER_INFO: Pin length, materials and other things that don't change the\n#               footprint.\n#\n# This library choose to use the prefix \"Conn_DIN41612_\", because Din 41612 is\n# more common term.\n# METHOD and further are ommited, because the footprint is suited for\n# soldering and press fit.\n#\n# It includes half and third sized connectors, that are not part of IEC 60603\n# or DIN 41612. These connectors are named 2X and 3X, a convention also used by\n# Harting.\n\n\n\n# When a manufacturer is mentioned in the comment, it means that\n# the value is explicitly stated in a datasheet by this company.\n\nROW_IDENTIFIER = ('a', 'b')\nLIBRARY_NAME = 'Connector_DIN'\nORIENTATION = {'H': 'Horizontal', 'V': 'Vertical'}\n\n#fp_name_format_string = \"Conn_DIN41612_{size:s}{num_pins:d}{gender:s}\n#fp_name_format_string = \"DIN41612_{size:s}{num_pins:d}{gender:s}_{num_rows:d}x{pins_per_row:d}_{orientation:s}\"\nfp_name_format_string = \"DIN41612_{size:s}_{num_rows:d}x{pins_per_row:d}_{orientation:s}\"\n\ndef AllPins(row, col):\n\treturn True\n\ndef EvenColPins(row, col):\n\treturn not bool(col % 2)\n\ndef OptionalPin(kicad_mod, row, col, row_step, col_step, pin_pad, pin_drill, opt_cb, rotate = False):\n\tif not opt_cb(row, col):\n\t\treturn\n\tshape = Pad.SHAPE_CIRCLE\n\tif col == 1 and row == ROW_IDENTIFIER[0]:\n\t\tshape = Pad.SHAPE_RECT\n\tif rotate:\n\t\tx = row_step * (ord(row) - ord(ROW_IDENTIFIER[0]))\n\t\ty = -col_step*(col-1)\n\telse:\n\t\tx = col_step*(col-1)\n\t\ty = row_step * (ord(row) - ord(ROW_IDENTIFIER[0]))\n\n\tkicad_mod.append(Pad(number= row + str(col), type=Pad.TYPE_THT, shape=shape,\n\t\t\t at=[x, y], size=pin_pad, drill=pin_drill, layers=Pad.LAYERS_THT))\n\t# don't know if KLC allows 3d compositing at all\n\t#pin_model = \"Pin_Headers.3dshapes/Pin_Header_Straight_1x01_Pitch2.54mm.wrl\"\n\t#inch = 25.4\n\t#pos_inch = [x/inch, -y/inch, 0]\n\t#kicad_mod.append(Model(filename=pin_model, at=pos_inch, scale=[1, 1, 1], rotate=[0, 0, 0]))\n\n\ndef BFemale(size, pin_cb, more_description):\n\t# This footprint is rotated by 90° counter clockwise\n\t# so columns are in x-direction and rows are in y-direction\n\tcolss = [32, 16, 10]\n\tcols = colss[size]\n\tnpth_b_offset_x = -0.3 # ERNI and ept\n\tnpth_steps = [90, 50, 34.76] # ERNI and ept\n\tnpth_step = npth_steps[size]\n\tnpth_drill = 2.8 # ERNI and ept\n\tcol_step = -2.54 # ERNI and ept\n\trow_step = 2.54 # ERNI and ept\n\tpin_drill = 1 # ERNI and ept\n\tpin_pad = 1.7 # same as module pinheader\n\touter_lengths = [95, 55, 39.76] # maximum value from ERNI and ept\n\touter_length = outer_lengths[size]\n\touter_width = 8.1 # ERNI and ept\n\tjack_width = 5.95 # ERNI: 6(-0.1), ept: 5.95(±0.05)\n\tjack_lengths = [85, 44.4, 29.1] # ERNI\n\tjack_length = jack_lengths[size]\n\tnotch_depth = 1 # ERNI and ept\n\tnotch_bottom_offset = -3 # ERNI and ept\n\n\tmid_x =  0.5 * row_step\n\tmid_y = -0.5 * col_step * (cols - 1)\n\n\t# ------ Init ------\n\tpin_count = 0;\n\tfor col in range(1, cols + 1):\n\t\tpin_count += int(pin_cb('A', col))\n\t\tpin_count += int(pin_cb('B', col))\n\t#size_names = [\"B\", \"2B\", \"3B\"]\n\tsize_names = [\"B\", \"B2\", \"B3\"]\n\tfootprint_name = fp_name_format_string.format(\n\t\tsize=size_names[size], num_pins=pin_count, gender=\"F\",\n\t\tnum_rows=2, pins_per_row=pin_count//2, orientation=ORIENTATION['V'])\n\n\t# init kicad footprint\n\tkicad_mod = Footprint(footprint_name)\n\tsize_descs = [\"B\", \"B/2\", \"B/3\"]\n\tkicad_mod.setDescription(\"DIN 41612 connector, type \" + size_descs[size] + \", vertical, \" + str(cols) + \" pins wide, 2 rows\" + more_description)\n\tkicad_mod.setTags(\"DIN 41512 IEC 60603 \" + size_descs[size])\n\n\t# ------ Pins and holes ------\n\tfor col in range(1, cols + 1):\n\t\tOptionalPin(kicad_mod, ROW_IDENTIFIER[0], col, row_step, col_step, pin_pad, pin_drill, pin_cb, True)\n\t\tOptionalPin(kicad_mod, ROW_IDENTIFIER[1], col, row_step, col_step, pin_pad, pin_drill, pin_cb, True)\n\n\t# non-plated drill holes, assumed to be equally distant to pins\n\tnpth_x = row_step + npth_b_offset_x\n\tnpth_y_left  = mid_y - npth_step * 0.5\n\tnpth_y_right = mid_y + npth_step * 0.5\n\tkicad_mod.append(Pad(number=\"\", type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n\t\t\t\t\t at=[npth_x, npth_y_left], size=npth_drill, drill=npth_drill, layers=Pad.LAYERS_NPTH))\n\tkicad_mod.append(Pad(number=\"\", type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n\t\t\t\t\t at=[npth_x, npth_y_right], size=npth_drill, drill=npth_drill, layers=Pad.LAYERS_NPTH))\n\n\n\t# ------ Courtyard ------\n\t# KLC: connectors should have 0.5mm clearance\n\tkicad_mod.append(RectLine(\n\t\tstart=[mid_x - outer_width/2 - 0.5, mid_y - outer_length/2 - 0.5],\n\t\tend=[mid_x + outer_width/2 + 0.5, mid_y + outer_length/2 + 0.5],\n\t\tlayer='F.CrtYd'))\n\n\t# ------ Fabrication layer ------\n\tj_t_x = mid_x - jack_width * 0.5 # jack top\n\tj_b_x = mid_x + jack_width * 0.5 # jack bottom\n\tj_l_y = mid_y - jack_length * 0.5 # jack left\n\tj_r_y = mid_y + jack_length * 0.5 # jack right\n\tn_x  = j_b_x + notch_bottom_offset # notch\n\tn_l_y = j_l_y + notch_depth # notch left\n\tn_r_y = j_r_y - notch_depth # notch right\n\n\tjack_notch_left  = [[j_t_x, n_l_y], [j_t_x, j_l_y], [n_x, j_l_y], [n_x, n_l_y], [j_b_x, n_l_y]]\n\tjack_notch_right = [[j_b_x, n_r_y], [n_x, n_r_y], [n_x, j_r_y], [j_t_x, j_r_y], [j_t_x, n_r_y]]\n\tpin_a1_arrow = [ # form taken from module Connectors_Molex\n\t\t[mid_x - outer_width/2 - 0.2,  0.0],\n\t\t[mid_x - outer_width/2 - 0.8, -0.3],\n\t\t[mid_x - outer_width/2 - 0.8,  0.3],\n\t\t[mid_x - outer_width/2 - 0.2,  0.0],\n\t]\n\n\tkicad_mod.append(PolygoneLine(\n\t\tpolygone=jack_notch_left + jack_notch_right + [jack_notch_left[0]],\n\t\tlayer='F.Fab'))\n\tkicad_mod.append(PolygoneLine(\n\t\tpolygone=pin_a1_arrow,\n\t\twidth=0.12,\n\t\tlayer='F.Fab'))\n\tkicad_mod.append(Text(\n\t\ttype='value', text=footprint_name,\n\t\tat=[mid_x, mid_y + outer_length/2 + 1.3],\n\t\tlayer='F.Fab'))\n\t# Very small Reference Designator to fit between the pins.\n\tkicad_mod.append(Text(\n\t\ttype='user', text='%R',\n\t\tat=[mid_x, mid_y],\n\t\tsize=[0.6, 0.6], thickness=0.07,\n\t\tlayer='F.Fab'))\n\n\t# ------ Silk screen ------\n\t# assume plastic part to be centered around the pins\n\t# silk screen must be visible, so add 0.1 mm\n\tkicad_mod.append(RectLine(\n\t\tstart=[mid_x - outer_width/2 - 0.1, mid_y - outer_length/2 - 0.1],\n\t\tend=[mid_x + outer_width/2 + 0.1, mid_y + outer_length/2 + 0.1],\n\t\twidth=0.15,\n\t\tlayer='F.SilkS'))\n\tkicad_mod.append(PolygoneLine(\n\t\tpolygone=jack_notch_left,\n\t\twidth=0.15,\n\t\tlayer='F.SilkS'))\n\tkicad_mod.append(PolygoneLine(\n\t\tpolygone=jack_notch_right,\n\t\twidth=0.15,\n\t\tlayer='F.SilkS'))\n\tkicad_mod.append(PolygoneLine(\n\t\tpolygone=pin_a1_arrow,\n\t\twidth=0.12,\n\t\tlayer='F.SilkS'))\n\tkicad_mod.append(Text(\n\t\ttype='reference', text='REF**',\n\t\tat=[mid_x, mid_y - outer_length/2 - 1],\n\t\tlayer='F.SilkS'))\n\n\t# ------ 3D reference ------\n\t# in case someone wants to make a model\n\tkicad_mod.append(Model(\n\t\tfilename=\"${KISYS3DMOD}/Connectors_IEC_DIN.3dshapes/\" + footprint_name + \".wrl\",\n\t\tat=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n\n\t# ------ Output ------\n\tfile_handler = KicadFileHandler(kicad_mod)\n\n\toutput_dir = '{lib_name:s}.pretty/'.format(lib_name=LIBRARY_NAME)\n\tif not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n\t\tos.makedirs(output_dir)\n\tfilename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n\tfile_handler.writeFile(filename)\n\n\ndef BMale(size, pin_cb, more_description):\n\tcolss = [32, 16, 10]\n\tcols = colss[size]\n\tnpth_a_offset_y = -2.54 # ERNI\n\tnpth_steps = [88.9, 48.26, 33.02] # ERNI\n\tnpth_step = npth_steps[size]\n\tnpth_drill = 2.8 # ERNI\n\tcol_step = 2.54 # ERNI and ept\n\trow_step = 2.54 # ERNI and ept\n\tpin_drill = 1 # ERNI and ept\n\tpin_pad = 1.7 # same as module pinheader\n\tjack_to_npth = 10.2 # ERNI\n\tjack_widths = [87.5, 47, 31.7] # ERNI\n\tjack_width = jack_widths[size]\n\tjack_to_eyelet = 12.7\n\teyelet_spans = [94, 53.5, 38.1] # ERNI or ept\n\teyelet_span = eyelet_spans[size]\n\tboard_edge_to_a = 5.3 # ERNI\n\n\tmid_x = 0.5 * col_step * (cols - 1)\n\tmid_y = 0.5 * row_step\n\n\t# ------ Init ------\n\tpin_count = 0;\n\tfor col in range(1, cols + 1):\n\t\tpin_count += int(pin_cb('A', col))\n\t\tpin_count += int(pin_cb('B', col))\n\t#size_names = [\"B\", \"2B\", \"3B\"]\n\tsize_names = [\"B\", \"B2\", \"B3\"]\n\tfootprint_name = fp_name_format_string.format(\n\t\tsize=size_names[size], num_pins=pin_count, gender=\"M\",\n\t\tnum_rows=2, pins_per_row=pin_count//2, orientation=ORIENTATION['H'])\n\n\t# init kicad footprint\n\tkicad_mod = Footprint(footprint_name)\n\tsize_descs = [\"B\", \"B/2\", \"B/3\"]\n\tkicad_mod.setDescription(\"DIN 41612 connector, type \" + size_descs[size] + \", horizontal, \" + str(cols) + \" pins wide, 2 rows\" + more_description)\n\tkicad_mod.setTags(\"DIN 41512 IEC 60603 \" + size_descs[size])\n\n\t# ------ Pins and holes ------\n\tfor col in range(1, cols + 1):\n\t\tOptionalPin(kicad_mod, ROW_IDENTIFIER[0], col, row_step, col_step, pin_pad, pin_drill, pin_cb)\n\t\tOptionalPin(kicad_mod, ROW_IDENTIFIER[1], col, row_step, col_step, pin_pad, pin_drill, pin_cb)\n\n\t# non-plated drill holes, assumed to be equally distant to pins\n\tnpth_x_left  = mid_x - npth_step * 0.5\n\tnpth_x_right = mid_x + npth_step * 0.5\n\tnpth_y = npth_a_offset_y\n\tkicad_mod.append(Pad(number=\"\", type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n\t\t\t\t\t at=[npth_x_left, npth_y], size=npth_drill, drill=npth_drill, layers=Pad.LAYERS_NPTH))\n\tkicad_mod.append(Pad(number=\"\", type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n\t\t\t\t\t at=[npth_x_right, npth_y], size=npth_drill, drill=npth_drill, layers=Pad.LAYERS_NPTH))\n\n\t# ------ Silk screen ------\n\t# assume plastic part to be centered around the pins\n\teyelet_border = jack_to_eyelet - jack_to_npth\n\tpackage_outline = [\n\t\t[mid_x - eyelet_span/2 + 2 * eyelet_border, npth_y + eyelet_border - pin_drill/2], # x: guess\n\t\t[mid_x - eyelet_span/2 + 2 * eyelet_border, npth_y + eyelet_border], # x: guess\n\t\t[mid_x - eyelet_span/2, npth_y + eyelet_border],\n\t\t[mid_x - eyelet_span/2, npth_y - eyelet_border], # y: guess, not ept\n\t\t[mid_x - jack_width/2, npth_y - eyelet_border], # y: guess, not ept\n\t\t[mid_x - jack_width/2, npth_y - jack_to_npth],\n\t\t# --- mirror line ---\n\t\t[mid_x + jack_width/2, npth_y - jack_to_npth],\n\t\t[mid_x + jack_width/2, npth_y - eyelet_border], # y: guess, not ept\n\t\t[mid_x + eyelet_span/2, npth_y - eyelet_border], # y: guess, not ept\n\t\t[mid_x + eyelet_span/2, npth_y + eyelet_border],\n\t\t[mid_x + eyelet_span/2 - 2 * eyelet_border, npth_y + eyelet_border], # x: guess\n\t\t[mid_x + eyelet_span/2 - 2 * eyelet_border, npth_y + eyelet_border - pin_drill/2], # x: guess\n\t]\n\t# silkscreen is offset by 0.1 mm to be visible with component placed\n\tsilkscreen_left = [\n\t\t[package_outline[ 0][0] + 0.1, package_outline[ 0][1] + 0.1],\n\t\t[package_outline[ 1][0] + 0.1, package_outline[ 1][1] + 0.1],\n\t\t[package_outline[ 2][0] - 0.1, package_outline[ 2][1] + 0.1],\n\t\t[package_outline[ 3][0] - 0.1, package_outline[ 3][1]],\n\t\t# can not draw further, it would leave the pcb\n\t]\n\tsilkscreen_right = [\n\t\t[package_outline[11][0] - 0.1, package_outline[11][1] + 0.1],\n\t\t[package_outline[10][0] - 0.1, package_outline[10][1] + 0.1],\n\t\t[package_outline[ 9][0] + 0.1, package_outline[ 9][1] + 0.1],\n\t\t[package_outline[ 8][0] + 0.1, package_outline[ 8][1]],\n\t\t# can not draw further, it would leave the pcb\n\t]\n\tpin_a1_arrow = [ # form taken from module Connectors_Molex\n\t\t[-pin_pad/2 - 0.5 - 0.0, 0.0],\n\t\t[-pin_pad/2 - 0.5 - 0.6, -0.3],\n\t\t[-pin_pad/2 - 0.5 - 0.6, 0.3],\n\t\t[-pin_pad/2 - 0.5 - 0.0, 0.0]\n\t]\n\tkicad_mod.append(PolygoneLine(\n\t\tpolygone=silkscreen_left,\n\t\twidth=0.15,\n\t\tlayer='F.SilkS'))\n\tkicad_mod.append(PolygoneLine(\n\t\tpolygone=silkscreen_right,\n\t\twidth=0.15,\n\t\tlayer='F.SilkS'))\n\tkicad_mod.append(PolygoneLine(\n\t\tpolygone=pin_a1_arrow,\n\t\twidth=0.12,\n\t\tlayer='F.SilkS'))\n\tkicad_mod.append(Text(\n\t\ttype='reference', text='REF**',\n\t\tat=[mid_x - npth_step * 0.5, row_step * 0.5],\n\t\tlayer='F.SilkS'))\n\n\t# ------ Fabrication layer ------\n\tkicad_mod.append(PolygoneLine(\n\t\tpolygone = package_outline + [package_outline[0]],\n\t\tlayer = 'F.Fab'))\n\tkicad_mod.append(Text(\n\t\ttype='value', text=footprint_name,\n\t\tat=[mid_x, npth_y + jack_to_npth - 1.3],\n\t\tlayer='F.Fab'))\n\tkicad_mod.append(Text(\n\t\ttype='user', text='%R',\n\t\tat=[mid_x, npth_y],\n\t\tsize=[1, 1], thickness=0.15,\n\t\tlayer='F.Fab'))\n\n\t# ------ Courtyard ------\n\t# KLC: connectors should have 0.5mm clearance\n\tcourtyard = [\n\t\t[-pin_pad/2 - 0.5, row_step + pin_pad/2 + 0.5],\n\t\t[-pin_pad/2 - 0.5, package_outline[10][1] + 0.5],\n\t\t[package_outline[ 2][0] - 0.5, package_outline[ 2][1] + 0.5],\n\t\t[package_outline[ 3][0] - 0.5, package_outline[ 3][1] - 0.5],\n\t\t[package_outline[ 4][0] - 0.5, package_outline[ 4][1] - 0.5],\n\t\t[package_outline[ 5][0] - 0.5, package_outline[ 5][1] - 0.5],\n\t\t[package_outline[ 6][0] + 0.5, package_outline[ 6][1] - 0.5],\n\t\t[package_outline[ 7][0] + 0.5, package_outline[ 7][1] - 0.5],\n\t\t[package_outline[ 8][0] + 0.5, package_outline[ 8][1] - 0.5],\n\t\t[package_outline[ 9][0] + 0.5, package_outline[ 9][1] + 0.5],\n\t\t[package_outline[10][0] - 0.5, package_outline[10][1] + 0.5],\n\t\t[(cols - 1) * col_step + pin_pad/2 + 0.5, package_outline[ 1][1] + 0.5],\n\t\t[(cols - 1) * col_step + pin_pad/2 + 0.5, row_step + pin_pad/2 + 0.5],\n\t]\n\tkicad_mod.append(PolygoneLine(\n\t\tpolygone = courtyard + [courtyard[0]],\n\t\tlayer = 'F.CrtYd'))\n\n\t# ------ Board edge ------\n\tkicad_mod.append(Line(\n\t\tstart = [mid_x - jack_width/2, -board_edge_to_a],\n\t\tend = [mid_x + jack_width/2, -board_edge_to_a],\n\t\twidth = 0.08,\n\t\tlayer = 'Dwgs.User'))\n\tkicad_mod.append(Line(\n\t\tstart = [mid_x, -board_edge_to_a - 1.5],\n\t\tend = [mid_x, -board_edge_to_a - 0.1],\n\t\twidth = 0.1,\n\t\tlayer = 'Cmts.User'))\n\tkicad_mod.append(PolygoneLine(\n\t\tpolygone = [\n\t\t\t[mid_x - 0.2, -board_edge_to_a - 0.6],\n\t\t\t[mid_x, -board_edge_to_a - 0.1],\n\t\t\t[mid_x + 0.2, -board_edge_to_a - 0.6],\n\t\t],\n\t\twidth = 0.1,\n\t\tlayer = 'Cmts.User'))\n\tkicad_mod.append(Text(\n\t\ttype='user', text='Board edge',\n\t\tat=[mid_x, -board_edge_to_a - 2],\n\t\tsize=[0.7, 0.7], thickness=0.1,\n\t\tlayer='Cmts.User'))\n\n\t# ------ 3D reference ------\n\t# in case someone wants to make a model\n\tkicad_mod.append(Model(\n\t\tfilename=\"{prefix}{lib_name}.3dshapes/{fp_name}.wrl\".format(prefix = '${KISYS3DMOD}/', lib_name=LIBRARY_NAME, fp_name=footprint_name),\n\t\tat=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n\n\t# ------ Output ------\n\tfile_handler = KicadFileHandler(kicad_mod)\n\n\toutput_dir = '{lib_name:s}.pretty/'.format(lib_name=LIBRARY_NAME)\n\tif not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n\t\tos.makedirs(output_dir)\n\tfilename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n\tfile_handler.writeFile(filename)\n\n\n\n\nBFemale(0, AllPins, \", full configuration\")\nBFemale(0, EvenColPins, \", even columns\")\nBFemale(1, AllPins, \", full configuration\")\nBFemale(1, EvenColPins, \", even columns\")\nBFemale(2, AllPins, \", full configuration\")\nBFemale(2, EvenColPins, \", even columns\")\n\nBMale(0, AllPins, \", full configuration\")\nBMale(0, EvenColPins, \", even columns\")\nBMale(1, AllPins, \", full configuration\")\nBMale(1, EvenColPins, \", even columns\")\nBMale(2, AllPins, \", full configuration\")\nBMale(2, EvenColPins, \", even columns\")\n\n# output kicad model\n"
  },
  {
    "path": "scripts/Connector/Connector_JAE/conn_ffc_jae_ff08.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\nfrom footprint_keepout_area import addRectangularKeepout\n\npinrange = [25, 29, 41, 51, 71, 81]\n\nseries = \"\"\nseries_long = 'JAE 0.2mm pitch, 1mm overall height FFC/FPC connector'\nmanufacturer = 'JAE'\norientation = 'H'\nnumber_of_rows = 2\ndatasheet='http://www.jae.com/z-en/pdf_download_exec.cfm?param=SJ108178.pdf'\n\nconn_category = \"FFC-FPC\"\n\nlib_by_conn_category = True\n\npart_code = \"FF08{:02d}SA1\"\n\n# def get_name(pin_count):\n#     return 'Molex-502250-{0}91_2Rows-{0}Pins_P0.3mm_Horizontal'.format(pin_count)\n\ncable_pitch = 0.2\nodd_pad_size = (0.55, 0.18) # bottom\neven_pad_size = (0.7, 0.18) # top\n\ndef make_module(pin_count, configuration):\n    pad_silk_off = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n    off = configuration['silk_fab_offset']\n\n    mpn = part_code.format(pin_count)\n\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_unequal_row_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins=pin_count, mounting_pad = \"\",\n        pitch=cable_pitch*2, orientation=orientation_str)\n\n    footprint_name = footprint_name.replace(\"__\",'_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setAttribute('smd')\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Circuits ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pin_count, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n    pad_to_pad_inside = 2\n    pad_to_pad_outside = pad_to_pad_inside + odd_pad_size[0] + even_pad_size[0]\n    row_spacing = pad_to_pad_outside - odd_pad_size[0]/2 - even_pad_size[0]/2\n\n    odd_pad_x = -pad_to_pad_outside/2 + odd_pad_size[0]/2\n    even_pad_x = odd_pad_x + row_spacing\n\n\n    B = cable_pitch * (pin_count - 1)\n\n    A = B + (7.05-4.8)\n    bar_width_max = 2*3.8\n    bar_chamfer_y = 1\n    bar_from_side_min = 0.1\n\n    bar_width = A - 2*bar_from_side_min\n    if bar_width > bar_width_max:\n        bar_width = bar_width_max\n\n    body_edge = {\n        'top': -A/2,\n        'bottom': A/2,\n        'left': odd_pad_x - odd_pad_size[0]/2 + 0.35\n    }\n    body_edge['right'] = body_edge['left'] + 2.85\n\n    bar_down_edge = body_edge['left'] + 3.23\n\n\n    bounding_box = {\n        'top': body_edge['top'],\n        'bottom': body_edge['bottom'],\n        'left': odd_pad_x - odd_pad_size[0]/2,\n        'right': bar_down_edge\n    }\n\n    kicad_mod.append(RectLine(\n        start=[body_edge['left'], body_edge['top']],\n        end=[body_edge['right'], body_edge['bottom']],\n        layer=\"F.Fab\", width=configuration['fab_line_width']\n    ))\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': body_edge['right'], 'y': -bar_width/2},\n            {'x': bar_down_edge, 'y': -bar_width/2 + bar_chamfer_y},\n            {'x': bar_down_edge, 'y': bar_width/2 - bar_chamfer_y},\n            {'x': body_edge['right'], 'y': bar_width/2}\n        ],\n        layer=\"F.Fab\", width=configuration['fab_line_width']\n    ))\n\n    odd_pins_outside = B/2 + odd_pad_size[1]/2 + pad_silk_off\n    silk_outline = [\n        {'x': body_edge['left']-off, 'y':odd_pins_outside},\n        {'x': body_edge['left']-off, 'y':body_edge['bottom']+off},\n        {'x': body_edge['right'] + off, 'y':body_edge['bottom']+off},\n        {'x': body_edge['right'] + off, 'y': bar_width/2 + off},\n        {'x': bar_down_edge + off, 'y': bar_width/2 - bar_chamfer_y + off},\n        {'x': bar_down_edge + off, 'y': 0}\n    ]\n    kicad_mod.append(PolygoneLine(\n        polygone=silk_outline,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']\n    ))\n    kicad_mod.append(PolygoneLine(\n        polygone=silk_outline, y_mirror=0,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']\n    ))\n\n    even_pins = pin_count//2\n    odd_pins = pin_count - even_pins\n    kicad_mod.append(PadArray(\n            center=[odd_pad_x,0], pincount=odd_pins,\n            initial=1, increment=2, y_spacing=2*cable_pitch,\n            type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n            size=odd_pad_size, layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(\n            center=[even_pad_x, 0], pincount=even_pins,\n            initial=2, increment=2, y_spacing=2*cable_pitch,\n            type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n            size=even_pad_size, layers=Pad.LAYERS_SMT))\n\n    pin1_y = -B/2\n    ps1_m = 0.3\n    p1s_x = bounding_box['left'] - pad_silk_off\n    pin = [\n        {'x': p1s_x -  ps1_m/sqrt(2), 'y': pin1_y-ps1_m/2},\n        {'x': p1s_x, 'y': pin1_y},\n        {'x': p1s_x -  ps1_m/sqrt(2), 'y': pin1_y+ps1_m/2},\n        {'x': p1s_x -  ps1_m/sqrt(2), 'y': pin1_y-ps1_m/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    sl=0.6\n    pin = [\n        {'x': body_edge['left'], 'y': pin1_y-sl/2},\n        {'x': body_edge['left'] + sl/sqrt(2), 'y': pin1_y},\n        {'x': body_edge['left'], 'y': pin1_y+sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='right')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    if lib_by_conn_category:\n        lib_name = configuration['lib_name_specific_function_format_string'].format(category=conn_category)\n    else:\n        lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for pincount in pinrange:\n        make_module(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JAE/conn_jae_LY20_tht_side.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\nfrom footprint_keepout_area import addRectangularKeepout\n\npins_per_row_range = range(2,23)\n\nseries = \"\"\nseries_long = 'LY 20 series connector'\nmanufacturer = 'JAE'\norientation = 'H'\nnumber_of_rows = 2\ndatasheet='http://www.jae.com/z-en/pdf_download_exec.cfm?param=SJ038187.pdf'\n\npart_code = \"LY20-{:d}P-DLT1\"\n\n# def get_name(pin_count):\n#     return 'Molex-502250-{0}91_2Rows-{0}Pins_P0.3mm_Horizontal'.format(pin_count)\n\npitch = 2\ndrill = 0.8\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n\npitch_row = 2\n\npad_size = [pitch_row - pad_to_pad_clearance, pitch - pad_to_pad_clearance]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\nif pad_size[1] - drill < 2*min_annular_ring:\n    pad_size[1] = drill + 2*min_annular_ring\nif pad_size[1] - drill > 2*max_annular_ring:\n    pad_size[1] = drill + 2*max_annular_ring\n\nROW_NAMES = ('a','b')\ndef incrementPadNumber(old_number):\n    return old_number[0] + str(int(old_number[1:])+1)\n\nif pad_size[0] == pad_size[1]:\n    pad_shape = Pad.SHAPE_CIRCLE\nelse:\n    pad_shape = Pad.SHAPE_OVAL\n\ndef make_module(pins_per_row, configuration):\n    pad_silk_off = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n    off = configuration['silk_fab_offset']\n\n    mpn = part_code.format(pins_per_row*2)\n\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    footprint_name = footprint_name.replace(\"__\",'_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Circuits ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    Wi = 4.8\n    T = 2.8\n    W = Wi + T\n\n\n    body_edge = {}\n    body_edge['right'] = pitch_row + 2.2 + T\n    body_edge['left'] = body_edge['right'] - W\n\n    A = (pins_per_row-1)*pitch\n    B = (A - 8) if A >= 8 else 0\n    C = (A - 4.6) if A >= 4.6 else 0\n    D = A + 2.6\n    E = A + 3.6\n\n    body_edge['top'] = -(E - A)/2\n    body_edge['bottom'] = body_edge['top'] + E\n\n    bounding_box = body_edge.copy()\n\n    ############################## Pins ###############################\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            initial=ROW_NAMES[row_idx]+'1', start=[(row_idx)*pitch_row, 0],\n            y_spacing=pitch, pincount=pins_per_row, increment=incrementPadNumber,\n            size=pad_size, drill=drill,\n            type=Pad.TYPE_THT, shape=pad_shape, layers=Pad.LAYERS_THT,\n            tht_pad1_id=ROW_NAMES[0]+'1',\n            **optional_pad_params))\n\n    ############################ Outline ##############################\n    kicad_mod.append(RectLine(\n        start=[body_edge['left'], body_edge['top']],\n        end=[body_edge['right'], body_edge['bottom']],\n        layer=\"F.Fab\", width=configuration['fab_line_width']\n    ))\n\n    r_no_silk = max(pad_size)/2 + pad_silk_off\n    dx = abs(body_edge['left']) + off\n    pin_center_silk_y = 0 if dx >= r_no_silk else sqrt(r_no_silk**2-dx**2)\n    pin1_center_silk_y = pad_size[1]/2 + pad_silk_off\n\n    YCb = A/2+C/2\n    YCt = A/2-C/2\n    YBb = A/2+B/2\n\n\n    poly_silk_b = [\n        {'x': body_edge['left']-off, 'y': body_edge['bottom']+off},\n        {'x': body_edge['right']+off, 'y': body_edge['bottom']+off},\n        {'x': body_edge['right']+off, 'y': YCb},\n    ]\n    if C > 0:\n        poly_silk_b.extend([\n            {'x': body_edge['right']-T, 'y': YCb},\n            {'x': body_edge['right']-T, 'y': A/2},\n        ])\n    kicad_mod.append(PolygoneLine(polygone=poly_silk_b,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=poly_silk_b, y_mirror=A/2,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n\n    if pin_center_silk_y == 0:\n        kicad_mod.append(Line(\n            start=[body_edge['left']-off, body_edge['top']],\n            end=[body_edge['left']-off, body_edge['bottom']],\n            layer=\"F.SilkS\", width=configuration['silk_line_width']\n        ))\n    else:\n        kicad_mod.append(Line(\n            start=[body_edge['left']-off, body_edge['top']-off],\n            end=[body_edge['left']-off, -pin1_center_silk_y],\n            layer=\"F.SilkS\", width=configuration['silk_line_width']\n        ))\n        kicad_mod.append(Line(\n            start=[body_edge['left']-off, pin1_center_silk_y],\n            end=[body_edge['left']-off, pitch-pin_center_silk_y],\n            layer=\"F.SilkS\", width=configuration['silk_line_width']\n        ))\n        kicad_mod.append(Line(\n            start=[body_edge['left']-off, A+pin_center_silk_y],\n            end=[body_edge['left']-off, body_edge['bottom']+off],\n            layer=\"F.SilkS\", width=configuration['silk_line_width']\n        ))\n        for i in range(1, pins_per_row-1):\n            yt = i*pitch + pin_center_silk_y\n            yb = (i+1)*pitch - pin_center_silk_y\n            kicad_mod.append(Line(\n                start=[body_edge['left']-off, yt],\n                end=[body_edge['left']-off, yb],\n                layer=\"F.SilkS\", width=configuration['silk_line_width']\n            ))\n\n    x1 = body_edge['right']-T\n\n    pin_w = 0.5\n    pin_L = 2.7\n    pin_chamfer_x = pin_w/3\n\n\n    if B>0:\n        x2 = x1 + 2 # estimated from drawing\n        poly = [\n            {'x': x2, 'y':YCb},\n            {'x': x2, 'y':YBb+pin_w/2}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly,\n            layer=\"F.SilkS\", width=configuration['silk_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=poly, y_mirror=A/2,\n            layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n\n    #pins\n    if C>0:\n        for i in range(pins_per_row):\n            ypc = i*pitch\n\n            x3 = x1 + pin_L\n            x2 = x3 - pin_chamfer_x\n\n            if ypc - pin_w/2 >= YCt and ypc + pin_w/2 <= YCb:\n                pin_poly = [\n                    {'x': x1, 'y': ypc-pin_w/2},\n                    {'x': x2, 'y': ypc-pin_w/2},\n                    {'x': x3, 'y': ypc},\n                    {'x': x2, 'y': ypc+pin_w/2},\n                    {'x': x1, 'y': ypc+pin_w/2}\n                ]\n                kicad_mod.append(PolygoneLine(polygone=pin_poly,\n                    layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    ########################### Pin 1 #################################\n\n    p1s_sl = 2\n    p1s_off = off + 0.3\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': body_edge['left'] + p1s_sl, 'y': body_edge['top'] - p1s_off},\n            {'x': body_edge['left'] - p1s_off, 'y': body_edge['top'] - p1s_off},\n            {'x': body_edge['left'] - p1s_off, 'y': body_edge['top'] + p1s_sl}\n        ], layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    p1f_sl = 1\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': body_edge['left'], 'y': p1f_sl/2},\n            {'x': body_edge['left'] + p1f_sl/sqrt(2), 'y': 0},\n            {'x': body_edge['left'], 'y': -p1f_sl/2}\n        ], layer=\"F.Fab\", width=configuration['fab_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        make_module(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JAE/conn_jae_LY20_tht_top.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\nfrom footprint_keepout_area import addRectangularKeepout\n\npins_per_row_range = range(2,23)\n\nseries = \"\"\nseries_long = 'LY 20 series connector'\nmanufacturer = 'JAE'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet='http://www.jae.com/z-en/pdf_download_exec.cfm?param=SJ103130.pdf'\n\npart_code = \"LY20-{:d}P-DT1\"\n\n# def get_name(pin_count):\n#     return 'Molex-502250-{0}91_2Rows-{0}Pins_P0.3mm_Horizontal'.format(pin_count)\n\npitch = 2\ndrill = 0.8\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n\npitch_row = 2\n\npad_size = [pitch_row - pad_to_pad_clearance, pitch - pad_to_pad_clearance]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\nif pad_size[1] - drill < 2*min_annular_ring:\n    pad_size[1] = drill + 2*min_annular_ring\nif pad_size[1] - drill > 2*max_annular_ring:\n    pad_size[1] = drill + 2*max_annular_ring\n\nROW_NAMES = ('a','b')\ndef incrementPadNumber(old_number):\n    return old_number[0] + str(int(old_number[1:])+1)\n\nif pad_size[0] == pad_size[1]:\n    pad_shape = Pad.SHAPE_CIRCLE\nelse:\n    pad_shape = Pad.SHAPE_OVAL\n\ndef make_module(pins_per_row, configuration):\n    pad_silk_off = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n    off = configuration['silk_fab_offset']\n\n    mpn = part_code.format(pins_per_row*2)\n\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    footprint_name = footprint_name.replace(\"__\",'_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Circuits ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    W = 5.3\n    Wi = 4.2\n\n    body_edge = {}\n    body_edge['left'] = -(W - pitch_row)/2\n    body_edge['right'] = body_edge['left'] + W\n\n    A = (pins_per_row-1)*pitch\n    B = (A - 8) if A >= 8 else 0\n    C = (A - 4.6) if A >= 4.6 else 0\n    D = A + 2.6\n    E = A + 3.6\n\n    body_edge['top'] = -(E - A)/2\n    body_edge['bottom'] = body_edge['top'] + E\n\n    bounding_box = body_edge.copy()\n\n    ############################## Pins ###############################\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            initial=ROW_NAMES[row_idx]+'1', start=[(row_idx)*pitch_row, 0],\n            y_spacing=pitch, pincount=pins_per_row, increment=incrementPadNumber,\n            size=pad_size, drill=drill,\n            type=Pad.TYPE_THT, shape=pad_shape, layers=Pad.LAYERS_THT,\n            tht_pad1_id=ROW_NAMES[0]+'1',\n            **optional_pad_params))\n\n    ############################ Outline ##############################\n    kicad_mod.append(RectLine(\n        start=[body_edge['left'], body_edge['top']],\n        end=[body_edge['right'], body_edge['bottom']],\n        layer=\"F.Fab\", width=configuration['fab_line_width']\n    ))\n\n    kicad_mod.append(RectLine(\n        start=[body_edge['left'], body_edge['top']],\n        end=[body_edge['right'], body_edge['bottom']],\n        layer=\"F.SilkS\", width=configuration['silk_line_width'],\n        offset=off\n    ))\n\n    # inside\n    CW = 1\n    xil = body_edge['left'] + (W - Wi)/2\n    xir =xil + Wi\n    yit = body_edge['top'] + (E-D)/2\n    yt1 = A/2-C/2\n    yb1 = A/2+C/2\n    yt2 = A/2-B/2\n\n    poly_left_t = [\n        {'x': pitch_row-CW/2, 'y': body_edge['top'] - off},\n        {'x': pitch_row-CW/2, 'y': yit},\n        {'x': xil, 'y': yit},\n        {'x': xil, 'y': yt1},\n        {'x': body_edge['left']-off, 'y': yt1},\n    ]\n    if C == 0:\n        del poly_left_t[-1]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_left_t,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=poly_left_t, y_mirror=A/2,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    poly_right_t = [\n        {'x': pitch_row+CW/2, 'y': body_edge['top'] - off},\n        {'x': pitch_row+CW/2, 'y': yit},\n        {'x': xir, 'y': yit},\n        {'x': xir, 'y': yt2},\n        {'x': body_edge['right']+off, 'y': yt2},\n    ]\n    if B == 0:\n        del poly_right_t[-1]\n    else:\n        kicad_mod.append(Line(\n            start={'x': body_edge['right']+off, 'y': yt1},\n            end={'x': xir, 'y': yt1},\n            layer=\"F.SilkS\", width=configuration['silk_line_width']\n        ))\n        kicad_mod.append(Line(\n            start={'x': body_edge['right']+off, 'y': yb1},\n            end={'x': xir, 'y': yb1},\n            layer=\"F.SilkS\", width=configuration['silk_line_width']\n        ))\n\n    kicad_mod.append(PolygoneLine(polygone=poly_right_t,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=poly_right_t, y_mirror=A/2,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    ########################### Pin 1 #################################\n\n    p1s_sl = 2\n    p1s_off = off + 0.3\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': body_edge['left'] + p1s_sl, 'y': body_edge['top'] - p1s_off},\n            {'x': body_edge['left'] - p1s_off, 'y': body_edge['top'] - p1s_off},\n            {'x': body_edge['left'] - p1s_off, 'y': body_edge['top'] + p1s_sl}\n        ], layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    p1f_sl = 1\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': body_edge['left'], 'y': p1f_sl/2},\n            {'x': body_edge['left'] + p1f_sl/sqrt(2), 'y': 0},\n            {'x': body_edge['left'], 'y': -p1f_sl/2}\n        ], layer=\"F.Fab\", width=configuration['fab_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='right')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        make_module(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JAE/helpers.py",
    "content": "def roundToBase(value, base):\n    if base == 0:\n        return value\n    return round(value/base) * base\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/00-SMD footprint generators can be found in Connector_SMD_single_row_plus_mounting_pad.md",
    "content": "The following connector footprints are generated in the generic scirpt located in ../Connector_SMD_single_row_plus_mounting_pad/\n\n- 'ACH'\n- 'AUH'\n- 'LEA'\n- 'GH'\n- 'PH' (only SMD version = `*PH-SM4*`)\n- 'SFH'\n- 'SHL'\n- 'SH'\n- 'SUR'\n- 'XAG'\n- 'ZE'\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_J2100_tht_side.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\nfrom math import sqrt\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"J2100\"\nmanufacturer = 'JST'\norientation = 'H'\nnumber_of_rows = 2\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eJFA-J2000.pdf'\n\npitch = 2.50\n\n#pin_range = [3,4,5,6,8,10] #number of pins in each row\npin_range = [6, 8, 10, 12, 16, 20]\nrow_pitch = 2.50\n\n#FP name strings\npart_base = \"S{n:02}B-J21DK-GG{s}R\" #JST part number format string\n\ndrill = 0.86 # 0.85 -0.03/+0.05 -> 0.86 +/-0.04\nmh_drill = 2\nmh_size = 3.4\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5\nmin_annular_ring = 0.15\n\nROW_NAMES = ('a','b')\ndef incrementPadNumber(old_number):\n    return old_number[0] + str(int(old_number[1:])+1)\n#FP description and tags\n\ndef generate_one_footprint(pins, configuration, keying):\n    #calculate fp dimensions\n    pins_per_row = int(pins / number_of_rows)\n    A = (pins_per_row - 1) * pitch\n    B = A + 5.2\n\n    #generate the name\n    mpn = part_base.format(n=pins, s=keying)\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    print('Building footprint: {}'.format(footprint_name))\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n    pad_size = [pitch - pad_to_pad_clearance, row_pitch - pad_to_pad_clearance]\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n\n    if pad_size[1] - drill > 2*pad_copper_y_solder_length:\n        pad_size[1] = drill + 2*pad_copper_y_solder_length\n    if pad_size[1] - drill < 2*min_annular_ring:\n        pad_size[1] = drill + 2*min_annular_ring\n\n    if pad_size[0] == pad_size[1]:\n        pad_shape = Pad.SHAPE_CIRCLE\n    else:\n        pad_shape = Pad.SHAPE_OVAL\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            initial=row_idx*pins_per_row+1, start=[0, -(row_idx)*row_pitch],\n            x_spacing=pitch, pincount=pins_per_row, increment=1,\n            size=pad_size, drill=drill, type=Pad.TYPE_THT,\n            shape=pad_shape, layers=Pad.LAYERS_THT, **optional_pad_params))\n\n    #draw the component outline\n    x1 = A/2 - B/2\n    x2 = x1 + B\n    y1 = -2.5 - 0.62\n    y2 = y1 + 17.8\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #draw the main outline around the footprint\n    kicad_mod.append(RectLine(start=[x1,y1], end=[x2,y2], layer='F.Fab', width=configuration['fab_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    if y1 < -row_pitch - pad_size[1]/2:\n        cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    else:\n        cy1 = roundToBase(-row_pitch - pad_size[1]/2-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #offset off\n    off = configuration['silk_fab_offset']\n\n    x1 -= off\n    y1 -= off\n    x2 += off\n    y2 += off\n\n    #outline\n    side = [\n    {'x': -1,'y': y1},\n    {'x': x1,'y': y1},\n    {'x': x1,'y': y2},\n    {'x': A/2,'y': y2},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=side, layer=\"F.SilkS\", width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=side, x_mirror=A/2, layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    #add mounting holes\n    if pins == 6:\n        m = Pad(at=[pitch,7],layers=Pad.LAYERS_THT,shape=Pad.SHAPE_CIRCLE,type=Pad.TYPE_THT,size=mh_size,drill=mh_drill)\n        kicad_mod.append(m)\n    else:\n        m1 = Pad(at=[0,7],layers=Pad.LAYERS_THT,shape=Pad.SHAPE_CIRCLE,type=Pad.TYPE_THT,size=mh_size,drill=mh_drill)\n        m2 = Pad(at=[A,7],layers=Pad.LAYERS_THT,shape=Pad.SHAPE_CIRCLE,type=Pad.TYPE_THT,size=mh_size,drill=mh_drill)\n\n        kicad_mod.append(m1)\n        kicad_mod.append(m2)\n\n    #add p1 marker\n    px = -3\n    m = 0.3\n\n    marker = [\n    {'x': px,'y': 0},\n    {'x': px-2*m,'y': m},\n    {'x': px-2*m,'y': -m},\n    {'x': px,'y': 0},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=marker, layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    sl = 1\n    marker = [\n        {'x': body_edge['left'],'y': sl/2},\n        {'x': body_edge['left'] +sl/sqrt(2),'y': 0},\n        {'x': body_edge['left'],'y': -sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=marker, layer='F.Fab', width=configuration['fab_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    #for pins_per_row in pin_range:\n        #generate_one_footprint(pins_per_row, configuration)\n    for pin_count in pin_range:\n        generate_one_footprint(pin_count, configuration, 'X')\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_J2100_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\nfrom math import sqrt\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"J2100\"\nmanufacturer = 'JST'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eJFA-J2000.pdf'\npitch = 2.50\n\n#pin_range = [3,4,5,6,8,10] #number of pins in each row\npin_range = [6, 8, 10, 12, 16, 20]\nrow_pitch = 4\n\n#FP name strings\npart_base = \"B{n:02}B-J21DK-GG{s}R\" #JST part number format string\n\ndrill = 0.86 # 0.85 -0.03/+0.05 -> 0.86 +/-0.04\nmh_drill = 2\nmh_size = 3\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5\nmin_annular_ring = 0.15\n\n#pin1_row_to_mh = 'far' # 'near'\n\nROW_NAMES = ('a','b')\ndef incrementPadNumber(old_number):\n    return old_number[0] + str(int(old_number[1:])+1)\n\n#FP description and tags\n\ndef generate_one_footprint(pins, configuration, keying):\n    #calculate fp dimensions\n    pins_per_row = int(pins / number_of_rows)\n    A = (pins_per_row - 1) * pitch\n    B = A + 5.2\n\n    mpn = part_base.format(n=pins, s=keying)\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_dual_pitch_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch_x=pitch, pitch_y=row_pitch, orientation=orientation_str)\n\n    print('Building footprint: {}'.format(footprint_name))\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n    pad_size = [pitch - pad_to_pad_clearance, row_pitch - pad_to_pad_clearance]\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n\n    if pad_size[1] - drill > 2*pad_copper_y_solder_length:\n        pad_size[1] = drill + 2*pad_copper_y_solder_length\n    if pad_size[1] - drill < 2*min_annular_ring:\n        pad_size[1] = drill + 2*min_annular_ring\n\n    if pad_size[0] == pad_size[1]:\n        pad_shape = Pad.SHAPE_CIRCLE\n    else:\n        pad_shape = Pad.SHAPE_OVAL\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(2):\n        #if pin1_row_to_mh == 'near':\n        if keying == 'X':\n            position_y = (row_idx)*row_pitch\n        elif keying == 'Y':\n            position_y = -(row_idx)*row_pitch\n\n        kicad_mod.append(PadArray(\n            initial=row_idx*pins_per_row+1, start=[0, position_y],\n            x_spacing=pitch, pincount=pins_per_row, increment=1,\n            size=pad_size, drill=drill, type=Pad.TYPE_THT, \n            shape=pad_shape, layers=Pad.LAYERS_THT, **optional_pad_params))\n\n    #draw the component outline\n    x1 = A/2 - B/2\n    x2 = x1 + B\n    y1 = -4.48\n    #if pin1_row_to_mh == 'near':\n    if keying == 'Y':\n        y1 -= row_pitch\n    y2 = y1 + 14.4\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #draw the main outline around the footprint\n    kicad_mod.append(RectLine(start=[x1,y1], end=[x2,y2], layer='F.Fab', width=configuration['fab_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #offset off\n    off = configuration['silk_fab_offset']\n\n\n    x1 -= off\n    y1 -= off\n    x2 += off\n    y2 += off\n\n    #outline\n    ol = RectLine(start=[x1,y1], end=[x2,y2], layer=\"F.SilkS\", width=configuration['silk_line_width'])\n    kicad_mod.append(ol)\n\n    #courtyard\n\n    #add mounting holes\n    mh_y = 3.3\n    #if pin1_row_to_mh != 'near':\n    if keying == 'X':\n        mh_y += row_pitch\n\n    m1 = Pad(at=[0, mh_y],layers=Pad.LAYERS_THT,shape=Pad.SHAPE_CIRCLE,type=Pad.TYPE_THT,size=3, drill=2)\n    m2 = Pad(at=[A, mh_y],layers=Pad.LAYERS_THT,shape=Pad.SHAPE_CIRCLE,type=Pad.TYPE_THT,size=3, drill=2)\n\n    kicad_mod.append(m1)\n    kicad_mod.append(m2)\n\n    #add p1 marker\n    px = -3\n    m = 0.3\n\n    marker = [\n    {'x': px,'y': 0},\n    {'x': px-2*m,'y': m},\n    {'x': px-2*m,'y': -m},\n    {'x': px,'y': 0},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=marker, layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    sl = 1\n    marker = [\n        {'x': body_edge['left'],'y': sl/2},\n        {'x': body_edge['left'] +sl/sqrt(2),'y': 0},\n        {'x': body_edge['left'],'y': -sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=marker, layer='F.Fab', width=configuration['fab_line_width']))\n\n    #line offset o\n    o = 1\n    ya = o\n    yb = -o-row_pitch\n    #if pin1_row_to_mh != 'near':\n    if keying == 'X':\n        ya += row_pitch\n        yb = -o\n    #draw lines between pin pairs\n    for i in range(pins_per_row - 1):\n        x = (i + 0.5) * pitch\n        kicad_mod.append(Line(start=[x,ya], end=[x,yb], width=configuration['fab_line_width'], layer='F.Fab'))\n\n    #draw the inside of the connector\n    #connector thickness t\n    t = 0.45\n    #notch size n\n    n = 1.2\n    inside = [\n    {'x': A/2 - n/2,'y': y1},\n    {'x': A/2 - n/2,'y': y1 + t},\n    {'x': x1 + t,'y': y1 + t},\n    {'x': x1 + t,'y': y2 - t},\n    {'x': x1 + t + n,'y': y2 - t},\n    {'x': x1 + t + n,'y': y2 - 2 * t},\n    {'x': A/2,'y': y2 - 2 * t}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone = inside, layer=\"F.SilkS\", width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone = inside, x_mirror=A/2, layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    #for pins_per_row in pin_range:\n        #generate_one_footprint(pins_per_row, configuration)\n    for pin_count in pin_range:\n        generate_one_footprint(pin_count, configuration, 'X')\n        #generate_one_footprint(pin_count, configuration, 'Y')\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_JWPF_tht_top.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"JWPF\"\nmanufacturer = 'JST'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eJWPF1.pdf'\n\n\npart_base = \"B{n:02}B-JWPF-SK-R\" #JST part number format string\n\nprefix = \"JST_JWPF_\"\n\npitch = 2.00\npad_to_pad_clearance = 0.8\npad_copper_x_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n# Connector Dimensions\ntab_width = 7.0\nrow_spacing = 4.0\npad_drill = 1.0\nmount_hole_size = 1.15\nmount_hole_offset_x = 1.5\n\n# Width of connector\njwpf_widths = {\n    2 : 8.1,\n    3 : 8.4,\n    4 : 8.4,\n    6 : 12.8,\n    8 : 12.5\n}\n\njwpf_lengths = {\n    2 : 7,\n    3 : 9,\n    4 : 11,\n    6 : 9.8,\n    8 : 11.8\n}\n\npin_range = [2, 3, 4, 6, 8]\n\n\ndef generate_one_footprint(pincount, configuration):\n    if pincount in [6, 8]:\n        number_of_rows = 2\n        pin_per_row = int(pincount / 2)\n    else:\n        number_of_rows = 1\n        pin_per_row = pincount\n\n    mpn = part_base.format(n=pincount)\n\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pin_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    conn_width = jwpf_widths[pincount]\n    conn_length = jwpf_lengths[pincount]\n\n    mount_hole_offset_y = 2.05 if number_of_rows == 1 else 2.45\n\n\n    # Add texts\n    x_mid = (number_of_rows-1) * row_spacing / 2\n    y_mid = (pin_per_row - 1) * pitch / 2.0\n\n    # Connector outline\n    y1 = y_mid - conn_length / 2\n    y2 = y_mid + conn_length / 2\n\n    x1 = -5.4 # measured from 3D model alignment\n    x2 = x1 + conn_width\n\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    y_ref = -3 if number_of_rows == 1 else -4\n\n    pad_size = [pad_drill + 2*pad_copper_x_solder_length, pitch - pad_to_pad_clearance]\n    if number_of_rows > 1:\n        if pad_size[0] - pad_drill > 2*pad_copper_x_solder_length:\n            pad_size[0] = pad_drill + 2*pad_copper_x_solder_length\n        if pad_size[0] - pad_drill < 2*min_annular_ring:\n            pad_size[0] = pad_drill + 2*min_annular_ring\n    if pad_size[1] - pad_drill < 2*min_annular_ring:\n        pad_size[1] = pad_drill + 2*min_annular_ring\n\n    if pad_size[0] == pad_size[1]:\n        pad_shape = Pad.SHAPE_CIRCLE\n    else:\n        pad_shape = Pad.SHAPE_OVAL\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    # Create pins\n    for i in range(number_of_rows):\n        kicad_mod.append(PadArray(\n            initial=1+i*pin_per_row, start=[i*row_spacing, 0],\n            pincount=pin_per_row, y_spacing=pitch,\n            type=Pad.TYPE_THT, shape=pad_shape,\n            size=pad_size, drill=pad_drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    # Add mounting hole\n    mx = -mount_hole_offset_x\n    my = (pin_per_row - 1) * pitch + mount_hole_offset_y\n    kicad_mod.append(Pad(at=[mx, my], size=mount_hole_size, drill=mount_hole_size, shape=Pad.SHAPE_CIRCLE, type=Pad.TYPE_NPTH, layers=Pad.LAYERS_NPTH))\n\n    # Tab dimensions\n    tw = 7\n    tt = 0.5\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    def draw_outline(offset=0, layer='F.Fab', width=configuration['fab_line_width']):\n        O = offset\n        R = 1.0\n\n        if pincount == 2:\n            poly = [\n                {'x': x2 + O - R, 'y': y1 - O},\n                {'x': x1 - O, 'y': y1 - O},\n                {'x': x1 - O, 'y': y2 + O},\n                {'x': x2 + O - R, 'y': y2 + O},\n            ]\n\n            kicad_mod.append(PolygoneLine(polygone=poly, layer=layer, width=width))\n        else:\n            # top line\n            kicad_mod.append(Line(start=[tt+x1-O+R, y1-O], end=[x2+O-R, y1-O], layer=layer, width=width))\n            # bottom line\n            kicad_mod.append(Line(start=[tt+x1-O+R, y2+O], end=[x2+O-R, y2+O], layer=layer, width=width))\n\n            # left line (including tab)\n            poly = [\n                {'x': tt+x1-O, 'y': y1-O+R},\n                {'x': tt+x1-O, 'y': y_mid - tw/2.0 - O},\n                {'x': x1-O, 'y': y_mid - tw/2.0 - O},\n                {'x': x1-O, 'y': y_mid + tw/2.0 + O},\n                {'x': tt+x1-O, 'y': y_mid + tw/2.0 + O},\n                {'x': tt+x1-O, 'y': y2+O-R}\n            ]\n\n            kicad_mod.append(PolygoneLine(polygone=poly, width=width, layer=layer))\n\n            # top left\n            kicad_mod.append(Arc(center=[tt+x1-O+R, y1-O+R], start=[tt+x1-O, y1-O+R], angle=90.0, layer=layer, width=width))\n            # bottom left\n            kicad_mod.append(Arc(center=[tt+x1-O+R, y2+O-R], start=[tt+x1-O+R, y2+O], angle=90.0, layer=layer, width=width))\n\n\n        # right line\n        kicad_mod.append(Line(start=[x2+O, y1-O+R], end=[x2+O, y2+O-R], layer=layer, width=width))\n\n        # top right\n        kicad_mod.append(Arc(center=[x2+O-R, y1-O+R], start=[x2+O-R, y1-O], angle=90.0, layer=layer, width=width))\n\n        # bottom right\n        kicad_mod.append(Arc(center=[x2+O-R, y2+O-R], start=[x2+O, y2+O-R], angle=90.0, layer=layer, width=width))\n\n\n    draw_outline()\n    draw_outline(offset=configuration['silk_fab_offset'], layer='F.SilkS', width=configuration['silk_line_width'])\n\n    # Add pin-1 marker on F.SilkS\n    Q = 0.35 # offset\n    L = 1.5\n    p1 = [\n        {'x': x1 - Q, 'y': y1 - Q + L},\n        {'x': x1 - Q, 'y': y1 - Q},\n        {'x': x1 - Q + L, 'y': y1 - Q},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=p1, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    # Add pin-1 marker on F.Fab\n    D = -0.5 - pad_size[1] / 2\n    M = 0.75\n    p1 = [\n        {'x': -M/2, 'y': D - M},\n        {'x': M/2, 'y': D - M},\n        {'x': 0, 'y': D},\n        {'x': -M/2, 'y': D - M},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=p1, layer='F.Fab', width=configuration['fab_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='left')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pin_range:\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_NV_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"NV\"\nmanufacturer = 'JST'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eNV.pdf'\n\npitch = 5.0\ndrill = 1.7 # 1.65 +0.1/-0 -> 1.7+/-0.05\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\npin_range = range(2, 5) #number of pins in each row\n\n#FP name strings\npart_base = \"B{n:02}P-NV\" #JST part number format string\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_base.format(n=pins)\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate dimensions\n    A = (pins - 1) * pitch\n    B = A + 5\n\n    #draw the component outline\n    x1 = A/2 - B/2\n    x2 = x1 + B\n    y2 = 4.8\n    y1 = y2 - 8.5\n\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #draw the main outline on F.Fab layer\n    kicad_mod.append(RectLine(start={'x':x1,'y':y1}, end={'x':x2,'y':y2}, layer='F.Fab', width=configuration['fab_line_width']))\n\n    #draw horizontal line for latch\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1,'y':(y1+1.7)},{'x':x2,'y':(y1+1.7)}],layer='F.Fab',width=0.1))\n\n\t#draw pin1 mark on F.Fab\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1,'y':-1},{'x':(x1+1),'y':0}],layer='F.Fab',width=0.1))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1,'y':1},{'x':(x1+1),'y':0}],layer='F.Fab',width=0.1))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #draw silk outline\n    off = configuration['silk_fab_offset']\n    x1 -= off\n    y1 -= off\n    x2 += off\n    y2 += off\n    kicad_mod.append(RectLine(start=[x1,y1], end=[x2,y2], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add pin1 mark on silk\n    px = x1 - 0.2\n    m = 0.3\n\n    marker = [{'x': px,'y': 0},{'x': px-2*m,'y': m},{'x': px-2*m,'y': -m},{'x': px,'y': 0}]\n\n    kicad_mod.append(PolygoneLine(polygone=marker, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #generate tht pads (1.65mm drill with 2.35x3mm oval pads)\n    pad_size = [pitch - pad_to_pad_clearance, drill + 2*pad_copper_y_solder_length]\n    if pad_size[0] - drill > 2*pad_copper_y_solder_length:\n        pad_size[0] = 2*pad_copper_y_solder_length + drill\n\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n\n    shape=Pad.SHAPE_OVAL\n    if pad_size[0] == pad_size[1]:\n        shape=Pad.SHAPE_CIRCLE\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(\n        pincount=pins, x_spacing=pitch,\n        type=Pad.TYPE_THT, shape=shape,\n        size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in range(2, 4):\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_PHD_horizontal.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\nfrom math import sqrt\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"PHD\"\nmanufacturer = 'JST'\norientation = 'H'\nnumber_of_rows = 2\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/ePHD.pdf'\n\npitch = 2.0\nrow_pitch = 2.0\ndrill = 0.75 # 0.7 +0.1/-0 -> 0.75+/-0.05\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\npin_range = range(4,18) #number of pins in each row\n\n#FP name strings\npart_base = \"S{n}B-PHDSS\" #JST part number format string\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_base.format(n=pins*number_of_rows) #JST part number format string\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n    A = (pins - 1) * pitch\n    B = A + 3.9\n\n    #generate the pads (row 1)\n    size = [pitch - pad_to_pad_clearance, row_pitch - pad_to_pad_clearance]\n    if size[0] - drill < 2*min_annular_ring:\n        size[0] = drill + 2*min_annular_ring\n    if size[0] - drill > 2*pad_copper_y_solder_length:\n        size[0] = drill + 2*pad_copper_y_solder_length\n\n    if size[1] - drill < 2*min_annular_ring:\n        size[1] = drill + 2*min_annular_ring\n    if size[1] - drill > 2*pad_copper_y_solder_length:\n        size[1] = drill + 2*pad_copper_y_solder_length\n\n    if size[0] == size[1]:\n        pad_shape = Pad.SHAPE_CIRCLE\n    else:\n        pad_shape = Pad.SHAPE_OVAL\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            pincount=pins, x_spacing=pitch,\n            type=Pad.TYPE_THT, shape=pad_shape,\n            start=[0, row_idx*row_pitch], initial=row_idx+1, increment=2,\n            size=size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    #draw the component outline\n    x1 = A/2.0 - B/2.0\n    x2 = x1 + B\n    y2 = row_pitch + 7\n    y1 = y2 - 9.5\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #draw fab outline measured from 3D model on JST's site\n    # \"wings\" by pins are 1.0mm wide\n    side = [\n    {'x': x1,'y': y1},\n    {'x': x1+1,'y': y1},\n    {'x': x1+1,'y': y1+3},\n    {'x': x2-1,'y': y1+3},\n    {'x': x2-1,'y': y1},\n    {'x': x2,'y': y1},\n    {'x': x2,'y': y2},\n    {'x': x1,'y': y2},\n    {'x': x1,'y': y1}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=side, width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    if y1 < -size[1]/2.0:\n        cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    else:\n        cy1 = roundToBase(-size[1]/2.0-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #offset off\n    off = configuration['silk_fab_offset']\n\n    x1 -= off\n    y1 -= off\n    x2 += off\n    y2 += off\n\n    #outline\n    # from above, recall \"wings\" by pins are 1.0mm wide\n    side = [\n    {'x': x1+1+2*off,'y': y1+3},\n    {'x': x1+1+2*off,'y': y1},\n    {'x': x1,'y': y1},\n    {'x': x1,'y': y2},\n    {'x': A/2.0,'y': y2},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=side, width=configuration['silk_line_width'], layer='F.SilkS'))\n    kicad_mod.append(PolygoneLine(polygone=side, x_mirror=A/2.0, width=configuration['silk_line_width'], layer='F.SilkS'))\n\n    D = 0.3\n    L = 2.5\n\n    #add p1 marker\n    marker = [\n        {'x': pitch/2.0 , 'y': y1-D+0.25},\n        {'x': pitch/2.0 , 'y': y1-D},\n        {'x': x1-D,'y': y1-D},\n        {'x': x1-D,'y': y1-D+L}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=marker,width=configuration['silk_line_width'],layer='F.SilkS'))\n    sl = 0.5\n    marker =[\n        {'x': body_edge['left']+1 , 'y': -sl},\n        {'x': body_edge['left']+1+(2*sl)/sqrt(2) , 'y': 0},\n        {'x': body_edge['left']+1 , 'y': sl}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=marker,layer='F.Fab',width=configuration['fab_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pin_range:\n        generate_one_footprint(pincount, configuration)"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_PHD_vertical.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\nfrom math import sqrt\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"PHD\"\nmanufacturer = 'JST'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/ePHD.pdf'\n\npitch = 2.0\n\npin_range=range(4,18) #number of pins in each row\nrow_pitch = 2.0\ndrill = 0.75 # 0.7 +0.1/-0 -> 0.75+/-0.05\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n#FP name strings\npart_base = \"B{n}B-PHDSS\" #JST part number format string\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_base.format(n=pins*number_of_rows) #JST part number format string\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n    A = (pins - 1) * pitch\n    B = A + 3.9\n\n    #draw the component outline\n    x1 = A/2.0 - B/2.0\n    x2 = x1 + B\n    y2 = 2 + 1.5\n    y1 = y2 - 5\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #wall thickness\n    t_short = 0.75 #short side (fixed at 5mm)\n    t_long = 0.4 #long side (A/B dimension)\n    \n    #draw simple outline on F.Fab layer\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],layer='F.Fab',width=configuration['fab_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #draw silk polarity lines\n    kicad_mod.append(RectLine(start=[x1+t_short,y1+t_long],end=[x2-t_short,y2-t_long],layer='F.SilkS',width=configuration['silk_line_width']))\n    \n    #offset off\n    off = configuration['silk_fab_offset']\n\n    #draw silk keying/polarity marks measured from 3D model on JST's site\n    # from bottom (pin 2 row) of connector, notches are 1.6mm up and 0.8mm wide\n    kicad_mod.append(Line(start=[x1-off,y2-2.4],end=[x1+t_short,y2-2.4],layer='F.SilkS',width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[x2+off,y2-2.4],end=[x2-t_short,y2-2.4],layer='F.SilkS',width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[x1-off,y2-1.6],end=[x1+t_short,y2-1.6],layer='F.SilkS',width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[x2+off,y2-1.6],end=[x2-t_short,y2-1.6],layer='F.SilkS',width=configuration['silk_line_width']))\n    # from sides, inner edge of notches are 3.42mm inside and 0.94mm wide at the top (pin 1 row) and 1.50mm wide at the bottom (pin 2 row)\n    kicad_mod.append(Line(start=[x1+3.42,y1-off],end=[x1+3.42,y1+t_long],layer='F.SilkS',width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[x1+2.48,y1-off],end=[x1+2.48,y1+t_long],layer='F.SilkS',width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[x2-3.42,y1-off],end=[x2-3.42,y1+t_long],layer='F.SilkS',width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[x2-2.48,y1-off],end=[x2-2.48,y1+t_long],layer='F.SilkS',width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[x1+3.42,y2+off],end=[x1+3.42,y2-t_long],layer='F.SilkS',width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[x1+1.92,y2+off],end=[x1+1.92,y2-t_long],layer='F.SilkS',width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[x2-3.42,y2+off],end=[x2-3.42,y2-t_long],layer='F.SilkS',width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[x2-1.92,y2+off],end=[x2-1.92,y2-t_long],layer='F.SilkS',width=configuration['silk_line_width']))\n\n    x1 -= off\n    y1 -= off\n    x2 += off\n    y2 += off\n\n    #draw silk outline\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],width=configuration['silk_line_width'],layer='F.SilkS'))\n\n    #add p1 marker\n    px = x1 - 0.2\n    m = 0.3\n\n    marker = [\n    {'x': px,'y': 0},\n    {'x': px-2*m,'y': m},\n    {'x': px-2*m,'y': -m},\n    {'x': px,'y': 0}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=marker,width=configuration['silk_line_width'],layer='F.SilkS'))\n    sl = 0.5\n    marker =[\n        {'x': body_edge['left'], 'y': sl},\n        {'x': body_edge['left'] + (2*sl)/sqrt(2) , 'y': 0},\n        {'x': body_edge['left'] , 'y': -sl}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=marker,layer='F.Fab',width=configuration['fab_line_width']))\n\n    #generate the pads (row 1)\n\n    size = [pitch - pad_to_pad_clearance, row_pitch - pad_to_pad_clearance]\n    if size[0] - drill < 2*min_annular_ring:\n        size[0] = drill + 2*min_annular_ring\n    if size[0] - drill > 2*pad_copper_y_solder_length:\n        size[0] = drill + 2*pad_copper_y_solder_length\n\n    if size[1] - drill < 2*min_annular_ring:\n        size[1] = drill + 2*min_annular_ring\n    if size[1] - drill > 2*pad_copper_y_solder_length:\n        size[1] = drill + 2*pad_copper_y_solder_length\n\n    if size[0] == size[1]:\n        pad_shape = Pad.SHAPE_CIRCLE\n    else:\n        pad_shape = Pad.SHAPE_OVAL\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            pincount=pins, x_spacing=pitch,\n            type=Pad.TYPE_THT, shape=pad_shape,\n            start=[0, row_idx*row_pitch], initial=row_idx+1, increment=2,\n            size=size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pin_range:\n        generate_one_footprint(pincount, configuration)"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_PUD_tht_side.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\nfrom math import sqrt\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"PUD\"\nmanufacturer = 'JST'\norientation = 'H'\nnumber_of_rows = 2\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/ePUD.pdf'\n\npitch = 2.0\nrow_pitch = 2\ndrill = 0.75 # 0.7 +0.1/-0 -> 0.75+/-0.05\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\nmh_drill = 1.65\nmh_y = row_pitch + 7.7\n\npin_range = range(4,21) #number of pins in each row\n\n#FP name strings\npart_base = \"S{n:02}B-PUDSS-1\" #JST part number format string\n\n#FP description and tags\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_base.format(n=pins*number_of_rows) #JST part number format string\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n    A = (pins - 1) * pitch\n    B = A + 4\n\n    #generate the pads (row 1)\n    size = [pitch - pad_to_pad_clearance, row_pitch - pad_to_pad_clearance]\n    if size[0] - drill < 2*min_annular_ring:\n        size[0] = drill + 2*min_annular_ring\n    if size[0] - drill > 2*pad_copper_y_solder_length:\n        size[0] = drill + 2*pad_copper_y_solder_length\n\n    if size[1] - drill < 2*min_annular_ring:\n        size[1] = drill + 2*min_annular_ring\n    if size[1] - drill > 2*pad_copper_y_solder_length:\n        size[1] = drill + 2*pad_copper_y_solder_length\n\n    if size[0] == size[1]:\n        pad_shape = Pad.SHAPE_CIRCLE\n    else:\n        pad_shape = Pad.SHAPE_OVAL\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            pincount=pins, x_spacing=pitch,\n            type=Pad.TYPE_THT, shape=pad_shape,\n            start=[0, row_idx*row_pitch], initial=row_idx+1, increment=2,\n            size=size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    #draw the component outline\n    x1 = A/2 - B/2\n    x2 = x1 + B\n    y2 = row_pitch + 7.7 + 2.4\n    y1 = y2 - 12.7\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #draw simple outline on F.Fab layer\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],layer='F.Fab',width=configuration['fab_line_width']))\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    if y1 < -size[1]/2:\n        cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    else:\n        cy1 = roundToBase(-size[1]/2-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #offset off\n    off = configuration['silk_fab_offset']\n\n    x1 -= off\n    y1 -= off\n    x2 += off\n    y2 += off\n\n    #outline\n    side = [\n    {'x': -1,'y': y1},\n    {'x': x1,'y': y1},\n    {'x': x1,'y': y2},\n    {'x': A/2,'y': y2},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=side, width=configuration['silk_line_width'], layer='F.SilkS'))\n    kicad_mod.append(PolygoneLine(polygone=side, x_mirror=A/2, width=configuration['silk_line_width'], layer='F.SilkS'))\n\n    #add mounting holes\n    m1 = Pad(at=[-0.9,mh_y],layers=Pad.LAYERS_NPTH,shape=Pad.SHAPE_CIRCLE,type=Pad.TYPE_NPTH,size=mh_drill, drill=mh_drill)\n    m2 = Pad(at=[A+0.9,mh_y],layers=Pad.LAYERS_NPTH,shape=Pad.SHAPE_CIRCLE,type=Pad.TYPE_NPTH,size=mh_drill, drill=mh_drill)\n\n    kicad_mod.append(m1)\n    kicad_mod.append(m2)\n\n    D = 0.3\n    L = 2.5\n\n    #add p1 marker\n    marker = [\n        {'x': pitch/2 , 'y': y1-D+0.25},\n        {'x': pitch/2 , 'y': y1-D},\n        {'x': x1-D,'y': y1-D},\n        {'x': x1-D,'y': y1-D+L}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=marker,width=configuration['silk_line_width'],layer='F.SilkS'))\n    sl = 1\n    marker =[\n        {'x': sl/2 , 'y': body_edge['top']},\n        {'x': 0 , 'y': body_edge['top']+sl/sqrt(2)},\n        {'x': -sl/2 , 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=marker,layer='F.Fab',width=configuration['fab_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pin_range:\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_PUD_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\nfrom math import sqrt\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"PUD\"\nmanufacturer = 'JST'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/ePUD.pdf'\n\npitch = 2.0\n\npin_range=range(4,21) #number of pins in each row\nrow_pitch = 2\ndrill = 0.75 # 0.7 +0.1/-0 -> 0.75+/-0.05\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\nmh_drill = 1.35\nmh_y = -3.4\n#FP name strings\npart_base = \"B{n:02}B-PUDSS\" #JST part number format string\n\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_base.format(n=pins*number_of_rows) #JST part number format string\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n    A = (pins - 1) * pitch\n    B = A + 4\n\n    #draw the component outline\n    x1 = A/2 - B/2\n    x2 = x1 + B\n    y2 = 2 + 2.4\n    y1 = y2 - 8.3\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #draw simple outline on F.Fab layer\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],layer='F.Fab',width=configuration['fab_line_width']))\n\n    #wall thickness t\n    t = 0.75\n\n    #draw inside tab\n    T = A/2 + 0.5\n    kicad_mod.append(RectLine(start=[A/2-T/2,y1+t],end=[A/2+T/2,y1+2*t],width=configuration['silk_line_width'],layer='F.SilkS')) #,layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #offset off\n    off = configuration['silk_fab_offset']\n\n    #outline\n    side = [\n    {'x': A/2-T/2-t,'y': y1-off},\n    {'x': A/2-T/2-t,'y': y1 + 2 * t},\n    {'x': A/2-T/2-2*t,'y': y1 + 2 * t},\n    {'x': A/2-T/2-2*t,'y': y1 + t},\n    {'x': x1 + t,'y': y1 + t},\n    {'x': x1 + t,'y': y2 - t},\n    {'x': A/2,'y': y2 - t},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=side,width=configuration['silk_line_width'],layer='F.SilkS')) #,  layer='F.Fab'))\n    kicad_mod.append(PolygoneLine(polygone=side,x_mirror=A/2,width=configuration['silk_line_width'],layer='F.SilkS'))# ,layer='F.Fab'))\n\n\n    x1 -= off\n    y1 -= off\n    x2 += off\n    y2 += off\n\n    #draw outline\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],width=configuration['silk_line_width'],layer='F.SilkS'))\n\n    #add p1 marker\n    px = x1 - 0.2\n    m = 0.3\n\n    marker = [\n    {'x': px,'y': 0},\n    {'x': px-2*m,'y': m},\n    {'x': px-2*m,'y': -m},\n    {'x': px,'y': 0}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=marker,width=configuration['silk_line_width'],layer='F.SilkS'))\n    sl = 1\n    marker =[\n        {'x': body_edge['left'], 'y': sl/2},\n        {'x': body_edge['left']+sl/sqrt(2) , 'y': 0},\n        {'x': body_edge['left'] , 'y': -sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=marker,layer='F.Fab',width=configuration['fab_line_width']))\n\n    #generate the pads (row 1)\n\n    size = [pitch - pad_to_pad_clearance, row_pitch - pad_to_pad_clearance]\n    if size[0] - drill < 2*min_annular_ring:\n        size[0] = drill + 2*min_annular_ring\n    if size[0] - drill > 2*pad_copper_y_solder_length:\n        size[0] = drill + 2*pad_copper_y_solder_length\n\n    if size[1] - drill < 2*min_annular_ring:\n        size[1] = drill + 2*min_annular_ring\n    if size[1] - drill > 2*pad_copper_y_solder_length:\n        size[1] = drill + 2*pad_copper_y_solder_length\n\n    if size[0] == size[1]:\n        pad_shape = Pad.SHAPE_CIRCLE\n    else:\n        pad_shape = Pad.SHAPE_OVAL\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            pincount=pins, x_spacing=pitch,\n            type=Pad.TYPE_THT, shape=pad_shape,\n            start=[0, row_idx*row_pitch], initial=row_idx+1, increment=2,\n            size=size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pin_range:\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_VH_tht_side-stabilizer.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"VH\"\nmanufacturer = 'JST'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eVH.pdf'\n\npitch = 3.96\n\npin_range = range(2, 8) #number of pins in each row\n\ndrill = 1.7 # 1.65 +0.1/-0.0 -> 1.7+/-0.05\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n#FP name strings\npart_base = \"S{n}P-VH\" #JST part number format string\n\n#FP description and tags\n# DISCLAIMER: This generator uses many magic numbers for the silk screen details. These might break if some parameters are changed.\n\ndef generate_one_footprint(pins, configuration):\n    silk_pad_clearance = configuration['silk_pad_clearance']+configuration['silk_line_width']/2\n    mpn = part_base.format(n=pins)\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n    A = (pins - 1) * pitch\n    B = A + 3.9\n\n    #coordinate locations\n    # y1 x1 x3                x4 x2\n    # y2 | |                   | |\n    # y3 | |1||2||3||4||5||6||7| |\n    # y4 |_|                  |__|\n    #      |                  |\n    # y5   |__________________|\n    # y6   || || || || || || ||\n\n    #generate pads\n    pad_size = [pitch - pad_to_pad_clearance, drill + 2*pad_copper_y_solder_length]\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n\n    if pad_size[0] - drill > 2*pad_copper_y_solder_length:\n        pad_size[0] = drill + 2*pad_copper_y_solder_length\n\n    shape=Pad.SHAPE_OVAL\n    if pad_size[0] == pad_size[1]:\n        shape=Pad.SHAPE_CIRCLE\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(\n        pincount=pins, x_spacing=pitch,\n        type=Pad.TYPE_THT, shape=shape,\n        size=pad_size, drill=drill,\n        layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    #draw the component outline\n    x1 = A/2 - B/2\n    x2 = x1 + B\n    x3 = -0.9\n    x4 = pitch * (pins - 1) + 0.9\n    y6 = 13.4\n    y4 = y6 - 7.7\n    y1 = y4 - 7.7\n    y2 = y1 + 2\n    y3 = y1 + 4.5\n    y5 = y3 + 9.4\n\n    body_edge={'left':x1, 'right':x2, 'top':y4, 'bottom':y5}\n\n    #draw shroud outline on F.Fab layer\n    kicad_mod.append(RectLine(start=[x3,y3],end=[x4,y5], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x4-0.2,'y':y3},{'x':x4-0.2,'y':y1},{'x':x2,'y':y1},{'x':x2,'y':y4},{'x':x4,'y':y4}], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x3,'y':y4},{'x':x1,'y':y4},{'x':x1,'y':y1},{'x':x3+0.2,'y':y1},{'x':x3+0.2,'y':y3}], layer='F.Fab', width=configuration['fab_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y6+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #draw pin outlines and plastic between pins on F.Fab (pin width is 1.4mm, so 0.7mm is half the pin width)\n    for pin in range(pins):\n        kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch - 0.7,'y':y5},{'x':pin * pitch - 0.7,'y':y6},{'x':pin * pitch + 0.7,'y':y6},{'x':pin * pitch + 0.7,'y':y5}], layer='F.Fab', width=configuration['fab_line_width']))\n        if pin < (pins - 1):\n            kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch + 1.38,'y':y3},{'x':pin * pitch + 1.38,'y':y2},{'x':pin * pitch + 2.58,'y':y2},{'x':pin * pitch + 2.58,'y':y3}], layer='F.Fab', width=configuration['fab_line_width']))\n\n    #draw pin1 mark on F.Fab\n    kicad_mod.append(PolygoneLine(polygone=[{'x':-0.8,'y':y3},{'x':0,'y':y3+0.8},{'x':0.8,'y':y3}], layer='F.Fab', width=configuration['fab_line_width']))\n\n    #draw silk outlines\n    off = configuration['silk_fab_offset']\n    x1 -= off\n    y1 -= off\n    x2 += off\n    y2 -= off\n    x3 -= off\n    y3 -= off\n    x4 += off\n    y4 += off\n    y5 += off\n    y6 += off\n\n    p1s_x = pad_size[0]/2 + silk_pad_clearance\n    p1s_y = pad_size[1]/2 + silk_pad_clearance\n\n    #silk around shroud; silk around stabilizers; silk long shroud between pin and shroud for first and last pins\n    #note that half of pin width is 0.7mm, so adding 0.12mm silk offset gives 0.82mm about pin center; 0.44 is double silk offset in caeses where 'off' is in the wrong direction\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x3,'y':y4},{'x':x3,'y':y5},{'x':-0.82,'y':y5}], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x4-0.44,'y':-1.6},{'x':x4-0.44,'y':y1},{'x':x2,'y':y1},{'x':x2,'y':y4},{'x':x4,'y':y4}], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x4-0.44,'y':y3},{'x':x4-0.44,'y':1.6}], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x3,'y':y4},{'x':x1,'y':y4},{'x':x1,'y':y1},{'x':x3+0.44,'y':y1},{'x':x3+0.44,'y':-p1s_y}], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x3+0.44,'y':1.7},{'x':x3+0.44,'y':y3}], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':(pins - 1) * pitch + 0.82,'y':y5},{'x':x4,'y':y5},{'x':x4,'y':y4}], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':-0.58,'y':y3},{'x':1.26,'y':y3}], layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch - 1.26,'y':y3},{'x':pin * pitch + 0.58,'y':y3}], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #per-pin silk\n    #pin silk\n    for pin in range(pins):\n        kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch - 0.82,'y':y5},{'x':pin * pitch - 0.82,'y':y6},{'x':pin * pitch + 0.82,'y':y6},{'x':pin * pitch + 0.82,'y':y5}], layer='F.SilkS', width=configuration['silk_line_width']))\n        #silk around plastic between pins 1 and 2 (since pin 1 is rectangular, it seends to be handled a bit differently to meet ~0.2mm pin-silk clearance)\n        if pin == 0:\n            kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch + 1.26,'y':y3},{'x':pin * pitch + 1.26,'y':1.7}], layer='F.SilkS', width=configuration['silk_line_width']))\n            kicad_mod.append(PolygoneLine(polygone=[\n                    {'x':pin * pitch + pad_size[0]/2 + silk_pad_clearance,'y':y2},\n                    {'x':(pin+1) * pitch - pad_size[0]/2 - silk_pad_clearance,'y':y2}],\n                layer='F.SilkS', width=configuration['silk_line_width']))\n            kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch + 2.7,'y':1},{'x':pin * pitch + 2.7,'y':y3}], layer='F.SilkS', width=configuration['silk_line_width']))\n        #silk around plastic between other pins; silk along shroud between pin and shroud for other pins\n        if (pin > 0) and (pin < (pins - 1)):\n            kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch + 1.26,'y':y3},{'x':pin * pitch + 1.26,'y':1}], layer='F.SilkS', width=configuration['silk_line_width']))\n            kicad_mod.append(PolygoneLine(polygone=[\n                    {'x':pin * pitch + pad_size[0]/2 + silk_pad_clearance,'y':y2},\n                    {'x':(pin+1) * pitch - pad_size[0]/2 - silk_pad_clearance,'y':y2}],\n                layer='F.SilkS', width=configuration['silk_line_width']))\n            kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch + 2.7,'y':1},{'x':pin * pitch + 2.7,'y':y3}], layer='F.SilkS', width=configuration['silk_line_width']))\n            kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch - 1.26,'y':y3},{'x':pin * pitch + 1.26,'y':y3}], layer='F.SilkS', width=configuration['silk_line_width']))\n        #silk between pins at locking end of shroud\n        if (pin > 0) and (pin < pins):\n            kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch - 3.14,'y':y5},{'x':pin * pitch - 0.82,'y':y5}],layer='F.SilkS'))\n\n    #add pin1 marker on F.FilkS (magic numbers intended to hit ~0.3mm copper-silk clearance)\n\n    kicad_mod.append(PolygoneLine(polygone=[{'x':0,'y':-p1s_y},{'x':-p1s_x,'y':-p1s_y},{'x':-p1s_x,'y':0}], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pin_range:\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_VH_tht_side.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"VH\"\nmanufacturer = 'JST'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eVH.pdf'\n\npitch = 3.96\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\ndrill = 1.7 # 1.65 +0.1/-0.0 -> 1.7 +/-0.05\n\npin_range = range(2, 11) #number of pins in each row\n\n#FP name strings\npart_base = \"B{n}PS-VH\" #JST part number format string\n\n\n#FP description and tags\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_base.format(n=pins)\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n    A = (pins - 1) * pitch\n    B = A + 3.9\n\n    #coordinate locations\n    #    x1 x3                x4 x2\n    #       1  2  3  4  5  6  7\n    # y1  _______________________\n    # y2 |_|                  |__|\n    #      |                  |\n    # y3   |__________________|\n    # y4   || || || || || || ||\n\n    #generate pads\n    pad_size = [pitch - pad_to_pad_clearance, drill + 2*pad_copper_y_solder_length]\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n    if pad_size[0] - drill > 2*pad_copper_y_solder_length:\n        pad_size[0] = drill + 2*pad_copper_y_solder_length\n\n    shape=Pad.SHAPE_OVAL\n    if pad_size[1] == pad_size[0]:\n        shape=Pad.SHAPE_CIRCLE\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(\n        pincount=pins, x_spacing=pitch,\n        type=Pad.TYPE_THT, shape=shape, size=pad_size,\n        drill=drill, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    #draw the component outline\n    x1 = A/2 - B/2\n    x2 = x1 + B\n    x3 = -0.9\n    x4 = pitch * (pins - 1) + 0.9\n    y1 = 14.9 - 7.7 - 3.2\n    y2 = y1 + 3.2\n    y3 = y1 + 9.4\n    y4 = 14.9\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y4}\n\n    #draw shroud outline on F.Fab layer\n    kicad_mod.append(RectLine(start=[x3,y1],end=[x4,y3],layer='F.Fab',width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x4,'y':y1},{'x':x2,'y':y1},{'x':x2,'y':y2},{'x':x4,'y':y2}],\n        layer='F.Fab',width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x3,'y':y2},{'x':x1,'y':y2},{'x':x1,'y':y1},{'x':x3,'y':y1}],\n        layer='F.Fab',width=configuration['fab_line_width']))\n\n    #draw pin1 mark on F.Fab\n    kicad_mod.append(PolygoneLine(polygone=[{'x':-0.8,'y':y1},{'x':0,'y':y1+0.8},{'x':0.8,'y':y1}],\n        layer='F.Fab',width=configuration['fab_line_width']))\n\n    #draw pin outlines on F.Fab (pin width is 1.4mm, so 0.7mm is half the pin width)\n    for pin in range(pins):\n        kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch - 0.7,'y':y1},\n                                                {'x':pin * pitch - 0.7,'y':0},\n                                                {'x':pin * pitch + 0.7,'y':0},\n                                                {'x':pin * pitch + 0.7,'y':y1}],\n                                            layer='F.Fab',width=configuration['fab_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch - 0.7,'y':y3},\n                                                {'x':pin * pitch - 0.7,'y':y4},\n                                                {'x':pin * pitch + 0.7,'y':y4},\n                                                {'x':pin * pitch + 0.7,'y':y3}],\n                                            layer='F.Fab',width=configuration['fab_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(-pad_size[1]/2-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y4+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #draw silk outlines\n    off = configuration['silk_fab_offset']\n    x1 -= off\n    y1 -= off\n    x2 += off\n    y2 += off\n    x3 -= off\n    y3 += off\n    x4 += off\n    y4 += off\n\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1,'y':y1},\n                                            {'x':x2,'y':y1},\n                                            {'x':x2,'y':y2},\n                                            {'x':x4,'y':y2},\n                                            {'x':x4,'y':y3},\n                                            {'x':x3,'y':y3},\n                                            {'x':x3,'y':y2},\n                                            {'x':x1,'y':y2},\n                                            {'x':x1,'y':y1}],\n                                        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #pin silk (half of pin width is 0.7mm, so adding 0.12mm silk offset gives 0.82mm about pin center)\n    for pin in range(pins):\n        kicad_mod.append(PolygoneLine(polygone=[{'x':pin * pitch - 0.82,'y':y3},\n                                                {'x':pin * pitch - 0.82,'y':y4},\n                                                {'x':pin * pitch + 0.82,'y':y4},\n                                                {'x':pin * pitch + 0.82,'y':y3}],\n                                            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add pin1 marker on F.FilkS\n    p1_y1 = -pad_size[1]/2 - configuration['silk_pad_clearance'] - configuration['silk_line_width']/2\n    p1_x1 = -pad_size[0]/2 - configuration['silk_pad_clearance'] - configuration['silk_line_width']/2\n\n    kicad_mod.append(PolygoneLine(polygone=[{'x':0,'y':p1_y1},{'x':p1_x1,'y':p1_y1},{'x':p1_x1,'y':0}],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pin_range:\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_VH_tht_top-shrouded.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"VH\"\nmanufacturer = 'JST'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eVH.pdf'\n\npitch = 3.96\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\ndrill = 1.7 # 1.65 +0.1/-0.0 -> 1.7+/-0.05\nmh_drill = 1.45\nmh_at = [-1.5, -3.4]\n\npin_range = range(2, 11) #number of pins in each row\n\n#FP name strings\npart_base = \"B{n:d}P-VH-FB-B\" #JST part number format string\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_base.format(n=pins)\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s}, shrouded ({:s}),  generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate dimensions\n    A = (pins - 1) * pitch\n    B = A + 5.84\n\n\n\n    #coordinate locations (latch is not drawn but is 2.3mm above y5 and width varies)\n    #    x1 x5 x3           x4 x6 x2\n    # y1 ______             ______\n    # y3 | O  |_____________|    |\n    # y5 |  ___________________  |\n    #    |  | 1 2 3 4 5 6 7 8  | |\n    # y4 |  |__________________| |\n    # y2 |_______________________|\n\n    #draw the component outline\n    x1 = A/2 - B/2\n    x2 = x1 + B\n    x3 = x1 + 2.9\n    x4 = x2 - 2.9\n    x5 = -2\n    x6 = pitch * (pins - 1) + 2\n    y2 = 5.2\n    y1 = y2 - 9.7\n    y3 = y1 + 1.2\n    y4 = 4.3\n    y5 = y4 - 6.4\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #draw outline on F.Fab layer\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1,'y':y2},\n                                            {'x':x1,'y':y1},\n                                            {'x':x3,'y':y1},\n                                            {'x':x3,'y':y3},\n                                            {'x':x4,'y':y3},\n                                            {'x':x4,'y':y1},\n                                            {'x':x2,'y':y1},\n                                            {'x':x2,'y':y2},\n                                            {'x':x1,'y':y2}],\n                                        layer='F.Fab',width=configuration['fab_line_width']))\n\n    #draw rectangle on F.Fab for shroud walls\n    kicad_mod.append(RectLine(start=[x5,y4],end=[x6,y5],layer='F.Fab',width=configuration['fab_line_width']))\n\n\t#draw pin1 mark on F.Fab\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1,'y':-1},{'x':(x1+1),'y':0}],layer='F.Fab',width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1,'y':1},{'x':(x1+1),'y':0}],layer='F.Fab',width=configuration['fab_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #draw silk outline\n    off = configuration['silk_fab_offset']\n    x1 -= off\n    y1 -= off\n    x2 += off\n    y2 += off\n    x3 += off\n    y3 -= off\n    x4 -= off\n\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1,'y':y2},\n                                            {'x':x1,'y':y1},\n                                            {'x':x3,'y':y1},\n                                            {'x':x3,'y':y3},\n                                            {'x':x4,'y':y3},\n                                            {'x':x4,'y':y1},\n                                            {'x':x2,'y':y1},\n                                            {'x':x2,'y':y2},\n                                            {'x':x1,'y':y2}],\n                                        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add pin1 mark on silk\n    px = x1 - 0.2\n    m = 0.3\n\n    marker = [{'x': px,'y': 0},{'x': px-2*m,'y': m},{'x': px-2*m,'y': -m},{'x': px,'y': 0}]\n\n    kicad_mod.append(PolygoneLine(polygone=marker,layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    #generate tht pads (1.65mm drill with 2.35x3mm oval pads)\n    pad_size = [pitch - pad_to_pad_clearance, drill + 2*pad_copper_y_solder_length]\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n    if pad_size[0] - drill > 2*pad_copper_y_solder_length:\n        pad_size[0] = drill + 2*pad_copper_y_solder_length\n\n    shape=Pad.SHAPE_OVAL\n    if pad_size[1] == pad_size[0]:\n        shape=Pad.SHAPE_CIRCLE\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(\n        pincount=pins, x_spacing=pitch,\n        type=Pad.TYPE_THT, shape=shape,\n        size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    #generate mounting post\n    post = Pad(at=mh_at, type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=mh_drill, drill=mh_drill, layers=Pad.LAYERS_NPTH)\n    kicad_mod.append(post)\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position=2.5)\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pin_range:\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_eh_tht_side.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\nfrom math import sqrt\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"EH\"\nmanufacturer = 'JST'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eEH.pdf'\n\npitch = 2.50\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\ndef generate_one_footprint(pincount, configuration):\n    mpn = \"S{pincount}B-EH\".format(pincount=pincount) #JST part number format string\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    if pincount == 2:\n        drill = 1.0\n    else:\n        drill = 0.95\n\n    pad_size = [pitch - pad_to_pad_clearance, drill + 2*pad_copper_y_solder_length]\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n\n    # create pads\n    # kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n    #                     at=[0, 0], size=pad_size,\n    #                     drill=drill, layers=Pad.LAYERS_THT))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[0, 0],\n        x_spacing=pitch, pincount=pincount,\n        size=pad_size, drill=drill,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    A = (pincount - 1) * pitch\n    B = A + 5.0\n\n    x1 = -2.5\n    y1 = -6.7\n    x2 = x1 + B\n    y21 = y1 + 6\n    y2 = 1.5\n    x11 = x1+1\n    x21 = x2-1\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #draw the main outline around the footprint\n    # kicad_mod.append(RectLine(start={'x':x1,'y':y1}, end={'x':x2,'y':y2}, layer='F.Fab', width=configuration['fab_line_width']))\n    fab_outline=[\n        {'x': x11, 'y': y21},\n        {'x': x11, 'y': y2},\n        {'x': x1, 'y': y2},\n        {'x': x1, 'y': y1},\n        {'x': x2, 'y': y1},\n        {'x': x2, 'y': y2},\n        {'x': x21, 'y': y2},\n        {'x': x21, 'y': y21},\n        {'x': x11, 'y': y21}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=fab_outline,\n        layer='F.Fab', width=configuration['fab_line_width']))\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ########################### SilkS #################################\n\n    #line offset\n    off = configuration['silk_fab_offset']\n\n    x1 -= off\n    y1 -= off\n\n    x2 += off\n    y2 += off\n\n\n    T = 1 + 2*configuration['silk_fab_offset']\n\n    y3 = y21 + off\n\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1+T,'y':y3},\n                               {'x':x1+T,'y':y2},\n                               {'x':x1,'y':y2},\n                               {'x':x1,'y':y1},\n                               {'x':x2,'y':y1},\n                               {'x':x2,'y':y2},\n                               {'x':x2-T,'y':y2},\n                               {'x':x2-T,'y':y3}], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1,'y':y1+T},\n                               {'x':x1+T,'y':y1+T},\n                               {'x':x1+T,'y':y3},\n                               {'x':x1,'y':y3}], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x2,'y':y1+T},\n                           {'x':x2-T,'y':y1+T},\n                           {'x':x2-T,'y':y3},\n                           {'x':x2,'y':y3}], layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n\n    #add pictures of pins\n    #pin-width w\n    #pin-length l\n    w = 0.32\n    l = 3.5\n\n    py = y3-1\n\n    kicad_mod.append(Line(start={'x':x1+T,'y':py},end={'x':x2-T,'y':py}, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    # kicad_mod.append(Line(start={'x':x1+T,'y':py+1},end={'x':x2-T,'y':py+1}, layer='F.SilkS', width=configuration['silk_line_width']))\n    pcs_x = pad_size[0]/2 + configuration['silk_pad_clearance'] + configuration['silk_line_width']\n    for p in range(pincount):\n\n        px = p * pitch\n\n        kicad_mod.append(PolygoneLine(polygone=[{'x': px,'y': py},\n                                   {'x': px-w,'y': py},\n                                   {'x': px-w,'y': py-l+0.25*w},\n                                   {'x': px,'y': py-l},\n                                   {'x': px+w,'y': py-l+0.25*w},\n                                   {'x': px+w,'y': py},\n                                   {'x': px,'y': py}], layer='F.SilkS', width=configuration['silk_line_width']))\n\n        if p < pincount-1:\n            kicad_mod.append(Line(start=[px + pcs_x, y3], end=[px + pitch - pcs_x, y3],\n                layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ######################### Pin 1 marker ##############################\n\n    xm = 0\n    ym = 1.5\n\n    m = 0.3\n\n    pin = [{'x':xm,'y':ym},\n           {'x':xm - m,'y':ym + 2 * m},\n           {'x':xm + m,'y':ym + 2 * m},\n           {'x':xm,'y':ym}]\n    kicad_mod.append(PolygoneLine(polygone=pin, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    sl = 1\n    pin = [\n        {'x':xm-sl/2,'y':y21},\n        {'x':xm,'y':y21-sl/sqrt(2)},\n        {'x':xm+sl/2,'y':y21}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,layer='F.Fab', width=configuration['fab_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in range(2, 16):\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_eh_tht_top.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"EH\"\nmanufacturer = 'JST'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eEH.pdf'\n\npitch = 2.50\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\ndef generate_one_footprint(pincount, configuration):\n    mpn = \"B{pincount}B-EH-A\".format(pincount=pincount)\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n    A = (pincount - 1) * pitch\n    B = A + 5.0\n\n    # set general values\n\n\n    if pincount == 2:\n        drill = 1.0\n    else:\n        drill = 0.95\n\n    pad_size = [pitch - pad_to_pad_clearance, drill + 2*pad_copper_y_solder_length]\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n\n    # create pads\n    # kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n    #                     at=[0, 0], size=pad_size,\n    #                     drill=drill, layers=Pad.LAYERS_THT))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[0, 0],\n        x_spacing=pitch, pincount=pincount,\n        size=pad_size, drill=drill,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n\n\n    x1 = -2.5\n    y1 = -1.6\n    x2 = x1 + B\n    y2 = y1 + 3.8\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #draw the main outline on F.Fab layer\n    kicad_mod.append(RectLine(start={'x':x1,'y':y1}, end={'x':x2,'y':y2}, layer='F.Fab', width=configuration['fab_line_width']))\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #line offset\n    off = configuration['silk_fab_offset']\n\n    x1 -= off\n    y1 -= off\n\n    x2 += off\n    y2 += off\n\n    #draw the main outline around the footprint\n    kicad_mod.append(RectLine(start={'x':x1,'y':y1},end={'x':x2,'y':y2}, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    T = 0.5\n\n    #add top line\n    kicad_mod.append(PolygoneLine(polygone=[{'x': x1,'y': 0},\n                               {'x': x1 + T,'y': 0},\n                               {'x': x1 + T,'y': y1 + T},\n                               {'x': x2 - T,'y': y1 + T},\n                               {'x': x2 - T,'y': 0},\n                               {'x': x2,'y':0}], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add bottom line (left)\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1,'y':y2-3*T},\n                               {'x':x1+2*T,'y':y2-3*T},\n                               {'x':x1+2*T,'y':y2}], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add bottom line (right)\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x2,'y':y2-3*T},\n                               {'x':x2-2*T,'y':y2-3*T},\n                               {'x':x2-2*T,'y':y2}], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add pin-1 marker\n    D = 0.3\n    L = 2.5\n    pin = [\n        {'x': x1-D,'y': y2+D-L},\n        {'x': x1-D,'y': y2+D},\n        {'x': x1-D+L,'y': y2+D},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin))\n    kicad_mod.append(PolygoneLine(polygone=pin, layer='F.Fab', width=configuration['fab_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in range(2, 16):\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_ph_tht_side.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"PH\"\nmanufacturer = 'JST'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/ePH.pdf'\n\nsilk_pin1_marker_type = 2\nfab_pin1_marker_type = 3\n\n\npitch = 2.00\n#pad_size=[1.2, 1.7]\ndrill_size = 0.75 #Datasheet: 0.7 +0.1/-0.0 => It might be better to assume 0.75 +/-0.05mm\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n# Connector Parameters\nx_min = -1.95\ny_max = 6.25\ny_min = y_max-6-1.6\ny_main_min = y_max - 6\n\nbody_back_protrusion_width=0.7\n\ndef generate_one_footprint(pincount, configuration):\n    silk_x_min = x_min - configuration['silk_fab_offset']\n    silk_y_min = y_min - configuration['silk_fab_offset']\n    silk_y_main_min = y_main_min - configuration['silk_fab_offset']\n    silk_y_max = y_max + configuration['silk_fab_offset']\n\n    x_mid = (pincount-1)*pitch/2.0\n    x_max = (pincount-1)*pitch + 1.95\n    silk_x_max = x_max + configuration['silk_fab_offset']\n\n    pad_size = [pitch - pad_to_pad_clearance, drill_size + 2*pad_copper_y_solder_length]\n    if pad_size[0] - drill_size < 2*min_annular_ring:\n        pad_size[0] = drill_size + 2*min_annular_ring\n\n    # Through-hole type shrouded header, Side entry type\n    mpn = \"S{n}B-PH-K\".format(n=pincount) #JST part number format string\n\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    # create Silkscreen\n    tmp_x1=x_min+body_back_protrusion_width+configuration['silk_fab_offset']\n    tmp_x2=x_max-body_back_protrusion_width-configuration['silk_fab_offset']\n    pad_silk_offset = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    poly_silk_outline= [\n                    {'x':-pad_size[0]/2.0-pad_silk_offset, 'y':silk_y_main_min},\n                    {'x':tmp_x1, 'y':silk_y_main_min},\n                    {'x':tmp_x1, 'y':silk_y_min},\n                    {'x':silk_x_min, 'y':silk_y_min},\n                    {'x':silk_x_min, 'y':silk_y_max},\n                    {'x':silk_x_max, 'y':silk_y_max},\n                    {'x':silk_x_max, 'y':silk_y_min},\n                    {'x':tmp_x2, 'y':silk_y_min},\n                    {'x':tmp_x2, 'y':silk_y_main_min},\n                    {'x':(pincount-1)*pitch+pad_size[0]/2.0+pad_silk_offset, 'y':silk_y_main_min}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_silk_outline, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    if configuration['allow_silk_below_part'] == 'tht' or configuration['allow_silk_below_part'] == 'both':\n        poly_big_cutout=[{'x':0.5, 'y':silk_y_max}\n                                  ,{'x':0.5, 'y':2}\n                                  ,{'x':x_max-2.45, 'y':2}\n                                  ,{'x':x_max-2.45, 'y':silk_y_max}]\n        kicad_mod.append(PolygoneLine(polygone=poly_big_cutout, layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Line(start=[silk_x_min, silk_y_main_min], end=[tmp_x1, silk_y_main_min], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[silk_x_max, silk_y_main_min], end=[tmp_x2, silk_y_main_min], layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(RectLine(start=[-1.3, 2.5], end=[-0.3, 4.1],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(RectLine(start=[(pincount-1)*pitch+1.3, 2.5], end=[(pincount-1)*pitch+0.3, 4.1],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Line(start=[-0.3, 4.1], end=[-0.3, silk_y_max],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[-0.8, 4.1], end=[-0.8, silk_y_max],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ########################### CrtYd ################################\n    part_x_min = x_min\n    part_x_max = x_max\n    part_y_min = y_min\n    part_y_max = y_max\n\n    cx1 = roundToBase(part_x_min-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(part_y_min-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(part_x_max+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(part_y_max+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ########################### Fab Outline ################################\n    tmp_x1=x_min+body_back_protrusion_width\n    tmp_x2=x_max-body_back_protrusion_width\n    poly_fab_outline= [\n                    {'x':tmp_x1, 'y':y_main_min},\n                    {'x':tmp_x1, 'y':y_min},\n                    {'x':x_min, 'y':y_min},\n                    {'x':x_min, 'y':y_max},\n                    {'x':x_max, 'y':y_max},\n                    {'x':x_max, 'y':y_min},\n                    {'x':tmp_x2, 'y':y_min},\n                    {'x':tmp_x2, 'y':y_main_min},\n                    {'x':tmp_x1, 'y':y_main_min}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_fab_outline, layer='F.Fab', width=configuration['fab_line_width']))\n\n    ############################# Pads ##################################\n    # kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n    #                     at=[0, 0], size=pad_size,\n    #                     drill=drill_size, layers=Pad.LAYERS_THT))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[0, 0],\n        x_spacing=pitch, pincount=pincount,\n        size=pad_size, drill=drill_size,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n\n    ########################### Pin 1 marker ################################\n    poly_pin1_marker = [\n        {'x':0, 'y':-1.2},\n        {'x':-0.4, 'y':-1.6},\n        {'x':0.4, 'y':-1.6},\n        {'x':0, 'y':-1.2}\n    ]\n    if silk_pin1_marker_type == 1:\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.SilkS', width=configuration['silk_line_width']))\n    if silk_pin1_marker_type == 2:\n        silk_pin1_marker_t2_x = -pad_size[0]/2.0-pad_silk_offset\n\n        kicad_mod.append(Line(start=[silk_pin1_marker_t2_x, silk_y_main_min],\n            end=[silk_pin1_marker_t2_x, -pad_size[1]/2.0-configuration['silk_pad_clearance']],layer='F.SilkS', width=configuration['silk_line_width']))\n\n    if fab_pin1_marker_type == 1:\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.Fab', width=configuration['fab_line_width']))\n\n    if fab_pin1_marker_type == 2:\n        poly_pin1_marker_type2 = [\n            {'x':-0.75, 'y':y_main_min},\n            {'x':0, 'y':y_main_min+0.75},\n            {'x':0.75, 'y':y_main_min}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker_type2, layer='F.Fab', width=configuration['fab_line_width']))\n\n    if fab_pin1_marker_type == 3:\n        fab_pin1_marker_t3_y = pad_size[1]/2.0\n        poly_pin1_marker_type2 = [\n            {'x':0, 'y':fab_pin1_marker_t3_y},\n            {'x':-0.5, 'y':fab_pin1_marker_t3_y+0.5},\n            {'x':0.5, 'y':fab_pin1_marker_t3_y+0.5},\n            {'x':0, 'y':fab_pin1_marker_t3_y}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker_type2, layer='F.Fab', width=configuration['fab_line_width']))\n\n    ######################### Text Fields ###############################\n    text_center_y = 2.5\n    body_edge={'left':part_x_min, 'right':part_x_max, 'top':part_y_min, 'bottom':part_y_max}\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position=text_center_y)\n\n\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in range(2,17):\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_ph_tht_top.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"PH\"\nmanufacturer = 'JST'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/ePH.pdf'\n\n\nfab_pin1_marker_type = 1\npin1_marker_offset = 0.3\npin1_marker_linelen = 1.25\n\ndrill_size = 0.75 #Datasheet: 0.7 +0.1/-0.0 => It might be better to assume 0.75 +/-0.05mm\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n\n\npitch = 2.00\n\n# Connector Parameters\nx_min = -1.95\ny_min = -1.7\ny_max = y_min + 4.5\n\ndef generate_one_footprint(pincount, configuration):\n    silk_x_min = x_min - configuration['silk_fab_offset']\n    silk_y_min = y_min - configuration['silk_fab_offset']\n    silk_y_max = y_max + configuration['silk_fab_offset']\n\n\n    x_mid = (pincount-1)*pitch/2.0\n    x_max = (pincount-1)*pitch + 1.95\n    silk_x_max = x_max + configuration['silk_fab_offset']\n\n    # Through-hole type shrouded header, Top entry type\n    mpn = \"B{n}B-PH-K\".format(n=pincount) #JST part number format string\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    # create Silkscreen\n    kicad_mod.append(RectLine(start=[silk_x_min,silk_y_min], end=[silk_x_max,silk_y_max],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    silk_inner_left=-1.45\n    silk_inner_right=x_max-0.5\n\n    poly_silk_p1_protrusion=[\n        {'x':-0.3, 'y':silk_y_min},\n        {'x':-0.3, 'y':silk_y_min-0.2},\n        {'x':-0.6, 'y':silk_y_min-0.2},\n        {'x':-0.6, 'y':silk_y_min}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_silk_p1_protrusion, layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[-0.3, silk_y_min-0.1], end=[-0.6, silk_y_min-0.1], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    if configuration['allow_silk_below_part'] == 'tht' or configuration['allow_silk_below_part'] == 'both':\n        poly_silk_inner_outline = [\n            {'x':0.5, 'y':silk_y_min},\n            {'x':0.5, 'y':-1.2},\n            {'x':silk_inner_left, 'y':-1.2},\n            {'x':silk_inner_left, 'y':2.3},\n            {'x':silk_inner_right, 'y':2.3},\n            {'x':silk_inner_right, 'y':-1.2},\n            {'x':x_max-2.45, 'y':-1.2},\n            {'x':x_max-2.45, 'y':silk_y_min}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_silk_inner_outline, layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Line(start=[silk_x_min, -0.5], end=[silk_inner_left, -0.5], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[silk_x_min, 0.8], end=[silk_inner_left, 0.8], layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Line(start=[silk_x_max, -0.5], end=[silk_inner_right, -0.5], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[silk_x_max, 0.8], end=[silk_inner_right, 0.8], layer='F.SilkS', width=configuration['silk_line_width']))\n\n        for i in range(0, pincount-1):\n            middle_x = 1+i*2\n            start_x = middle_x-0.1\n            end_x = middle_x+0.1\n            poly_silk_inner_protrusion=[\n                {'x':start_x, 'y':2.3},\n                {'x':start_x, 'y':1.8},\n                {'x':end_x, 'y':1.8},\n                {'x':end_x, 'y':2.3}\n            ]\n            kicad_mod.append(PolygoneLine(polygone=poly_silk_inner_protrusion, layer='F.SilkS', width=configuration['silk_line_width']))\n            kicad_mod.append(Line(start=[middle_x, 2.3], end=[middle_x, 1.8], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ########################### Pin 1 marker ################################\n    poly_pin1_marker = [\n        {'x':silk_x_min-pin1_marker_offset+pin1_marker_linelen, 'y':silk_y_min-pin1_marker_offset},\n        {'x':silk_x_min-pin1_marker_offset, 'y':silk_y_min-pin1_marker_offset},\n        {'x':silk_x_min-pin1_marker_offset, 'y':silk_y_min-pin1_marker_offset+pin1_marker_linelen}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.SilkS', width=configuration['silk_line_width']))\n    if fab_pin1_marker_type == 1:\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.Fab', width=configuration['fab_line_width']))\n\n    if fab_pin1_marker_type == 2:\n        poly_pin1_marker_type2 = [\n            {'x':-1, 'y':y_min},\n            {'x':0, 'y':y_min+1},\n            {'x':1, 'y':y_min}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker_type2, layer='F.Fab', width=configuration['fab_line_width']))\n\n    ########################## Fab Outline ###############################\n    kicad_mod.append(RectLine(start=[x_min,y_min], end=[x_max,y_max],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    ############################# CrtYd ##################################\n    part_x_min = x_min\n    part_x_max = x_max\n    part_y_min = y_min\n    part_y_max = y_max\n\n    cx1 = roundToBase(part_x_min-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(part_y_min-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(part_x_max+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(part_y_max+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n\n    ############################# Pads ##################################\n    pad_size = [pitch - pad_to_pad_clearance, drill_size + 2*pad_copper_y_solder_length]\n    if pad_size[0] - drill_size < 2*min_annular_ring:\n        pad_size[0] = drill_size + 2*min_annular_ring\n\n    # kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n    #                     at=[0, 0], size=pad_size,\n    #                     drill=drill_size, layers=Pad.LAYERS_THT))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[0, 0],\n        x_spacing=pitch, pincount=pincount,\n        size=pad_size, drill=drill_size,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    ######################### Text Fields ###############################\n    text_center_y = 1.5\n    body_edge={'left':part_x_min, 'right':part_x_max, 'top':part_y_min, 'bottom':part_y_max}\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position=text_center_y)\n\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in range(2,17):\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_vh_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"VH\"\nmanufacturer = 'JST'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eVH.pdf'\n\npitch = 3.96\ndrill = 1.7 # 1.65 +0.1/-0.0 -> 1.7 +/-0.05\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n\n#FP name strings\n\npart_base = \"B{n:d}P{n_total:s}-{suffix:s}\"\n\ndef generate_one_footprint(pins, series_params, configuration):\n    #calculate dimensions\n    A = (pins - 1) * pitch\n    B = A + 3.9\n    \n    post_omitted = True if len(series_params) == 4 else False\n    pins_used = pins - len(series_params[3]) if post_omitted else pins\n    \n    # if removed pins are a fixed pattern (every 2 pins, every 3 pins, etc.),\n    # then we can determine an effective pitch\n    # if all pins are loaded or removed pins are disorderly use the default pitch\n    pitch_effective = pitch\n    if post_omitted:\n        if ((pins - 1) % (pins_used - 1)) == 0:\n            pitch_effective = ((pins - 1) / (pins_used - 1)) * pitch\n\n    #generate name\n    mpn = part_base.format(n = pins_used, n_total = str(pins) if post_omitted else '', suffix=series_params[1])\n\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_used, mounting_pad = \"\",\n        pitch=pitch_effective, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series_params[2], mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #coordinate locations\n    #    x1 x3                  x4 x2\n    # y3    ____________________\n    # y1 __|____________________|__\n    #    | 1  2  3  4  5  6  7  8 |\n    # y2 |________________________|\n\n    #draw the component outline\n    x1 = A/2 - B/2\n    x2 = x1 + B\n    y2 = 4.8\n    y1 = y2 - 6.8\n    y3 = y1 - 1.7\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #draw outline on F.Fab layer\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2], layer='F.Fab', width=configuration['fab_line_width']))\n\n    #draw rectangle on F.Fab for latch\n    x3 = -0.75\n    x4 = pitch * (pins - 1) + 0.75\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x3,'y':y1},{'x':x3,'y':y3},{'x':x4,'y':y3},{'x':x4,'y':y1}], layer='F.Fab', width=configuration['fab_line_width']))\n\n    #draw pin1 mark on F.Fab\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1,'y':-1},{'x':(x1+1),'y':0}], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[{'x':x1,'y':1},{'x':(x1+1),'y':0}], layer='F.Fab', width=configuration['fab_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(y3-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #draw silk outline\n    off = configuration['silk_fab_offset']\n    x1 -= off\n    y1 -= off\n    x2 += off\n    y2 += off\n    x3 -= off\n    y3 -= off\n    x4 += off\n\n    kicad_mod.append(PolygoneLine(polygone=[\n            {'x':x1,'y':y2},\n            {'x':x1,'y':y1},\n            {'x':x3,'y':y1},\n            {'x':x3,'y':y3},\n            {'x':x4,'y':y3},\n            {'x':x4,'y':y1},\n            {'x':x2,'y':y1},\n            {'x':x2,'y':y2},\n            {'x':x1,'y':y2}],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add pin1 mark on silk\n    px = x1 - 0.2\n    m = 0.3\n\n    marker = [{'x': px,'y': 0},{'x': px-2*m,'y': m},{'x': px-2*m,'y': -m},{'x': px,'y': 0}]\n    kicad_mod.append(PolygoneLine(polygone=marker, layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n    pad_size = [pitch - pad_to_pad_clearance, drill + 2*pad_copper_y_solder_length]\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n    if pad_size[0] - drill > 2*pad_copper_y_solder_length:\n        pad_size[0] = drill + 2*pad_copper_y_solder_length\n\n    shape=Pad.SHAPE_OVAL\n    if pad_size[1] == pad_size[0]:\n        shape=Pad.SHAPE_CIRCLE\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n        optional_pad_params['radius_ratio'] = 0.25\n        optional_pad_params['maximum_radius'] = 0.25\n\n    exclude_pin_list = series_params[3] if post_omitted else []\n    if post_omitted:\n        if pins > 3 and len(series_params[3]) == 1:\n            for pin in range(1, pins + 1):\n                if pin != series_params[3][0]:\n                    #shape = optional_pad_params['tht_pad1_shape'] if pin == 1 else shape\n                    kicad_mod.append(Pad(\n                        number=pin, at=[(pin - 1) * pitch_effective, 0],\n                        type=Pad.TYPE_THT,\n                        shape=optional_pad_params['tht_pad1_shape'] if pin == 1 else shape,\n                        size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n                        **optional_pad_params))\n        else:\n            for pin in range(1, pins_used + 1):\n                kicad_mod.append(Pad(\n                    number=pin, at=[(pin - 1) * pitch_effective, 0],\n                    type=Pad.TYPE_THT,\n                    shape=optional_pad_params['tht_pad1_shape'] if pin == 1 else shape,\n                    size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n                    **optional_pad_params))\n    else:\n        kicad_mod.append(PadArray(\n            pincount=pins, x_spacing=pitch,\n            type=Pad.TYPE_THT, shape=shape,\n            size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    #tuple argument meaning: [start,end] list for range of pin counts, MPN suffix, material, optional list of missing pins\n    #the first two tuples generate the fully-stuffed parts while the last tuple makes a 3-pin part with pin 2 missing\n    #here are examples from page 4 of the datasheet (this can generate non-contiguous pin numbers so be careful!):\n    #1) B6P7-VH: ([7,8], series, series, [6])\n    #2) B6P7-VH-L: ([7,8], series + \"-L\", series, [2])\n    #3) 1. B4P7-VH: ([7,8], series, series, [2,4,6])\n    #3) 2. B3P7-VH: ([7,8], series, series, [2,3,5,6])\n    #3) 3. B3P9-VH: ([9,10], series, series, [2,3,4,6,7,8])\n    #for series_params in [([7,8], series, series, [6]), ([7,8], series + \"-L\", series, [2]), ([7,8], series, series, [2,4,6]), ([7,8], series, series, [2,3,5,6]), ([9,10], series, series, [2,3,4,6,7,8])]:\n    for series_params in [([2,11], series, series), ([2,12], series + \"-B\", series + \" PBT\"), ([3,4], series, series, [2])]:\n        for pincount in range(series_params[0][0], series_params[0][1]):\n            generate_one_footprint(pincount, series_params, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_xh_tht_side.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"XH\"\nmanufacturer = 'JST'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eXH.pdf'\n\n\npitch = 2.50\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n#FP name strings\npart_base = \"S{n}B-XH-{variant:s}\" #JST part number format string\n\nfab_pin1_marker_type = 2\nfab_first_marker_w = 1.25\nfab_first_marker_h = 1\n\n#FP description and tags\n\nvariant_params = {\n    'A':{\n        'V': 9.2,\n        'pin_range': range(2,17)\n        },\n    'A-1':{\n        'V': 7.6,\n        'pin_range': range(2,16)\n        }\n    }\n\ndef generate_one_footprint(pins, variant, configuration):\n    V=variant_params[variant]['V']\n    #calculate fp dimensions\n    A = (pins - 1) * pitch\n    B = A + 4.9\n\n    #Thickness of connector\n    T = 11.5\n\n    #corners\n    x1 = -2.45\n    x2 = x1 + B\n\n    x_mid = (x1 + x2) / 2\n\n    y2 = V\n    y1= y2 - T\n\n\n    #y at which the plastic tabs end\n    y3 = y2 - 7\n\n    #generate the name\n    mpn = part_base.format(n=pins, variant=variant)\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n    if pins == 2:\n        drill = 1.0\n    else:\n        drill = 0.95\n\n    pad_size = [pitch - pad_to_pad_clearance, drill + 2*pad_copper_y_solder_length]\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n\n    #generate the pads\n    ############################# Pads ##################################\n    # kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n    #                     at=[0, 0], size=pad_size,\n    #                     drill=drill, layers=Pad.LAYERS_THT))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[0, 0],\n        x_spacing=pitch, pincount=pincount,\n        size=pad_size, drill=drill,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    #draw the courtyard\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #offset the outline around the connector\n    off = configuration['silk_fab_offset']\n\n    xo1 = x1 - off\n    yo1 = y1 - off\n\n    xo2 = x2 + off\n    yo2 = y2 + off\n\n    #thickness of the notches\n    notch = 1.5\n\n    #wall thickness of the outline\n    wall = 1.2\n\n    #draw the outline of the connector\n    outline = [\n    {'x': x_mid,'y': yo2},\n    {'x': xo1,'y': yo2},\n    {'x': xo1,'y': yo1},\n    {'x': xo1+wall+2*off,'y': yo1},\n    {'x': xo1+wall+2*off,'y': y3 - off},\n    {'x': A/2,'y': y3 - off},\n    #{'x': -1.1,'y': y3 + off}\n    ]\n    if variant == 'A-1':\n        outline = outline[:-1]\n    kicad_mod.append(PolygoneLine(polygone=outline, layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=outline, x_mirror=x_mid, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    outline = [\n    {'x': x_mid,'y': y2},\n    {'x': x1,'y': y2},\n    {'x': x1,'y': y1},\n    {'x': x1+wall,'y': y1},\n    {'x': x1+wall,'y': y3},\n    {'x': A/2,'y': y3},\n    #{'x': -1.1,'y': y3 + off}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=outline, layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=outline, x_mirror=x_mid, layer='F.Fab', width=configuration['fab_line_width']))\n\n\n    #draw the pinsss\n    for i in range(pins):\n\n        x = i * pitch\n        w = 0.25\n        kicad_mod.append(RectLine(start=[x-w,y3+1], end=[x+w,y2-0.5], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add pin-1 designator\n    px = 0\n    py = -1.5\n    m = 0.3\n\n    pin1 = [\n    {'x': px,'y': py},\n    {'x': px-m,'y': py-2*m},\n    {'x': px+m,'y': py-2*m},\n    {'x': px,'y': py},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin1, layer='F.SilkS', width=configuration['silk_line_width']))\n    if fab_pin1_marker_type == 1:\n        kicad_mod.append(PolygoneLine(polygone=pin1, layer='F.Fab', width=configuration['fab_line_width']))\n\n    if fab_pin1_marker_type == 2:\n        fab_marker_left = -fab_first_marker_w/2.0\n        fab_marker_bottom = y3 - fab_first_marker_h\n        poly_fab_marker = [\n            {'x':fab_marker_left, 'y':y3},\n            {'x':0, 'y':fab_marker_bottom},\n            {'x':fab_marker_left + fab_first_marker_w, 'y':y3}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_fab_marker, layer='F.Fab', width=configuration['fab_line_width']))\n\n    ######################### Text Fields ###############################\n    text_center_y = 'center'\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position=text_center_y)\n\n\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        for pincount in variant_params[variant]['pin_range']:\n            generate_one_footprint(pincount, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_xh_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nfrom itertools import chain\n\nseries = \"XH\"\nmanufacturer = 'JST'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eXH.pdf'\n\npitch = 2.50\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n#FP name strings\npart_base = \"B{n}B-XH-{variant:s}\" #JST part number format string\n\nvariant_params = {\n    'A':{\n        'boss': False,\n        'back_protrusion': False,\n        'pin_range': chain(range(2,17), [20])\n    },\n    'AM':{\n        'boss': True,\n        'back_protrusion': False,\n        'pin_range': chain(range(1,11), [12])\n    }\n}\n\nfab_first_marker_w = 1.25\npin1_marker_linelen = 1.25\nfab_first_marker_h = 1\nfab_pin1_marker_type = 2\npin1_marker_offset = 0.3\n\n#FP description and tags\n\ndef generate_one_footprint(pins, variant, configuration):\n    #calculate fp dimensions\n    boss = variant_params[variant]['boss']\n    A = (pins - 1) * pitch\n    B = A + 4.9\n\n    #connector thickness\n    T = 5.75\n\n    #corners\n    x1 = -2.45\n    x2 = x1 + B\n\n\n    x_mid = (x1 + x2) / 2\n\n    y1 = -2.35\n    y2 = y1 + T\n\n    #generate the name\n    mpn = part_base.format(n=pins, variant=variant)\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s}{:s} ({:s}), generated with kicad-footprint-generator\".format(\n        series, mpn, ', with boss' if boss else '', datasheet))\n\n    tags = configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation])\n    if boss:\n        tags += \" boss\"\n    #set the FP tags\n    kicad_mod.setTags(tags)\n\n    #draw simple outline on F.Fab layer\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],layer='F.Fab', width=configuration['fab_line_width']))\n\n    # set general values\n    #kicad_mod.append(Text(type='reference', text='REF**', at=[x_mid,-3.5], layer='F.SilkS'))\n\n    if pins == 2:\n        drill = 1.0\n    else:\n        drill = 0.95\n\n    pad_size = [pitch - pad_to_pad_clearance, drill + 2*pad_copper_y_solder_length]\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n\n    #generate the pads\n    ############################# Pads ##################################\n    # kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n    #                     at=[0, 0], size=pad_size,\n    #                     drill=drill, layers=Pad.LAYERS_THT))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[0, 0],\n        x_spacing=pitch, pincount=pins,\n        size=pad_size, drill=drill,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    if boss:\n        if pins == 1:\n            boss_y = 4.35\n            boss_x = 0\n            boss_drill = 1.75\n            kicad_mod.append(Pad(type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n                                 at=[boss_x, boss_y], size=boss_drill,\n                                 drill=boss_drill, layers=Pad.LAYERS_NPTH))\n        else:\n            boss_y = 2\n            boss_x = -1.6\n            boss_drill = 1.2\n            kicad_mod.append(Pad(type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n                                 at=[boss_x, boss_y], size=boss_drill,\n                                 drill=boss_drill, layers=Pad.LAYERS_NPTH))\n\n    if boss and pins == 1:\n        boss_size_1pin = 1.5\n        off = configuration['silk_fab_offset']\n        x_boss_fab_off = boss_size_1pin/2 + off\n        x_boss_pad_off = boss_drill/2 + configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n        x_boss = x_boss_fab_off\n        if x_boss_pad_off > x_boss:\n            x_boss=x_boss_pad_off\n        out_silk = PolygoneLine(polygone=[\n            {'x': -x_boss, 'y':boss_y},\n            {'x': -x_boss, 'y':y2+off},\n            {'x': x1-off, 'y':y2+off},\n            {'x': x1-off, 'y':y1-off},\n            {'x': x2+off, 'y':y1-off},\n            {'x': x2+off, 'y':y2+off},\n            {'x': x_boss, 'y':y2+off},\n            {'x': x_boss, 'y':boss_y}\n        ], layer='F.SilkS', width=configuration['silk_line_width'])\n        kicad_mod.append(out_silk)\n        kicad_mod.append(Arc(center=[0,boss_y], start=[-x_boss, boss_y], angle=-180,\n            layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n        out_fab = PolygoneLine(polygone=[\n            {'x': -boss_size_1pin/2, 'y':boss_y},\n            {'x': -boss_size_1pin/2, 'y':y2},\n            {'x': x1, 'y':y2},\n            {'x': x1, 'y':y1},\n            {'x': x2, 'y':y1},\n            {'x': x2, 'y':y2},\n            {'x': boss_size_1pin/2, 'y':y2},\n            {'x': boss_size_1pin/2, 'y':boss_y}\n        ], layer='F.Fab', width=configuration['fab_line_width'])\n        kicad_mod.append(out_fab)\n        kicad_mod.append(Arc(center=[0,boss_y], start=[-boss_size_1pin/2, boss_y], angle=-180,\n            layer=\"F.Fab\", width=configuration['fab_line_width']))\n\n\n    else:\n        out = RectLine(start=[x1,y1], end=[x2,y2], offset=configuration['silk_fab_offset'],\n            layer='F.SilkS', width=configuration['silk_line_width'])\n        kicad_mod.append(out)\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #draw the courtyard\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    if boss and pins == 1:\n        cy2 = roundToBase(boss_y+boss_drill/2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #draw the connector outline\n\n\n    if fab_pin1_marker_type == 2:\n        fab_marker_left = -fab_first_marker_w/2.0\n        fab_marker_bottom = y1 + fab_first_marker_h\n        poly_fab_marker = [\n            {'x':fab_marker_left, 'y':y1},\n            {'x':0, 'y':fab_marker_bottom},\n            {'x':fab_marker_left + fab_first_marker_w, 'y':y1}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_fab_marker, layer='F.Fab', width=configuration['fab_line_width']))\n\n    #wall thickness w\n    w = 0.75\n\n    #gap size g\n    g = 1.5\n\n    off = 0.1\n\n    x1 -= off\n    y1 -= off\n\n    x2 += off\n    y2 += off\n\n    #draw the center tab\n    kicad_mod.append(RectLine(start=[g/2,y1], end=[A-g/2,y1+w], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add left tab\n    kicad_mod.append(RectLine(start=[x1,y1], end=[-g/2,y1+w], layer='F.SilkS', width=configuration['silk_line_width']))\n    #right tab\n    kicad_mod.append(RectLine(start=[A+g/2,y1], end=[x2,y1+w], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #add other line\n    line = [\n    {'x': x1,'y': y1+w+g},\n    {'x': x1+w,'y': y1+w+g},\n    {'x': x1+w,'y': y2-w},\n    {'x': A/2,'y': y2-w}\n    ]\n    if boss and pins > 1:\n        line2 = line[:2]\n        line2.append({'x': x1+w,'y': boss_y - boss_drill/2 - configuration['silk_line_width']/2 - configuration['silk_pad_clearance']})\n        kicad_mod.append(PolygoneLine(polygone=line2, layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Line(start=[A/2, y2-w],\n            end=[boss_x+boss_drill/2+ configuration['silk_line_width']/2 + configuration['silk_pad_clearance'], y2-w],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n    else:\n        kicad_mod.append(PolygoneLine(polygone=line, layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=line, x_mirror=A/2, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #pin-1 marker\n    y =  -2.75\n    m = 0.3\n\n    poly_pin1_marker = [\n        {'x':x1-pin1_marker_offset+pin1_marker_linelen, 'y':y1-pin1_marker_offset},\n        {'x':x1-pin1_marker_offset, 'y':y1-pin1_marker_offset},\n        {'x':x1-pin1_marker_offset, 'y':y1-pin1_marker_offset+pin1_marker_linelen}\n    ]\n    if fab_pin1_marker_type == 2:\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.SilkS', width=configuration['silk_line_width']))\n    if fab_pin1_marker_type == 3:\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.Fab', width=configuration['fab_line_width']))\n\n    pin = [\n    {'x': 0,'y': y},\n    {'x': -m,'y': y-2*m},\n    {'x': m,'y': y-2*m},\n    {'x': 0,'y': y},\n    ]\n\n\n    if fab_pin1_marker_type == 1:\n        kicad_mod.append(PolygoneLine(polygone=pin, layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=pin, layer='F.Fab', width=configuration['fab_line_width']))\n\n    ######################### Text Fields ###############################\n    text_center_y = 'bottom'\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position=text_center_y)\n\n\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        for pincount in variant_params[variant]['pin_range']:\n            generate_one_footprint(pincount, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_ze_tht_side.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\nfrom math import floor,ceil\n\nseries = \"ZE\"\nmanufacturer = 'JST'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eZE.pdf'\n\npitch = 1.5\ny_spacing = 3.70\n\ndrill = 0.75 # 0.7 +0.1/-0.1 -> 0.75 +/-0.05\npad_size = [1.4, 1.75] # Using same pad size as top entry\n\nmh_drill = 1.15\n\ndef generate_one_footprint(pincount, configuration):\n    mpn = \"S{pincount:02}B-ZESK-2D\".format(pincount=pincount)\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #dimensions\n    A = (pincount - 1) * 1.5\n    B = A + 4.5\n\n    #outline\n    x1 = -1.55 - 0.7\n    x2 = x1 + B\n\n    xMid = x1 + B/2\n\n    y2 = 3.7 + 3.65\n    y1 = y2 - 7.8\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #add outline to F.Fab\n    kicad_mod.append(RectLine(\n        start={'x': x1, 'y': y1},\n        end={'x': x2, 'y': y2},\n        layer='F.Fab', width=configuration['fab_line_width']\n        ))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    if y1 < -pad_size[1]/2:\n        cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    else:\n        cy1 = roundToBase(-pad_size[1]/2-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    #expand the outline a little bit\n    out = configuration['silk_fab_offset']\n    x1 -= out\n    x2 += out\n    y1 -= out\n    y2 += out\n\n    silk_pad_offset = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n    if y1 < -(pad_size[1]/2 + silk_pad_offset):\n        kicad_mod.append(RectLine(start={'x':x1,'y':y1}, end={'x':x2,'y':y2},\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    else:\n        num_odd_pins = ceil(pincount/2)\n        pos_last_odd_pad = (num_odd_pins-1) * 2*pitch\n        poly_silk = [\n            {'x': -(pad_size[0]/2 + silk_pad_offset), 'y': y1},\n            {'x': x1, 'y': y1},\n            {'x': x1, 'y': y2},\n            {'x': x2, 'y': y2},\n            {'x': x2, 'y': y1},\n            {'x': pos_last_odd_pad + (pad_size[0]/2 + silk_pad_offset), 'y': y1},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_silk,\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n        for i in range(num_odd_pins-1):\n            kicad_mod.append(Line(start=[i * 2*pitch + (pad_size[0]/2 + silk_pad_offset), y1],\n                end=[(i+1) * 2*pitch - (pad_size[0]/2 + silk_pad_offset), y1],\n                width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n\n    # create odd numbered pads\n    #createNumberedPadsTHT(kicad_mod, ceil(pincount/2), pitch * 2, drill, pad_size,  increment=2)\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            initial=row_idx+1, start=[row_idx*pitch, row_idx*y_spacing],\n            x_spacing=pitch*2,\n            pincount=ceil(pincount/2) if row_idx == 0 else floor(pincount/2),\n            size=pad_size, drill=drill, increment=2,\n            type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n    #create even numbered pads\n    #createNumberedPadsTHT(kicad_mod, floor(pincount/2), pitch * 2, drill, pad_size, starting=2, increment=2, y_off=y_spacing, x_off=pitch)\n\n\n\n    #add mounting holes\n    # kicad_mod.append(MountingHole(\n    #     {'x': -1.55, 'y': 1.85},\n    #     1.1\n    # ))\n    #\n    # kicad_mod.append(MountingHole(\n    #     {'x': A+1.55    , 'y': 1.85},\n    #     1.1\n    # )\n    kicad_mod.append(Pad(at={'x': -1.55, 'y': 1.85}, type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_NPTH,\n        drill=mh_drill, size=mh_drill))\n    kicad_mod.append(Pad(at={'x': A+1.55, 'y': 1.85}, type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_NPTH,\n        drill=mh_drill, size=mh_drill))\n\n    #draw the line at the bottom\n\n    xa = xMid - A/2 + out\n    xb = xMid + A/2 - out\n    y3 = y2 - 1\n    kicad_mod.append(PolygoneLine(polygone=[\n        {'x':xa,'y':y2},\n        {'x':xa,'y':y3},\n        {'x':xb,'y':y3},\n        {'x':xb,'y':y2}\n    ], width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    # add pin-1 marker\n    D = 0.3\n    L = 1.5\n    pin_1 = [\n        {'x': x1-D,'y': y1-D+L},\n        {'x': x1-D,'y':  y1-D},\n        {'x': x1-D + L,'y':  y1-D},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin_1, width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    kicad_mod.append(PolygoneLine(polygone=pin_1, layer='F.Fab', width=configuration['fab_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in range(2, 17):\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/conn_jst_ze_tht_top.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\"))\n\nfrom math import floor,ceil\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"ZE\"\nmanufacturer = 'JST'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.jst-mfg.com/product/pdf/eng/eZE.pdf'\n\n#ZE connector, top-entry THT, NO BOSS\n\npitch = 1.5\ny_spacing = 2.0\n\ndrill = 0.75 # 0.7 +0.1/-0.0 -> 0.75 +/-0.05\nmh_drill = 0.85\n\npad_size = [1.4, 1.75] # Measurements from freecad sketch (pad to pad clearance > 0.8 for a 45° trace.)\n\nvariant_parameters = {\n    '1D': {\n        'boss':True,\n        'pin_range':range(2,17),\n        'descr_str':', with boss'\n        },\n    'D': {\n        'boss':False,\n        'pin_range':range(3,17),\n        'descr_str':''\n        }\n}\ndef generate_one_footprint(pincount, variant, configuration):\n    mpn = \"B{pincount:02}B-ZESK-{suff}\".format(pincount=pincount,suff=variant)\n    boss = variant_parameters[variant]['boss']\n\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"JST {:s} series connector, {:s}{:s} ({:s}), generated with kicad-footprint-generator\"\\\n        .format(series, mpn, variant_parameters[variant]['descr_str'], datasheet))\n\n    tags = configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation])\n    if boss:\n        tags += ' boss'\n    kicad_mod.setTags(tags)\n\n    #dimensions\n    A = (pincount - 1) * 1.5\n    B = A + 4.5\n\n    #outline\n    x1 = -1.55 - 0.7\n    x2 = x1 + B\n\n    xMid = x1 + B/2\n\n    y2 = 0.65\n    y1 = y2 - 5.75\n    body_edge={'left':x1, 'right':x2, 'top':y1, 'bottom':y2}\n\n    #add outline to F.Fab\n    kicad_mod.append(RectLine(\n        start={'x': x1, 'y': y1},\n        end={'x': x2, 'y': y2},\n        layer='F.Fab', width=configuration['fab_line_width']\n        ))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(x1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    if y1 < -pad_size[1]/2:\n        cy1 = roundToBase(y1-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    else:\n        cy1 = roundToBase(-pad_size[1]/2-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(x2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(y2+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n\n    # create odd numbered pads\n    # createNumberedPadsTHT(kicad_mod, ceil(pincount/2), pitch * 2, drill, {'x':dia, 'y':dia},  increment=2)\n    #special treatment for pin 1 (rectangular pad alone would reduce the clearance too much)\n    if configuration['kicad4_compatible']:\n        kicad_mod.append(Pad(number=1, at=[0, 0],\n            size=pad_size, drill=drill,\n            type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT))\n\n        kicad_mod.append(Pad(number=1, at=[-pad_size[0]/4, 0],\n            size=[pad_size[0]/2,pad_size[1]],\n            type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=['F.Cu', 'F.Mask']))\n        kicad_mod.append(Pad(number=1, at=[-pad_size[0]/4, 0],\n            size=[pad_size[0]/2,pad_size[1]],\n            type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=['B.Cu', 'B.Mask']))\n\n    else:\n        kicad_mod.append(ChamferedPad(number=1, at=[0, 0],\n            size=pad_size, drill=drill,\n            type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n            chamfer_size=0.4, radius_ratio=0.25, maximum_radius=0.25,\n            corner_selection=CornerSelection({CornerSelection.TOP_RIGHT:True})))\n\n    if pincount > 2:\n        kicad_mod.append(PadArray(initial=3, start=[2*pitch, 0],\n            x_spacing=pitch*2, pincount=ceil(pincount/2)-1,\n            size=pad_size, drill=drill, increment=2,\n            type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT))\n\n    #create even numbered pads\n    # createNumberedPadsTHT(kicad_mod, floor(pincount/2), pitch * 2, drill, {'x':dia, 'y':dia}, starting=2, increment=2, y_off=y_spacing, x_off=pitch)\n    kicad_mod.append(PadArray(initial=2, start=[pitch, -y_spacing],\n        x_spacing=pitch*2, pincount=floor(pincount/2),\n        size=pad_size, drill=drill, increment=2,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT))\n\n    #expand the outline a little bit\n    out = configuration['silk_fab_offset']\n    x1 -= out\n    x2 += out\n    y1 -= out\n    y2 += out\n\n    silk_pad_offset = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n    if y2 > (pad_size[1]/2 + silk_pad_offset):\n        kicad_mod.append(RectLine(start={'x':x1,'y':y1}, end={'x':x2,'y':y2},\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    else:\n        num_odd_pins = ceil(pincount/2)\n        pos_last_odd_pad = (num_odd_pins-1) * 2*pitch\n        poly_silk = [\n            {'x': -(pad_size[0]/2 + silk_pad_offset), 'y': y2},\n            {'x': x1, 'y': y2},\n            {'x': x1, 'y': y1},\n            {'x': x2, 'y': y1},\n            {'x': x2, 'y': y2},\n            {'x': pos_last_odd_pad + (pad_size[0]/2 + silk_pad_offset), 'y': y2},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_silk,\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n        for i in range(num_odd_pins-1):\n            kicad_mod.append(Line(start=[i * 2*pitch + (pad_size[0]/2 + silk_pad_offset), y2],\n                end=[(i+1) * 2*pitch - (pad_size[0]/2 + silk_pad_offset), y2],\n                width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n\n    #add mounting hole (only for the -1D option which has the boss)\n    if boss:\n        #     kicad_mod.append(MountingHole(\n        #     {'x': -1.65, 'y': -3.8},\n        #     1.1\n        # )\n        kicad_mod.append(Pad(at={'x': -1.65, 'y': -3.8}, type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_NPTH,\n            drill=mh_drill, size=mh_drill))\n\n    #thicknes t of sidewalls\n    t = 0.8\n    xa = xMid - A/2 - 0.25 + out\n    xb = xMid + A/2 + 0.25 - out\n    y3 = y1 + 1.7\n\n    q = 0.4 #inner rect offset\n\n    #outer rect\n    kicad_mod.append(RectLine(\n        start={'x': xa,'y': y1},\n        end={'x': xb,'y': y3},\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"\n        ))\n\n    #inner rect\n    kicad_mod.append(RectLine(\n        start={'x': xa+q,'y': y1+q},\n        end={'x': xb-q,'y': y3-q},\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"\n        ))\n\n    #left side\n    if not boss:\n        kicad_mod.append(PolygoneLine(polygone=[\n            {'x': xa,'y': y3},\n            {'x': x1+t,'y':y3},\n            {'x': x1+t,'y':y2-t},\n            {'x': -1,'y':y2-t},\n        ], width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    else: #boss were declared\n        kicad_mod.append(Line(\n            start={'x': xa,'y': y3},\n            end={'x': -0.9,'y': y3},\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"\n            ))\n\n        kicad_mod.append(PolygoneLine(polygone=[\n            {'x': x1+t,'y': -3},\n            {'x': x1+t,'y': y2-t},\n            {'x': -1,'y': y2-t},\n        ], width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    #right side\n\n    if pincount %2 == 0: #even number of pins\n        xEnd = (pincount / 2 - 1) * (2 * pitch) + 1\n    else:\n        xEnd = floor(pincount / 2) * (2 * pitch) + 1\n\n    kicad_mod.append(PolygoneLine(polygone=[\n        {'x': xb,'y': y3},\n        {'x': x2-t,'y': y3},\n        {'x': x2-t,'y': y2-t},\n        {'x': xEnd,'y': y2-t},\n    ], width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    #draw lines between pads\n    for i in range(0, ceil(pincount/2) - 1):\n\n        X1 = i * 2 * pitch + pad_size[1]/2 + silk_pad_offset\n        X2 = (i + 1) * 2 * pitch - (pad_size[1]/2 + silk_pad_offset)\n        kicad_mod.append(Line(\n            start={'x': X1,'y': y2-t},\n            end={'x': X2,'y': y2-t},\n            width=configuration['silk_line_width'], layer='F.SilkS'))\n\n    #draw the 'vertical' lines where the actual pinny bits go\n\n    #width of each slot w\n    w = 0.15\n    #clearance distance d\n    d = 0.3\n    # for i in range(pincount):\n    #\n    #     x = i * pitch\n    #\n    #     Y1 = y3 + d\n    #     Y2 = -pad_size[1]/2 - d\n    #\n    #     kicad_mod.append(RectLine(start={'x':x-w, 'y': Y1},\n    #     end={'x':x+w, 'y': Y2},\n    #     width=configuration['fab_line_width'], layer='F.Fab'))\n\n    # add pin-1 marking above the pin1\n\n    d = 0.3\n    l = 1.5\n    xp1 = x1 - d\n    xp2 = xp1 + l\n\n    yp2 = y2 + d\n    yp1 = yp2 - l\n\n    pin1 = [\n        {'x': xp1,'y': yp1},\n        {'x': xp1,'y': yp2},\n        {'x': xp2,'y': yp2},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin1,width=configuration['silk_line_width'], layer='F.SilkS'))\n    kicad_mod.append(PolygoneLine(polygone=pin1,layer='F.Fab', width=configuration['fab_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_parameters:\n        for pincount in variant_parameters[variant]['pin_range']:\n            generate_one_footprint(pincount, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_JST/helpers.py",
    "content": "def roundToBase(value, base):\n    return round(value/base) * base\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/00-SMD footprint generators can be found in Connector_SMD_single_row_plus_mounting_pad.md",
    "content": "The following connector footprints are generated in the generic scirpt located in ../Connector_SMD_single_row_plus_mounting_pad/\n\n- 'Panelmate'\n  - '53780-{pincount:02d}70'\n- 'Pico-EZmate'\n  - '78171-00{pincount:02d}'\n- 'Pico-EZmate_Slim'\n  - '202656-0{pincount:02d}1'\n- 'PicoBlade'\n  - '53398-{pincount:02d}71'\n- 'PicoBlade'\n  - '53261-{pincount:02d}71'\n- 'Pico-Clasp'\n  - '501331-{pincount:02d}07'\n- 'Pico-Clasp'\n  - '501331-{pincount:02d}07'\n- 'Pico-Clasp'\n  - '202396-{pincount:02d}07'\n- 'Pico-Lock'\n  - '504050-{pincount:02d}91'\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_ffc_molex_200528.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\nfrom footprint_keepout_area import addRectangularKeepout\n\npinrange = range(4, 31) # 4-30 circuits\n\nseries = \"\"\nseries_long = ('Molex 1.00mm Pitch Easy-On BackFlip, ' +\n               'Right-Angle, Bottom Contact FFC/FPC')\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 1\n\nconn_category = \"FFC-FPC\"\n\nlib_by_conn_category = True\n\npart_code = \"200528-0{:02d}0\"\n\npitch = 1.0\npad_size = (0.4, 1.0)\nmp_size = (2.0, 1.3)\nfoot_y = 3.95\ntoe_size = (0.55, 0.35)\nlead_size = (0.15, pad_size[1] - 0.6)\n\n\n\n\ndef make_module(pin_count, configuration):\n    mpn = part_code.format(pin_count)\n    datasheet='https://www.molex.com/pdm_docs/sd/2005280{:02d}0_sd.pdf'.format(pin_count)\n\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(\n        man = manufacturer,\n        series = series,\n        mpn = mpn,\n        num_rows = number_of_rows,\n        pins = pin_count,\n\tpins_per_row = pin_count,\n        mounting_pad = \"-1MP\",\n        pitch = pitch,\n        orientation = orientation_str)\n\n    footprint_name = footprint_name.replace(\"__\",'_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setAttribute('smd')\n    kicad_mod.setDescription(\n        (\"Molex {:s}, {:s}, {:d} Circuits ({:s}), \" +\n         \"generated with kicad-footprint-generator\").format(\n        series_long, mpn, pin_count, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(\n        man=manufacturer,\n        series=series,\n        orientation=orientation_str,\n        entry=configuration['entry_direction'][orientation]))\n\n\n\n\n    A = pin_count + 5.2\n    B = pin_span = pin_count - 1\n    C = pin_count + 3.6\n    pin_y = -(0.4 - (lead_size[1] / 2)) - 0.71\n    lever_size = (C, 4)\n    toe_ins_corner = ((A / 2) - toe_size[0], pin_y + (0.4 - (lead_size[1] / 2)))\n    lever_out_corner = (C / 2,\n        (toe_ins_corner[1] - toe_size[1]) + 5.25)\n    pad_silk_off = (configuration['silk_pad_clearance'] +\n                    (configuration['silk_line_width'] / 2))\n    fab_silk_off = configuration['silk_fab_offset']\n\n    ## Mounting Pads ##\n\n    mp_pos = ((pin_span / 2) + 1.8 + (mp_size[0] / 2),\n        pin_y + (pad_size[1] / 2) + 1.55 + (mp_size[1] / 2))\n\n    def make_anchor_pad(x_direction):\n        kicad_mod.append(\n            Pad(number = configuration['mounting_pad_number'],\n                type = Pad.TYPE_SMT,\n                shape = Pad.SHAPE_RECT,\n                at = [x_direction * mp_pos[0], mp_pos[1]],\n                size = mp_size,\n                layers = Pad.LAYERS_SMT))\n    make_anchor_pad(-1)\n    make_anchor_pad(1)\n\n    ## Pads ##\n\n    kicad_mod.append(\n        PadArray(center = [0, pin_y],\n            pincount = pin_count,\n            x_spacing = pitch,\n            type = Pad.TYPE_SMT,\n            shape = Pad.SHAPE_RECT,\n            size = pad_size,\n            layers = Pad.LAYERS_SMT))\n\n    ## Fab ##\n\n    fab_body_outline = [\n        {'x': toe_ins_corner[0], 'y': toe_ins_corner[1] - toe_size[1]},\n        {'x': toe_ins_corner[0], 'y': toe_ins_corner[1]},\n        {'x': -toe_ins_corner[0], 'y': toe_ins_corner[1]},\n        {'x': -toe_ins_corner[0], 'y': toe_ins_corner[1] - toe_size[1]},\n        {'x': -(A / 2), 'y': toe_ins_corner[1] - toe_size[1]},\n        {'x': -(A / 2), 'y': (toe_ins_corner[1] - toe_size[1]) + foot_y},\n        {'x': (A / 2), 'y': (toe_ins_corner[1] - toe_size[1]) + foot_y},\n        {'x': (A / 2), 'y': toe_ins_corner[1] - toe_size[1]},\n        {'x': toe_ins_corner[0], 'y': toe_ins_corner[1] - toe_size[1]}\n    ]\n\n    kicad_mod.append(PolygoneLine(\n        polygone = fab_body_outline,\n        layer = 'F.Fab',\n        width = configuration['fab_line_width']))\n\n    fab_pin1_mark = [\n        {'x': -(pin_span / 2) - 0.5, 'y': toe_ins_corner[1]},\n        {'x': -(pin_span / 2), 'y': toe_ins_corner[1] + 0.75},\n        {'x': -(pin_span / 2) + 0.5, 'y': toe_ins_corner[1]}\n    ]\n\n    kicad_mod.append(PolygoneLine(\n        polygone = fab_pin1_mark,\n        layer = 'F.Fab',\n        width = configuration['fab_line_width']))\n\n    fab_lever_outline = [\n        {'x': lever_out_corner[0], 'y': lever_out_corner[1] - lever_size[1]},\n        {'x': -lever_out_corner[0], 'y': lever_out_corner[1] - lever_size[1]},\n        {'x': -lever_out_corner[0], 'y': lever_out_corner[1]},\n        {'x': lever_out_corner[0], 'y': lever_out_corner[1]},\n        {'x': lever_out_corner[0], 'y': lever_out_corner[1] - lever_size[1]}\n    ]\n\n    kicad_mod.append(PolygoneLine(\n        polygone = fab_lever_outline,\n        layer = 'F.Fab',\n        width = configuration['fab_line_width']))\n\n    ## SilkS ##\n\n    silk_outline1 = [\n        {'x': (-(pin_span / 2) - (pad_size[0] / 2)) - pad_silk_off, 'y': pin_y - (pad_size[1] / 2)},\n        {'x': (-(pin_span / 2) - (pad_size[0] / 2)) - pad_silk_off, 'y': toe_ins_corner[1] - fab_silk_off},\n        {'x': -toe_ins_corner[0] + fab_silk_off, 'y': toe_ins_corner[1] - fab_silk_off},\n        {'x': -toe_ins_corner[0] + fab_silk_off, 'y': (toe_ins_corner[1] - toe_size[1]) - fab_silk_off},\n        {'x': -(A / 2) - fab_silk_off, 'y': (toe_ins_corner[1] - toe_size[1]) - fab_silk_off},\n        {'x': -(A / 2) - fab_silk_off, 'y': (mp_pos[1] - (mp_size[1] / 2)) - pad_silk_off},\n    ]\n\n\n    silk_outline2 = [\n        {'x': -(A / 2) - fab_silk_off, 'y': (mp_pos[1] + (mp_size[1] / 2)) + pad_silk_off},\n        {'x': -(A / 2) - fab_silk_off, 'y': ((toe_ins_corner[1] - toe_size[1]) + foot_y) + fab_silk_off},\n        {'x': -lever_out_corner[0] - fab_silk_off, 'y': ((toe_ins_corner[1] - toe_size[1]) + foot_y) + fab_silk_off},\n        {'x': -lever_out_corner[0] - fab_silk_off, 'y': lever_out_corner[1] + fab_silk_off},\n        {'x': lever_out_corner[0] + fab_silk_off, 'y': lever_out_corner[1] + fab_silk_off},\n        {'x': lever_out_corner[0] + fab_silk_off, 'y': ((toe_ins_corner[1] - toe_size[1]) + foot_y) + fab_silk_off},\n        {'x': (A / 2) + fab_silk_off, 'y': ((toe_ins_corner[1] - toe_size[1]) + foot_y) + fab_silk_off},\n        {'x': (A / 2) + fab_silk_off, 'y': (mp_pos[1] + (mp_size[1] / 2)) + pad_silk_off},\n    ]\n\n    silk_outline3 = [\n        {'x': (A / 2) + fab_silk_off, 'y': (mp_pos[1] - (mp_size[1] / 2)) - pad_silk_off},\n        {'x': (A / 2) + fab_silk_off, 'y': (toe_ins_corner[1] - toe_size[1]) - fab_silk_off},\n        {'x': toe_ins_corner[0] - fab_silk_off, 'y': (toe_ins_corner[1] - toe_size[1]) - fab_silk_off},\n        {'x': toe_ins_corner[0] - fab_silk_off, 'y': toe_ins_corner[1] - fab_silk_off},\n        {'x': ((pin_span / 2) + (pad_size[0] / 2)) + pad_silk_off, 'y': toe_ins_corner[1] - fab_silk_off}\n    ]\n\n    kicad_mod.append(PolygoneLine(\n        polygone = silk_outline1,\n        layer = 'F.SilkS',\n        width = configuration['silk_line_width']))\n\n    kicad_mod.append(PolygoneLine(\n        polygone = silk_outline2,\n        layer = 'F.SilkS',\n        width = configuration['silk_line_width']))\n\n    kicad_mod.append(PolygoneLine(\n        polygone = silk_outline3,\n        layer = 'F.SilkS',\n        width = configuration['silk_line_width']))\n\n    ## CrtYd ##\n\n    bounding_box = {\n        'top': pin_y - (pad_size[1] / 2),\n        'left': (-mp_pos[0] - (mp_size[0] / 2)),\n        'bottom': lever_out_corner[1],\n        'right': (mp_pos[0] + (mp_size[0] / 2))}\n\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ## Text ##\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=bounding_box, courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='center')\n\n\n\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    if lib_by_conn_category:\n        lib_name = configuration['lib_name_specific_function_format_string'].format(category=conn_category)\n    else:\n        lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\n\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for pincount in pinrange:\n        make_module(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_ffc_molex_502250.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\nfrom footprint_keepout_area import addRectangularKeepout\n\npinrange = [17, 21, 23, 27, 33, 35, 39, 41, 51]\n\nseries = \"\"\nseries_long = 'Molex 0.30mm Pitch Easy-On BackFlip Type FFC/FPC'\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 2\n\nconn_category = \"FFC-FPC\"\n\nlib_by_conn_category = True\n\npart_code = \"502250-{0}91\"\n\n# def get_name(pin_count):\n#     return 'Molex-502250-{0}91_2Rows-{0}Pins_P0.3mm_Horizontal'.format(pin_count)\n\ncable_pitch = 0.3\nodd_pad_size = (0.80, 0.26) # bottom\neven_pad_size = (0.65, 0.3) # top\nanchor_pad_size = (0.85, 0.4)\n\ndef make_module(pin_count, configuration):\n    pad_silk_off = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n    off = configuration['silk_fab_offset']\n\n    datasheet='http://www.molex.com/pdm_docs/sd/502250{0}91_sd.pdf'.format(pin_count)\n\n    mpn = part_code.format(pin_count)\n\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_unequal_row_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins=pin_count, mounting_pad = \"-1MP\",\n        pitch=cable_pitch*2, orientation=orientation_str)\n\n    footprint_name = footprint_name.replace(\"__\",'_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setAttribute('smd')\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Circuits ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pin_count, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n    TL = 0.25\n    TW = 0.3\n\n    gab_anchor_L = 0.4\n    gab_anchor_W = 0.3\n\n    pad_to_pad_outside = 3.6\n    row_spacing = pad_to_pad_outside - odd_pad_size[0]/2 - even_pad_size[0]/2\n\n    odd_pad_x = -pad_to_pad_outside/2 + odd_pad_size[0]/2\n    even_pad_x = odd_pad_x + row_spacing\n\n\n    pins_width = cable_pitch * (pin_count - 1)\n    anchor_pad_spacing = pins_width + 1.4\n\n    anchor_pad_x = odd_pad_x - odd_pad_size[0]/2 + (0.3 + anchor_pad_size[0]/2)\n\n    width = pins_width + 2.1\n    bar_width = pins_width + 0.48\n\n    body_edge = {\n        'top': -width/2,\n        'bottom': width/2,\n        'left': anchor_pad_x -0.55/2 - 0.36\n    }\n    body_edge['right'] = body_edge['left'] + 3.53 - TL\n\n    bar_down_edge = body_edge['left'] + 4.19\n\n    ctyd_width = anchor_pad_spacing + anchor_pad_size[0]# + 1.0\n    bounding_box = {\n        'top': -ctyd_width/2,\n        'bottom': ctyd_width/2,\n        'left': odd_pad_x - odd_pad_size[0]/2,\n        'right': bar_down_edge\n    }\n\n    fab_outline = [\n        {'x': body_edge['left'], 'y':0},\n        {'x': body_edge['left'], 'y':body_edge['bottom']},\n        {'x': anchor_pad_x - gab_anchor_L/2, 'y':body_edge['bottom']},\n        {'x': anchor_pad_x - gab_anchor_L/2, 'y':body_edge['bottom'] - gab_anchor_W},\n        {'x': anchor_pad_x + gab_anchor_L/2, 'y':body_edge['bottom'] - gab_anchor_W},\n        {'x': anchor_pad_x + gab_anchor_L/2, 'y':body_edge['bottom']},\n        {'x': body_edge['right'] + TL, 'y':body_edge['bottom']},\n        {'x': body_edge['right'] + TL, 'y':body_edge['bottom']-TW},\n        {'x': body_edge['right'], 'y':body_edge['bottom']-TW},\n        {'x': body_edge['right'], 'y':0}\n    ]\n\n    kicad_mod.append(PolygoneLine(\n        polygone=fab_outline,\n        layer=\"F.Fab\", width=configuration['fab_line_width']\n    ))\n    kicad_mod.append(PolygoneLine(\n        polygone=fab_outline, y_mirror=0,\n        layer=\"F.Fab\", width=configuration['fab_line_width']\n    ))\n\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': body_edge['right'], 'y': -bar_width/2},\n            {'x': bar_down_edge, 'y': -bar_width/2},\n            {'x': bar_down_edge, 'y': bar_width/2},\n            {'x': body_edge['right'], 'y': bar_width/2}\n        ],\n        layer=\"F.Fab\", width=configuration['fab_line_width']\n    ))\n\n    odd_pins_outside = pins_width/2 + odd_pad_size[0]/2 + pad_silk_off\n    silk_outline = [\n        {'x': body_edge['left']-off, 'y':odd_pins_outside},\n        {'x': body_edge['left']-off, 'y':body_edge['bottom']+off},\n        {'x': body_edge['right'] + TL + off, 'y':body_edge['bottom']+off},\n        {'x': body_edge['right'] + TL + off, 'y':body_edge['bottom']-TW - off},\n        {'x': body_edge['right'] + off, 'y':body_edge['bottom']-TW - off},\n        {'x': body_edge['right'] + off, 'y': bar_width/2 + off},\n        {'x': bar_down_edge + off, 'y': bar_width/2 + off},\n        {'x': bar_down_edge + off, 'y': 0}\n    ]\n    kicad_mod.append(PolygoneLine(\n        polygone=silk_outline,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']\n    ))\n    kicad_mod.append(PolygoneLine(\n        polygone=silk_outline, y_mirror=0,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']\n    ))\n\n    even_pins = pin_count//2\n    odd_pins = pin_count - even_pins\n    kicad_mod.append(PadArray(\n            center=[odd_pad_x,0], pincount=odd_pins,\n            initial=1, increment=2, y_spacing=2*cable_pitch,\n            type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n            size=odd_pad_size, layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(\n            center=[even_pad_x, 0], pincount=even_pins,\n            initial=2, increment=2, y_spacing=2*cable_pitch,\n            type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n            size=even_pad_size, layers=Pad.LAYERS_SMT))\n\n\n    def anchor_pad(direction):\n        # f.write(\"  (pad \\\"\\\" smd rect (at {x:1.5g} {y:1.5g}) \"\n        #     \"(size {pad_size[0]} {pad_size[1]}) \"\n        #     \"(layers F.Cu F.Paste F.Mask))\\n\".format(\n        #             x=anchor_pad_spacing / 2 * direction,\n        #             y=0.325 - row_spacing/2 + y_offset,\n        #             pad_size=anchor_pad_size))\n        kicad_mod.append(Pad(number=configuration['mounting_pad_number'], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                        at=[anchor_pad_x, anchor_pad_spacing / 2 * direction],\n                        size=anchor_pad_size, layers=Pad.LAYERS_SMT))\n    anchor_pad(-1)\n    anchor_pad(1)\n\n    pin1_y = -pins_width/2\n    ps1_m = 0.3\n    p1s_x = bounding_box['left'] - pad_silk_off\n    pin = [\n        {'x': p1s_x -  ps1_m/sqrt(2), 'y': pin1_y-ps1_m/2},\n        {'x': p1s_x, 'y': pin1_y},\n        {'x': p1s_x -  ps1_m/sqrt(2), 'y': pin1_y+ps1_m/2},\n        {'x': p1s_x -  ps1_m/sqrt(2), 'y': pin1_y-ps1_m/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    sl=0.6\n    pin = [\n        {'x': body_edge['left'], 'y': pin1_y-sl/2},\n        {'x': body_edge['left'] + sl/sqrt(2), 'y': pin1_y},\n        {'x': body_edge['left'], 'y': pin1_y+sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='right')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    if lib_by_conn_category:\n        lib_name = configuration['lib_name_specific_function_format_string'].format(category=conn_category)\n    else:\n        lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for pincount in pinrange:\n        make_module(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_SPOX_tht_side.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"SPOX\"\nseries_long = 'SPOX Connector System'\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'https://www.molex.com/pdm_docs/sd/022057045_sd.pdf'\n\n#pins_per_row per row\npins_per_row_range = range(2, 16)\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"5268-{n:02}A\"\n\npitch = 2.5\ndrill = 0.85\n\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2 * max_annular_ring]\nif pad_size[0] - drill < 2 * min_annular_ring:\n    pad_size[0] = drill + 2 * min_annular_ring\nif pad_size[0] - drill > 2 * max_annular_ring:\n    pad_size[0] = drill + 2 * max_annular_ring\n\npad_shape = Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\ndef generate_one_footprint(pins_per_row, configuration):\n    mpn = part_code.format(n = pins_per_row * number_of_rows)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man = manufacturer,\n        series = series,\n        mpn = mpn, num_rows = number_of_rows, pins_per_row = pins_per_row, mounting_pad = \"\",\n        pitch = pitch, orientation = orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series = series,\n        orientation = orientation_str, man = manufacturer,\n        entry = configuration['entry_direction'][orientation]))\n\n    A = (pins_per_row - 1) * pitch\n    C = A + 2 * 2.45\n\n    #connector width\n    W = 7.9\n    chamfer_pin_n = {'x': 1, 'y': 1}\n\n    off = configuration['silk_fab_offset']\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width'] / 2\n\n    body_edge = {}\n    body_edge['left'] = (A - C) / 2\n    body_edge['right'] = body_edge['left'] + C\n    body_edge['top'] = -(7.9 - 6.6)\n    body_edge['bottom'] = body_edge['top'] + W\n\n    bounding_box = body_edge.copy()\n\n    # generate the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(start = [0, 0], pincount = pins_per_row, x_spacing = pitch,\n        type = Pad.TYPE_THT, shape = pad_shape, size = pad_size, drill = drill,\n        layers = Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    def generateOutline(off = 0, grid = 0):\n        poly = [\n                {'x': body_edge['left'] - off, 'y': body_edge['top'] - off},\n                {'x': body_edge['left'] - off, 'y': body_edge['bottom'] + off},\n                {'x': body_edge['right']+off, 'y':body_edge['bottom'] +off},\n                {'x': body_edge['right'] + off, 'y': body_edge['top'] - off},\n                {'x': body_edge['left'] - off, 'y': body_edge['top'] - off},\n            ]\n        if grid == 0:\n            return poly\n        else:\n            return [{'x': roundToBase(p['x'], grid), 'y': roundToBase(p['y'], grid)} for p in poly]\n\n    # outline on Fab\n    kicad_mod.append(PolygoneLine(polygone = generateOutline(),\n        layer = 'F.Fab', width = configuration['fab_line_width']))\n\n    # outline on SilkScreen\n    kicad_mod.append(PolygoneLine(polygone = generateOutline(off = off),\n        layer = 'F.SilkS', width = configuration['silk_line_width']))\n\n    #pin-1 mark\n    sl = 2\n    o = off + 0.3\n    pin = [\n        {'y': body_edge['top'] + sl, 'x': body_edge['left'] - o},\n        {'y': body_edge['top'] - o, 'x': body_edge['left'] - o},\n        {'y': body_edge['top'] - o, 'x': body_edge['left'] + sl}\n    ]\n    kicad_mod.append(PolygoneLine(polygone = pin,\n        layer = 'F.SilkS', width = configuration['silk_line_width']))\n\n    sl = 1\n    pin = [\n        {'y': sl / 2, 'x': body_edge['left']},\n        {'y': 0, 'x': body_edge['left'] + sl / sqrt(2)},\n        {'y': -sl / 2, 'x': body_edge['left']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone = pin,\n        width = configuration['fab_line_width'], layer = 'F.Fab'))\n\n    ########################### CrtYd #################################\n    poly_crtyd = generateOutline(configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = poly_crtyd[0]['y']\n    cy2 = poly_crtyd[1]['y']\n    kicad_mod.append(PolygoneLine(\n        polygone = poly_crtyd,\n        layer = 'F.CrtYd', width = configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod = kicad_mod, configuration = configuration, body_edges = body_edge,\n        courtyard = {'top': cy1, 'bottom': cy2},\n        fp_name = footprint_name, text_y_inside_position = 'bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix', '${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series = series, man = manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix = model3d_path_prefix, lib_name = lib_name, fp_name = footprint_name)\n    kicad_mod.append(Model(filename = model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name = lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir = output_dir, fp_name = footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_SPOX_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"SPOX\"\nseries_long = 'SPOX Connector System'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.molex.com/pdm_docs/sd/022035035_sd.pdf'\n\n#pins_per_row per row\npins_per_row_range = range(2,16)\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"5267-{n:02}A\"\n\npitch = 2.5\ndrill = 0.85\n\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\n\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\n\n\ndef generate_one_footprint(pins_per_row, configuration):\n    mpn = part_code.format(n=pins_per_row*number_of_rows)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    A = (pins_per_row - 1) * pitch\n    B = A + 2*1.75\n    C = A + 2*2.45\n\n    #connector width\n    W = 4.9\n    chamfer_pin_n = {'x': 1, 'y': 1}\n\n    off = configuration['silk_fab_offset']\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    body_edge={}\n    body_edge['left'] = (A - C) / 2\n    body_edge['right'] = body_edge['left'] + C\n    body_edge['top'] = -3.1\n    body_edge['bottom'] = body_edge['top'] + W\n\n    bounding_box = body_edge.copy()\n\n    # generate the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(start=[0,0], pincount=pins_per_row, x_spacing=pitch,\n        type=Pad.TYPE_THT, shape=pad_shape, size=pad_size, drill=drill,\n        layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    def generateOutline(off = 0, grid = 0):\n        poly = [\n                {'x': body_edge['left']-off, 'y':body_edge['top']-off},\n                {'x': body_edge['left']-off, 'y':body_edge['bottom']+off},\n                {'x': body_edge['right']-chamfer_pin_n['x']+off, 'y':body_edge['bottom']+off},\n                {'x': body_edge['right']+off, 'y':body_edge['bottom']-chamfer_pin_n['y']+off},\n                {'x': body_edge['right']+off, 'y':body_edge['top']-off},\n                {'x': body_edge['left']-off, 'y':body_edge['top']-off},\n            ]\n        if grid == 0:\n            return poly\n        else:\n            return [{'x':roundToBase(p['x'], grid), 'y':roundToBase(p['y'], grid)} for p in poly]\n\n    # outline on Fab\n    kicad_mod.append(PolygoneLine(polygone=generateOutline(),\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    # outline on SilkScreen\n    kicad_mod.append(PolygoneLine(polygone=generateOutline(off=off),\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #pin-1 mark\n    sl=2\n    o = off + 0.3\n    pin = [\n        {'y': body_edge['bottom'] - sl, 'x': body_edge['left'] - o},\n        {'y': body_edge['bottom'] + o, 'x': body_edge['left'] - o},\n        {'y': body_edge['bottom'] + o, 'x': body_edge['left'] + sl}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    sl=1\n    pin = [\n        {'y': body_edge['bottom'], 'x': -sl/2},\n        {'y': body_edge['bottom'] - sl/sqrt(2), 'x': 0},\n        {'y': body_edge['bottom'], 'x': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    poly_crtyd = generateOutline(configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = poly_crtyd[0]['y']\n    cy2 = poly_crtyd[1]['y']\n    kicad_mod.append(PolygoneLine(\n        polygone=poly_crtyd,\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2},\n        fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_kk_254_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"KK-254\"\nseries_long = 'KK-254 Interconnect System'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.molex.com/pdm_docs/sd/022272021_sd.pdf'\n\npitch = 2.54\ndrill = 1.19 # from datasheet\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\neng_mpn = 'AE-6410-{n:02d}A'\nnew_mpn_example = '22-27-2{n:02d}1'\n\ndef generate_one_footprint(pincount, configuration):\n\n    mpn = eng_mpn.format(n=pincount)\n    new_mpn = new_mpn_example.format(n=pincount)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    descr_format_str = \"Molex {:s}, old/engineering part number: {:s} example for new part number: {:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(descr_format_str.format(series_long, mpn, new_mpn, pincount, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    # calculate working values\n    end_pos_x = (pincount-1) * pitch\n    centre_x = (end_pos_x - start_pos_x) / 2.0\n    nudge = configuration['silk_fab_offset']\n    silk_w = configuration['silk_line_width']\n    fab_w = configuration['fab_line_width']\n\n\n    body_edge={\n        'left':start_pos_x - pitch/2,\n        'right':end_pos_x + pitch/2,\n        'bottom':1.88+1\n        }\n    body_edge['top'] = body_edge['bottom']-5.8\n\n    # create pads\n    # kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n    #                     at=[0, 0], size=pad_size,\n    #                     drill=drill, layers=Pad.LAYERS_THT))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[start_pos_x, 0],\n        x_spacing=pitch, pincount=pincount,\n        size=pad_size, drill=drill,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    # create fab outline\n    kicad_mod.append(RectLine(start=[body_edge['left'], body_edge['top']],\\\n        end=[body_edge['right'], body_edge['bottom']], layer='F.Fab', width=fab_w))\n\n    # create silkscreen\n    kicad_mod.append(RectLine(start=[body_edge['left']-nudge, body_edge['top']-nudge],\\\n        end=[body_edge['right']+nudge, body_edge['bottom']+nudge], layer='F.SilkS', width=silk_w))\n\n    # pin 1 markers\n    kicad_mod.append(Line(start=[body_edge['left']-0.4, -2.0],\\\n        end=[body_edge['left']-0.4, 2.0], layer='F.SilkS', width=silk_w))\n\n    sl=1\n    poly_pin1_marker = [\n        {'x': body_edge['left'], 'y': -sl/2},\n        {'x': body_edge['left'] + sl/sqrt(2), 'y': 0},\n        {'x': body_edge['left'], 'y': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.Fab', width=fab_w))\n\n    yr1=body_edge['bottom']+nudge\n    yr2 = yr1 - 1\n    yr3 = yr2 - 0.53\n    if pincount <= 6:\n        # one ramp\n        kicad_mod.append(PolygoneLine(polygone=[[start_pos_x, yr1], [start_pos_x, yr2],\\\n            [end_pos_x, yr2], [end_pos_x, yr1]], layer='F.SilkS', width=silk_w))\n        kicad_mod.append(PolygoneLine(polygone=[[start_pos_x, yr2], [start_pos_x+0.25, yr3],\\\n            [end_pos_x-0.25, yr3], [end_pos_x, yr2] ],layer='F.SilkS', width=silk_w))\n        kicad_mod.append(PolygoneLine(polygone=[[start_pos_x+0.25, yr1],\\\n            [start_pos_x+0.25, yr2]], layer='F.SilkS', width=silk_w))\n        kicad_mod.append(PolygoneLine(polygone=[[end_pos_x-0.25, yr1],\\\n            [end_pos_x-0.25, yr2]], layer='F.SilkS', width=silk_w))\n\n    else:\n        # two ramps\n        poly1=[\n            {'x': start_pos_x, 'y': yr1},\n            {'x': start_pos_x, 'y': yr2},\n            {'x': start_pos_x+2*pitch, 'y': yr2},\n            {'x': start_pos_x+2*pitch, 'y': yr1}\n        ]\n        poly2=[\n            {'x': start_pos_x, 'y': yr2},\n            {'x': start_pos_x+0.25, 'y': yr3},\n            {'x': start_pos_x+2*pitch, 'y': yr3},\n            {'x': start_pos_x+2*pitch, 'y': yr2}\n        ]\n        poly3=[\n            {'x': start_pos_x+0.25, 'y': yr1},\n            {'x': start_pos_x+0.25, 'y': yr2}\n        ]\n\n        kicad_mod.append(PolygoneLine(polygone=poly1, layer='F.SilkS', width=silk_w))\n        kicad_mod.append(PolygoneLine(polygone=poly2, layer='F.SilkS', width=silk_w))\n        kicad_mod.append(PolygoneLine(polygone=poly3, layer='F.SilkS', width=silk_w))\n\n        kicad_mod.append(PolygoneLine(polygone=poly1, x_mirror=centre_x, layer='F.SilkS', width=silk_w))\n        kicad_mod.append(PolygoneLine(polygone=poly2, x_mirror=centre_x, layer='F.SilkS', width=silk_w))\n        kicad_mod.append(PolygoneLine(polygone=poly3, x_mirror=centre_x, layer='F.SilkS', width=silk_w))\n\n    for i in range(0, pincount):\n        middle_x = start_pos_x + i * pitch\n        start_x = middle_x - 1.6/2\n        end_x = middle_x + 1.6/2\n        y1 = body_edge['top'] - nudge\n        y2 = y1 + 0.6\n        kicad_mod.append(PolygoneLine(polygone=[[start_x, y1], [start_x, y2],\\\n            [end_x, y2], [end_x, y1]], layer='F.SilkS', width=silk_w))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(body_edge['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(body_edge['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(body_edge['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(body_edge['bottom']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in range(2, 17):\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_kk_396_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"KK-396\"\nseries_long = 'KK 396 Interconnect System'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'https://www.molex.com/pdm_docs/sd/026604020_sd.pdf'\n\npitch = 3.96\ndrill = 1.7\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 0.8\nmax_annular_ring = 1.2 # How much copper should be in y direction?\nmin_annular_ring = 0.3\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\neng_mpn = 'A-41791-00{n:02d}'\nnew_mpn_example = '26-60-4{n:02d}0'\n\ndef generate_one_footprint(pincount, configuration):\n\n    mpn = eng_mpn.format(n=pincount)\n    new_mpn = new_mpn_example.format(n=pincount)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    descr_format_str = \"Molex {:s}, old/engineering part number: {:s} example for new part number: {:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(descr_format_str.format(series_long, mpn, new_mpn, pincount, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    # calculate working values\n    end_pos_x = (pincount-1) * pitch\n    centre_x = (end_pos_x - start_pos_x) / 2.0\n    nudge = configuration['silk_fab_offset']\n    silk_w = configuration['silk_line_width']\n    fab_w = configuration['fab_line_width']\n\n\n    body_edge={\n        'left':start_pos_x - 1.91,\n        'right':end_pos_x + 1.91,\n        'top':-5.11\n        }\n    body_edge['bottom'] = body_edge['top']+10.01\n\n    # create pads\n    # kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n    #                     at=[0, 0], size=pad_size,\n    #                     drill=drill, layers=Pad.LAYERS_THT))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[start_pos_x, 0],\n        x_spacing=pitch, pincount=pincount,\n        size=pad_size, drill=drill,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    offset_ramp_x = 1.905\n    offset_ramp_y = 1.005\n\n    # create fab outline\n    kicad_mod.append(PolygoneLine(polygone=[\n        [body_edge['left'], body_edge['top']],\\\n        [body_edge['right'], body_edge['top']],\\\n        [body_edge['right'], body_edge['bottom'] - offset_ramp_y],\\\n        [body_edge['right'] - offset_ramp_x, body_edge['bottom'] - offset_ramp_y],\\\n        [body_edge['right'] - offset_ramp_x, body_edge['bottom']],\\\n        [body_edge['left'] + offset_ramp_x, body_edge['bottom']],\\\n        [body_edge['left'] + offset_ramp_x, body_edge['bottom'] - offset_ramp_y],\\\n        [body_edge['left'], body_edge['bottom'] - offset_ramp_y],\\\n        [body_edge['left'], body_edge['top']]], layer='F.Fab', width=fab_w))\n\n    # create silkscreen\n    kicad_mod.append(PolygoneLine(polygone=[\n        [body_edge['left'] - nudge, body_edge['top'] - nudge],\\\n        [body_edge['right'] + nudge, body_edge['top'] - nudge],\\\n        [body_edge['right'] + nudge, body_edge['bottom'] + nudge - offset_ramp_y],\\\n        [body_edge['right'] + nudge - offset_ramp_x, body_edge['bottom'] + nudge - offset_ramp_y],\\\n        [body_edge['right'] + nudge - offset_ramp_x, body_edge['bottom'] + nudge],\\\n        [body_edge['left'] - nudge + offset_ramp_x, body_edge['bottom'] + nudge],\\\n        [body_edge['left'] - nudge + offset_ramp_x, body_edge['bottom'] + nudge - offset_ramp_y],\\\n        [body_edge['left'] - nudge, body_edge['bottom'] + nudge - offset_ramp_y],\\\n        [body_edge['left'] - nudge, body_edge['top'] - nudge]], layer='F.SilkS',\n        width=silk_w))\n\n    # pin 1 markers\n    kicad_mod.append(Line(start=[body_edge['left']-0.4, -2.0],\\\n        end=[body_edge['left']-0.4, 2.0], layer='F.SilkS', width=silk_w))\n\n    sl=1\n    poly_pin1_marker = [\n        {'x': body_edge['left'], 'y': -sl/2},\n        {'x': body_edge['left'] + sl/sqrt(2), 'y': 0},\n        {'x': body_edge['left'], 'y': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.Fab', width=fab_w))\n\n    yr1=body_edge['bottom']+nudge\n    yr2 = yr1 - 1.0\n    yr3 = yr2 - 1.67\n\n    ramps_pin_map = {\n        2: [[1, 2]],\n        3: [[1, 3]],\n        4: [[1, 4]],\n        5: [[1, 5]],\n        6: [[1, 3], [4, 6]],\n        7: [[1, 4], [5, 7]],\n        8: [[1, 4], [5, 8]],\n        9: [[1, 5], [6, 9]],\n        10: [[1, 5], [6, 10]],\n        11: [[1, 6], [7, 11]],\n        12: [[1, 4], [5, 8], [9, 12]],\n        13: [[1, 4], [5, 9], [10, 13]],\n        14: [[1, 5], [6, 9], [10, 14]],\n        15: [[1, 5], [6, 10], [11, 15]],\n        16: [[1, 5], [6, 11], [12, 16]],\n        17: [[1, 6], [7, 11], [12, 17]],\n        18: [[1, 6], [7, 12], [13, 18]],\n    }\n\n    for ramp in ramps_pin_map[pincount]:\n        ramp_start_x = start_pos_x + (ramp[0] - 1) * pitch\n        if ramp[0] != 1:\n            ramp_start_x -= 1.5\n        ramp_end_x = start_pos_x + (ramp[1] - 1) * pitch\n        if ramp[1] != pincount:\n            ramp_end_x += 1.5\n        kicad_mod.append(PolygoneLine(polygone=[\n            [ramp_start_x, yr1], [ramp_start_x, yr2],\\\n            [ramp_end_x, yr2], [ramp_end_x, yr1]],\\\n            layer='F.SilkS', width=silk_w))\n        kicad_mod.append(PolygoneLine(polygone=[\n            [ramp_start_x, yr2], [ramp_start_x, yr3],\\\n            [ramp_end_x, yr3], [ramp_end_x, yr2]],\\\n            layer='F.SilkS', width=silk_w))\n\n    for i in range(0, pincount):\n        middle_x = start_pos_x + i * pitch\n        start_x = middle_x - 1.6/2\n        end_x = middle_x + 1.6/2\n        y1 = body_edge['top'] - nudge\n        y2 = y1 + 0.6\n        kicad_mod.append(PolygoneLine(polygone=[[start_x, y1], [start_x, y2],\\\n            [end_x, y2], [end_x, y1]], layer='F.SilkS', width=silk_w))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(body_edge['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(body_edge['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(body_edge['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(body_edge['bottom']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in range(2, 19):\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_mega-fit_tht_side_dual-row.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Mega-Fit\"\nseries_long = 'Mega-Fit Power Connectors'\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 2\ndatasheet = 'http://www.molex.com/pdm_docs/sd/1720640002_sd.pdf'\n\n#pins_per_row per row\npins_per_row_range = [1, 2, 3, 4, 5, 6]\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"76825-00{n:02d}\"\n\nalternative_codes = [\n\"172064-00{n:02d}\",\n\"172064-10{n:02d}\"\n]\n\npitch = 5.7\ndrill = 1.8\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 1.75\nmax_annular_ring = 0.95 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n\nrow = 5.5\n\nsize = row - pad_to_pad_clearance\nif size - drill < 2*min_annular_ring:\n    size = drill + 2*min_annular_ring\nif size - drill > max_annular_ring:\n    size = drill + 2*max_annular_ring\n\n\n\ndef generate_one_footprint(pins_per_row, configuration):\n    mpn = part_code.format(n=pins_per_row*2)\n    alt_mpn = [code.format(n=pins_per_row*2) for code in alternative_codes]\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s} (compatible alternatives: {:s}), {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, ', '.join(alt_mpn), pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n    #http://www.molex.com/pdm_docs/sd/768250010_sd.pdf\n\n    #connector length\n    if pins_per_row == 1:\n        A = 8.35\n    else:\n        A = pins_per_row * pitch + 0.65\n\n    if pins_per_row == 1 or pins_per_row == 2:\n        B = 0\n    else:\n        B = A - 6.35\n\n    #pin centers\n    P = (pins_per_row - 1) * pitch\n\n    #corner positions for plastic housing outline\n\n    x1 = -(A-P)/2\n    x2 = x1 + A\n\n    y2 = -1.1\n    y1 = y2 - 14.8\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n\n    #generate the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            pincount=pins_per_row, initial=row_idx*pins_per_row+1,\n            start=[0, row_idx*row], x_spacing=pitch, type=Pad.TYPE_THT,\n            shape=Pad.SHAPE_CIRCLE, size=size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    off = configuration['silk_fab_offset']\n    silk_pad_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    #add PCB locators\n    r_loc = 3.00\n    y_loc = -7.3\n\n    #two locators\n    if pins_per_row > 2:\n        lx1 = P/2 - B/2\n        lx2 = P/2 + B/2\n\n        kicad_mod.append(Pad(at=[lx1, y_loc],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=r_loc,drill=r_loc, layers=Pad.LAYERS_NPTH))\n        kicad_mod.append(Pad(at=[lx2, y_loc],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=r_loc,drill=r_loc, layers=Pad.LAYERS_NPTH))\n\n        kicad_mod.append(Circle(center=[lx1, y_loc],radius=r_loc/2+silk_pad_off, layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Circle(center=[lx2, y_loc],radius=r_loc/2+silk_pad_off, layer='F.SilkS', width=configuration['silk_line_width']))\n    else:\n        #one locator\n        kicad_mod.append(Pad(at=[P/2,y_loc],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=r_loc, drill=r_loc, layers=Pad.LAYERS_NPTH))\n\n        kicad_mod.append(Circle(center=[P/2,y_loc], radius=r_loc/2+silk_pad_off, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #draw the outline of the shape\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2], layer='F.Fab', width=configuration['fab_line_width']))\n\n    outline = [\n    {'x': P/2,'y': y1-off},\n    {'x': x1-off,'y': y1-off},\n    {'x': x1-off,'y': y2+off},\n    {'x': -size/2 - silk_pad_off,'y': y2+off},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=outline, layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=outline,x_mirror=P/2 if P != 0 else 0.00000001, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #draw lines between each pin\n    for i in range(pins_per_row-1):\n        xa = i * pitch + size / 2 + silk_pad_off\n        xb = (i+1) * pitch - size / 2 - silk_pad_off\n\n        kicad_mod.append(Line(start=[xa,y2+off],end=[xb,y2+off], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #draw the pins!\n\n    o = size/2 + silk_pad_off\n    w = 0.3\n    for i in range(pins_per_row):\n        x = i * pitch\n        ya = o\n        yb = row - o\n        kicad_mod.append(Line(start=[x-w,ya],end=[x-w,yb], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[x+w,ya],end=[x+w,yb], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #pin-1 marker\n    x =  -2.5\n    m = 0.3\n\n    pin = [\n    {'x': x,'y': 0},\n    {'x': x-2*m,'y': +m},\n    {'x': x-2*m,'y': -m},\n    {'x': x,'y': 0},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    sl = 2\n    pin = [\n        {'x': -sl/2, 'y': body_edge['bottom']},\n        {'x': 0, 'y': body_edge['bottom']-sl/sqrt(2)},\n        {'x': sl/2, 'y': body_edge['bottom']},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin, width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(body_edge['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(body_edge['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(body_edge['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(row + size/2 + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_mega-fit_tht_top_dual_row.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\ndraw_inner_details = False\n\nseries = \"Mega-Fit\"\nseries_long = 'Mega-Fit Power Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\n\n\n#pins_per_row_per_row per row\npins_per_row_range = [1, 2, 3, 4, 5, 6]\n\n#Molex part number\n#n = number of circuits per row\nvariant_params = {\n    'boss':{\n        'mount_pins': False,\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/768290102_sd.pdf',\n        'part_code': \"76829-01{n:02d}\",\n        'alternative_codes': [\n            \"172065-02{n:02d}\",\n            \"172065-03{n:02d}\"\n            ]\n        },\n    'mount_pins':{\n        'mount_pins': True,\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/768290004_sd.pdf',\n        'part_code': \"76829-00{n:02d}\",\n        'alternative_codes': [\n            \"172065-00{n:02d}\",\n            \"172065-10{n:02d}\"\n            ]\n        }\n}\n\npitch = 5.7\ndrill = 1.8\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 1.75\nmax_annular_ring = 0.95 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n\nrow = 5.7\n\nsize = row - pad_to_pad_clearance\nif size - drill < 2*min_annular_ring:\n    size = drill + 2*min_annular_ring\nif size - drill > 2*max_annular_ring:\n    size = drill + 2*max_annular_ring\n\n\n\ndef generate_one_footprint(pins_per_row, variant, configuration):\n    mpn = variant_params[variant]['part_code'].format(n=pins_per_row*2)\n    alt_mpn = [code.format(n=pins_per_row*2) for code in variant_params[variant]['alternative_codes']]\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s} (compatible alternatives: {:s}), {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, ', '.join(alt_mpn), pins_per_row, variant_params[variant]['datasheet']))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n\n    #connector length\n    if pins_per_row == 1:\n        A = 8.35\n    else:\n        A = pins_per_row * pitch + 0.65\n\n    B = A + 7.04\n\n    #pin centers\n    P = (pins_per_row - 1) * pitch\n\n    #plasic pin-lock centre-distance\n    C = A + 3.99\n    #print('A: {}, B: {}, C: {}'.format(A,B,C))\n    #connector width\n    W = 12.48\n\n    #corner positions\n    x1 = -(A-P)/2\n    x2 = x1 + A\n\n    y2 = 3.47 + row\n    y1 = y2 -W\n\n    #tab length\n    tab_l = 3.4\n    #tab width\n    tab_w = 1.55\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n    bounding_box['bottom'] = y2 + tab_w\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    #generate the pads\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            pincount=pins_per_row, initial=row_idx*pins_per_row+1,\n            start=[0, row_idx*row], x_spacing=pitch, type=Pad.TYPE_THT,\n            shape=Pad.SHAPE_CIRCLE, size=size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    off = configuration['silk_fab_offset']\n    silk_pad_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    if variant_params[variant]['mount_pins']:\n        #add PCB locators\n        loc = 3.00\n        offset = -0.325\n\n        lx1 = P/2 - C/2\n        lx2 = P/2 + C/2\n\n        mounting_pin_y = row - offset\n\n        kicad_mod.append(Pad(at=[lx1, mounting_pin_y],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=loc,drill=loc, layers=Pad.LAYERS_NPTH))\n        kicad_mod.append(Pad(at=[lx2, mounting_pin_y],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=loc,drill=loc, layers=Pad.LAYERS_NPTH))\n\n        #draw outline around the PCB locators\n        #arc distance from pin\n        mount_pin_radius = (B/2 - C/2)\n        bounding_box['left'] = P/2 - B/2\n        bounding_box['right'] = P/2 + B/2\n\n        ######################## Fab ############################\n\n        kicad_mod.append(Arc(center=[lx1,mounting_pin_y],\n            start=[lx1,mounting_pin_y+mount_pin_radius], angle=180,\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n        kicad_mod.append(Line(start=[lx1,mounting_pin_y-mount_pin_radius],\n            end=[x1,mounting_pin_y-mount_pin_radius],\n            layer='F.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(Line(start=[lx1,mounting_pin_y+mount_pin_radius],\n            end=[x1,mounting_pin_y+mount_pin_radius],\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n\n        kicad_mod.append(Arc(center=[lx2,mounting_pin_y],\n            start=[lx2,mounting_pin_y-mount_pin_radius], angle=180,\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n        kicad_mod.append(Line(start=[lx2,mounting_pin_y-mount_pin_radius],\n            end=[x2,mounting_pin_y-mount_pin_radius],\n            layer='F.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(Line(start=[lx2,mounting_pin_y+mount_pin_radius],\n            end=[x2,mounting_pin_y+mount_pin_radius],\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n        ######################## Silk ############################\n        mount_pin_radius = loc/2 + silk_pad_off\n        kicad_mod.append(Arc(center=[lx1,mounting_pin_y],\n            start=[lx1,mounting_pin_y+mount_pin_radius], angle=180,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Line(start=[lx1,mounting_pin_y-mount_pin_radius],\n            end=[x1-off,mounting_pin_y-mount_pin_radius],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[lx1,mounting_pin_y+mount_pin_radius],\n            end=[x1-off,mounting_pin_y+mount_pin_radius],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n        kicad_mod.append(Arc(center=[lx2,mounting_pin_y],\n            start=[lx2,mounting_pin_y-mount_pin_radius], angle=180,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Line(start=[lx2,mounting_pin_y-mount_pin_radius],\n            end=[x2+off,mounting_pin_y-mount_pin_radius],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[lx2,mounting_pin_y+mount_pin_radius],\n            end=[x2+off,mounting_pin_y+mount_pin_radius],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n    else:\n        #add PCB locators\n        boss_drill = 1.8\n\n        boss_x = (pins_per_row-1) * pitch + (3.48 if pins_per_row == 1 else 2.48)\n        boss_y = row + 2.77\n\n        kicad_mod.append(Pad(at=[boss_x, boss_y],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n            size=boss_drill, drill=boss_drill, layers=Pad.LAYERS_NPTH))\n\n    #draw the outline of the shape\n    p1m_sl = 1\n    kicad_mod.append(PolygoneLine(polygone=[\n            {'x': body_edge['left'] + p1m_sl, 'y': body_edge['top']},\n            {'x': body_edge['left'], 'y': body_edge['top'] +p1m_sl},\n            {'x': body_edge['left'], 'y': body_edge['bottom']},\n            {'x': body_edge['right'], 'y': body_edge['bottom']},\n            {'x': body_edge['right'], 'y': body_edge['top']},\n            {'x': body_edge['left'] + p1m_sl, 'y': body_edge['top']}\n        ],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    #draw the outline of the tab\n    kicad_mod.append(PolygoneLine(polygone=[\n        {'x': P/2 - tab_l/2,'y': y2},\n        {'x': P/2 - tab_l/2,'y': y2 + tab_w},\n        {'x': P/2 + tab_l/2,'y': y2 + tab_w},\n        {'x': P/2 + tab_l/2,'y': y2},\n    ], layer='F.Fab', width=configuration['fab_line_width']))\n\n\n    #draw the outline of the connector on the silkscreen\n\n    outline = [\n    {'x': P/2,'y': y1-off},\n    {'x': x1-off,'y': y1-off},\n    {'x': x1-off,'y': y2+off},\n    {'x': P/2 - tab_l/2 - off,'y': y2+off},\n    {'x': P/2 - tab_l/2 - off,'y': y2 + off + tab_w},\n    {'x': P/2, 'y': y2 + off + tab_w},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=outline,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    if variant_params[variant]['mount_pins']:\n        kicad_mod.append(PolygoneLine(polygone=outline, x_mirror=P/2,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n    else:\n        outline1 = outline[:2]\n        outline1.append({'x': outline[2]['x'], 'y': boss_y - boss_drill/2 - silk_pad_off})\n        kicad_mod.append(PolygoneLine(polygone=outline1, x_mirror=P/2,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n        outline2 = outline[2:]\n        outline2[0]['x'] = P - boss_x + boss_drill/2 + silk_pad_off # outline contains the mirrored version\n        kicad_mod.append(PolygoneLine(polygone=outline2, x_mirror=P/2,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n    #draw square around each pin\n    if draw_inner_details:\n        for i in range(pins_per_row):\n            for j in range(2):\n                x = i * pitch\n                y = j * row\n                s = 0.4 * pitch\n                kicad_mod.append(RectLine(start=[x-s,y-s],end=[x+s,y+s], layer='F.Fab', width=configuration['fab_line_width']))\n\n    #pin-1 marker\n    p1m_off = 0.3 + off\n    p1m_sl = 2\n    pin = [\n        {'x': body_edge['left'] - p1m_off,'y': body_edge['top'] + p1m_sl},\n        {'x': body_edge['left'] - p1m_off,'y': body_edge['top'] - p1m_off},\n        {'x': body_edge['left'] + p1m_sl,'y': body_edge['top'] - p1m_off},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    if variant_params[variant]['mount_pins']:\n        cx3 = roundToBase(body_edge['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n        cx4 = roundToBase(body_edge['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n        mount_pin_radius = (B/2 - C/2)\n        cy3=roundToBase(mounting_pin_y - mount_pin_radius - configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n        poly_crtyd = [\n            {'x': cx3, 'y': cy1},\n            {'x': cx3, 'y': cy3},\n            {'x': cx1, 'y': cy3},\n            {'x': cx1, 'y': cy2},\n            {'x': cx2, 'y': cy2},\n            {'x': cx2, 'y': cy3},\n            {'x': cx4, 'y': cy3},\n            {'x': cx4, 'y': cy1},\n            {'x': cx3, 'y': cy1}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_crtyd,\n            layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    else:\n        kicad_mod.append(RectLine(\n            start=[cx1, cy1], end=[cx2, cy2],\n            layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_micro-clasp_tht_side.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\ndraw_inner_details = False\n\nseries = \"MicroClasp\"\nseries_long = 'MicroClasp Wire-to-Board System'\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 1\n\n\n#pins_per_row_per_row per row\npins_per_row_range = range(2,16)\n\n#Molex part number\n#n = number of circuits per row\n#with boss, suffix = 10\n#no boss, suffix = 30\npart = \"55935-{n:02}{boss}\"\nvariant_params = {\n    'no_boss':{\n        'boss': False,\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/559350530_sd.pdf',\n        'part_code': \"55935-{n:02}30\",\n        },\n    'boss':{\n        'boss': True,\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/559350210_sd.pdf',\n        'part_code': \"55935-{n:02}10\",\n        }\n}\n\npitch = 2\ndrill = 0.8\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\n\n\ndef generate_one_footprint(pins, variant, configuration):\n    boss = variant_params[variant]['boss']\n    mpn = variant_params[variant]['part_code'].format(n=pins)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}{:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\".format(series_long,\n        mpn, \", with PCB locator\" if boss else '',\n        pins, variant_params[variant]['datasheet']))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n\n    #B = distance between end-point pins\n    B = (pins - 1) * pitch\n    #A = total connector length\n    A = B + 6\n    #C = internal length of connector\n    C = B + 3\n\n    #T = length of tab\n\n    if pins == 2:\n        T = 5\n    else:\n        T = 6.78\n\n    #corners\n    x1 = -(A-B) / 2\n    x2 = x1 + A\n\n    y2 = 9.2\n    y1 = y2 - 11.25\n\n    #y-pos of tab\n    yt = y1 + 11.75\n    xt = B/2 - T/2\n\n    #y-pos backside\n    yb = 0\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n    bounding_box['bottom']=yt\n    \n    silk_pad_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    \n    out = [\n    {'x': B/2, 'y': yt},\n    {'x': xt+(yt-y2), 'y': yt},\n    {'x': xt, 'y': y2},\n    {'x': x1, 'y': y2},\n    {'x': x1, 'y': y1},\n    {'x': (B-C)/2, 'y': y1},\n    {'x': (B-C)/2, 'y': yb},\n    {'x': B/2,'y': yb}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=out,\n        layer=\"F.Fab\", width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=out,x_mirror=B/2,\n        layer=\"F.Fab\", width=configuration['fab_line_width']))\n\n    #offset\n    o = configuration['silk_fab_offset']\n    x1 -= o\n    y1 -= o\n    x2 += o\n    y2 += o\n    yt += o\n    xt -= o\n\n    out = [\n    {'x': B/2, 'y': yt},\n    {'x': xt+(yt-y2), 'y': yt},\n    {'x': xt, 'y': y2},\n    {'x': x1, 'y': y2},\n    {'x': x1, 'y': y1},\n    {'x': (B-C)/2+o, 'y': y1},\n    {'x': (B-C)/2+o, 'y': yb-o},\n    {'x': -pad_size[0]/2-silk_pad_off,'y': yb-o}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=out,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=out,x_mirror=B/2,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    #draw silkscreen inbetween pads\n    for i in range(0,pins-1):\n        xa = i * pitch + pad_size[0] / 2 + silk_pad_off\n        xb = (i+1) * pitch - pad_size[0] / 2 - silk_pad_off\n\n        kicad_mod.append(Line(start=[xa,yb-o],end=[xb,yb-o], layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n    #generate the pads\n    kicad_mod.append(PadArray(\n        pincount=pins, x_spacing=pitch, type=Pad.TYPE_THT,\n        shape=pad_shape, size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    #add PCB locator if needed\n    if boss:\n        boss_x = B+2\n        boss_y = 2.4\n        boss_drill = 1.2\n        kicad_mod.append(Pad(at=[boss_x, boss_y], size=boss_drill, drill=boss_drill,\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_NPTH))\n        boss_x = -2\n        kicad_mod.append(Pad(at=[boss_x, boss_y], size=boss_drill, drill=boss_drill,\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_NPTH))\n\n    #pin-1 marker\n    y =  3.5\n    m = 0.3\n\n    p1m_sl = 2\n    p1m_off = o + 0.3\n    pin = [\n        {'x': body_edge['left'] - p1m_off,'y': body_edge['top']+p1m_sl},\n        {'x': body_edge['left'] - p1m_off,'y': body_edge['top']-p1m_off},\n        {'x': body_edge['left'] + p1m_sl,'y': body_edge['top']-p1m_off},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    p1m_sl = 1\n\n    pin = [\n        {'x': -p1m_sl/2,'y': 0},\n        {'x': 0,'y': 0 + p1m_sl/sqrt(2)},\n        {'x': p1m_sl/2,'y': 0},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        layer=\"F.Fab\", width=configuration['fab_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_micro-clasp_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\ndraw_inner_details = False\n\nseries = \"MicroClasp\"\nseries_long = 'MicroClasp Wire-to-Board System'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 1\n\n\n#pins_per_row_per_row per row\npins_per_row_range = range(2,16)\n\n#Molex part number\n#n = number of circuits per row\n#with boss, suffix = 10\n#no boss, suffix = 30\npart = \"55932-{n:02}{boss}\"\nvariant_params = {\n    'no_boss':{\n        'boss': False,\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/559320530_sd.pdf',\n        'part_code': \"55932-{n:02}30\",\n        },\n    'boss':{\n        'boss': True,\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/559320210_sd.pdf',\n        'part_code': \"55932-{n:02}10\",\n        }\n}\n\npitch = 2\ndrill = 0.8\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\n\n\ndef generate_one_footprint(pins, variant, configuration):\n    boss = variant_params[variant]['boss']\n    mpn = variant_params[variant]['part_code'].format(n=pins)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}{:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\".format(series_long,\n        mpn, \", with PCB locator\" if boss else '',\n        pins, variant_params[variant]['datasheet']))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n\n    #B = distance between end-point pins\n    B = (pins - 1) * pitch\n    #A = total connector length\n    A = B + 6\n    #C = internal length of connector\n    C = B + 3\n\n    #T = length of tab\n\n    if pins == 2:\n        T = 5\n    else:\n        T = 6.78\n\n    #wall-thickness w\n    w = 0.6\n\n    #corners\n    x1 = -(A-B) / 2\n    x2 = x1 + A\n\n    y2 = 3\n    y1 = y2 - (6.3 if pins == 2 else 5.8)\n\n    #y-pos of tab\n    yt = y2 - 6.7\n    xt = B/2 - T/2\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n    bounding_box['top']=yt\n\n    out = [\n    {'x': B/2, 'y': yt},\n    {'x': xt, 'y': yt},\n    {'x': xt, 'y': y1},\n    {'x': x1, 'y': y1},\n    {'x': x1, 'y': y2},\n    {'x': B/2, 'y': y2},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=out,\n        layer=\"F.Fab\", width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=out,x_mirror=B/2,\n        layer=\"F.Fab\", width=configuration['fab_line_width']))\n\n    #offset\n    o = configuration['silk_fab_offset']\n    x1 -= o\n    y1 -= o\n    x2 += o\n    y2 += o\n    yt -= o\n    xt -= o\n\n\n    out = [\n    {'x': B/2, 'y': yt},\n    {'x': xt, 'y': yt},\n    {'x': xt, 'y': y1},\n    {'x': x1, 'y': y1},\n    {'x': x1, 'y': y2},\n    {'x': B/2, 'y': y2},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=out,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=out,x_mirror=B/2,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    #generate the pads\n    kicad_mod.append(PadArray(\n        pincount=pins, x_spacing=pitch, type=Pad.TYPE_THT,\n        shape=pad_shape, size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    #add PCB locator if needed\n    if boss:\n        boss_x = B+2\n        boss_y = -1.9\n        boss_drill = 1.3\n        kicad_mod.append(Pad(at=[boss_x, boss_y], size=boss_drill, drill=boss_drill,\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_NPTH))\n\n\n    #draw the inner wall\n    # Inner details are incorrect. I could not be bothered to fix them.\n    # wall = [\n    # {'x': B/2, 'y': yt + 2*w},\n    # {'x': B/2 - pitch / 2, 'y': yt + 2*w},\n    # {'x': B/2 - pitch / 2, 'y': yt + w},\n    # {'x': B/2 - T/2 + w, 'y': yt + w},\n    # {'x': B/2 - T/2 + w, 'y': y1 + 2*w},\n    # {'x': -0.25, 'y': y1 + 2*w},\n    # {'x': -0.25, 'y': y1 + w},\n    # {'x': -(C-B)/2, 'y': y1 + w},\n    # {'x': -(C-B)/2, 'y': y2 - 3*w},\n    # {'x': x1+w, 'y': y2 - 3*w},\n    # {'x': x1+w, 'y': y2 - w},\n    # {'x': B/2, 'y': y2 - w},\n    # ]\n    #\n    # kicad_mod.append(PolygoneLine(polygone=wall,\n    #     layer=\"F.SilkS\", width=configuration['silk_line_width']))\n    # kicad_mod.append(PolygoneLine(polygone=wall, x_mirror=B/2,\n    #     layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    #pin-1 marker\n    y =  3.5\n    m = 0.3\n\n    p1m_sl = 2\n    p1m_off = o + 0.3\n    pin = [\n        {'x': body_edge['left'] - p1m_off,'y': body_edge['bottom']-p1m_sl},\n        {'x': body_edge['left'] - p1m_off,'y': body_edge['bottom']+p1m_off},\n        {'x': body_edge['left'] + p1m_sl,'y': body_edge['bottom']+p1m_off},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    p1m_sl = 1\n\n    pin = [\n        {'x': -p1m_sl/2,'y': body_edge['bottom']},\n        {'x': 0,'y': body_edge['bottom'] - p1m_sl/sqrt(2)},\n        {'x': p1m_sl/2,'y': body_edge['bottom']},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        layer=\"F.Fab\", width=configuration['fab_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_micro-fit-3.0_smd_side_dual_row.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Micro-Fit_3.0\"\nseries_long = 'Micro-Fit 3.0 Connector System'\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 2\ndatasheet = 'http://www.molex.com/pdm_docs/sd/430450210_sd.pdf'\n\n\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"43045-{n:02}10\"\n\nalternative_codes = [\n\"43045-{n:02}11\",\n\"43045-{n:02}09\"\n]\n\npitch = 3.0\npincount_range = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24]\n\nrow = 5.5\n\n\npad_size = [1.27, 2.92]\npitch_y = 1.71 + pad_size[1]\n\nmount_pad_size = [3.43, 1.65]\n\ndef generate_one_footprint(pins, configuration):\n    pins_per_row = pins//2\n\n    mpn = part_code.format(n=pins)\n    alt_mpn = [code.format(n=pins) for code in alternative_codes]\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"-1MP\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s} (compatible alternatives: {:s}), {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, ', '.join(alt_mpn), pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n    kicad_mod.setAttribute('smd')\n\n    # Calculate dimensions\n    if (pins < 4):\n        B = 0\n    else:\n        B = ((pins / 2) - 1) * pitch\n\n    A = B + 6.65\n    C = B + 11.2\n    # D = pitch_y + PadSiseY\n    pad_row_1_y = -pitch_y/2\n    pad_row_2_y = pad_row_1_y + pitch_y\n    pad1_x = -B/2\n\n    mount_pad_x = ((C - mount_pad_size[0]) / 2)\n    mount_pad_y = pad_row_1_y - (6.93 - pad_size[1]/2)\n\n    body_edge={\n        'left':-A/2,\n        'right':A/2,\n        'top': mount_pad_y - 4.6\n        }\n    body_edge['bottom'] = body_edge['top'] + 9.91\n\n    #\n    # Add solder nails\n    #\n    kicad_mod.append(Pad(at=[-mount_pad_x, mount_pad_y], number=configuration['mounting_pad_number'],\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=mount_pad_size,\n        layers=Pad.LAYERS_SMT))\n    kicad_mod.append(Pad(at=[mount_pad_x, mount_pad_y], number=configuration['mounting_pad_number'],\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=mount_pad_size,\n        layers=Pad.LAYERS_SMT))\n\n    #\n    # Add pads\n    #\n    kicad_mod.append(PadArray(start=[pad1_x, pad_row_1_y], initial=1,\n        pincount=pins_per_row, increment=1,  x_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(start=[pad1_x, pad_row_2_y], initial=pins_per_row+1,\n        pincount=pins_per_row, increment=1, x_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=Pad.LAYERS_SMT))\n\n    #\n    # Add F.Fab\n    #\n    LayerA = ['F.Fab', 'F.SilkS', 'F.CrtYd']\n    LineDXA = [\n        0,\n        configuration['silk_fab_offset'],\n        configuration['courtyard_offset']['connector']\n        ]\n    LindeDeltaA = [0, configuration['silk_pad_clearance'] + configuration['silk_line_width']/2, 0]\n    LineWidthA = [\n        configuration['fab_line_width'],\n        configuration['silk_line_width'],\n        configuration['courtyard_line_width']\n        ]\n    gridA = [0, 0, configuration['courtyard_grid']]\n    for i in range(0,3):\n        LineDX = LineDXA[i]\n        Layer = LayerA[i]\n        LineWidth = LineWidthA[i]\n        LindeDelta = LindeDeltaA[i]\n        points = []\n        grid = gridA[i]\n\n        x1 = 0\n        y1 = body_edge['top'] - LineDX\n\n        points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n        #\n        x1 = (A / 2) - 1 + LineDX\n        y1 = y1\n        points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n        #\n        x1 = (A / 2) + LineDX\n        y1 = y1 + 2\n        points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n        #\n        x1 = x1\n        y1 = mount_pad_y - ((mount_pad_size[1] / 2) + LineDX + LindeDelta)\n        points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n        #\n        if (i == 1): # SilkS\n            kicad_mod.append(PolygoneLine(polygone=points, layer=Layer, width=LineWidth))\n            #\n            # Need to do something ugly here, becosue we will do points = []\n            # We need to reflect these points already here\n            #\n            points2 = []\n            for pp in points:\n                points2.append([-pp[0], pp[1]])\n            kicad_mod.append(PolygoneLine(polygone=points2, layer=Layer, width=LineWidth))\n            #\n            #\n            points = []\n            x1 = x1\n            y1 =mount_pad_y + ((mount_pad_size[1] / 2) + LineDX + LindeDelta)\n            points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n        elif (i == 2): # CrtYd\n            x1 = mount_pad_x + (mount_pad_size[0] / 2) +  LineDX\n            y1 = y1\n            points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n            #\n            x1 = x1\n            y1 =mount_pad_y + ((mount_pad_size[1] / 2) + LineDX)\n            points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n            #\n            x1 = (A / 2) + LineDX\n            y1 = y1\n            points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n        #\n        x1 = x1\n        y1 = body_edge['bottom'] + LineDX\n        points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n        #\n        x1 = (B / 2) + (pad_size[0] / 2) + LineDX  + LindeDelta\n        y1 = y1\n        points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n        #\n        if (i == 0):\n            x1 = 0\n            y1 = y1\n            points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n\n        if (i == 1):\n            ttx1 = x1\n            tty1 = y1 + (pad_size[1] / 2)\n\n        if (i == 2):\n            x1 = x1\n            y1 = ((pitch_y / 2) + (pad_size[1] / 2) + LineDX)\n            ttx1 = x1\n            tty1 = y1\n            points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n            #\n            #\n            x1 = 0\n            y1 = y1\n            points.append([roundToBase(x1, grid), roundToBase(y1, grid)])\n        #\n        # Reflect right part around the X-axis\n        #\n        points2 = []\n        for pp in points:\n            points2.append([0 - pp[0], pp[1]])\n        #\n        #\n        if (i == 0): # Fab\n            # Add pin 1 marker\n            tt = len(points2)\n            ps = points2[tt - 1]\n            p1 = points2[tt - 2]\n            p2 = [(0 - (B / 2)) - 1, p1[1]]\n            p3 = [(0 - (B / 2)), p1[1] - 1]\n            p4 = [(0 - (B / 2)) + 1, p1[1]]\n            points2[tt - 2] = p2\n            points2[tt - 1] = p3\n            points2.append(p4)\n            points2.append(ps)\n        elif (i == 1): # silk\n            points2.append([roundToBase(0 - ttx1, grid), roundToBase(tty1, grid)])\n\n        #\n        #\n        kicad_mod.append(PolygoneLine(polygone=points, layer=Layer, width=LineWidth))\n        #\n        kicad_mod.append(PolygoneLine(polygone=points2, layer=Layer, width=LineWidth))\n\n    ######################### Text Fields ###############################\n    cy1 = roundToBase(body_edge['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cy2 = roundToBase(pad_row_2_y + pad_size[1]/2 + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for pincount in pincount_range:\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_micro-fit-3.0_smd_top_dual_row.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Micro-Fit_3.0\"\nseries_long = 'Micro-Fit 3.0 Connector System'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\n\nvariant_params = {\n    'solder_mounting':{\n        'mount_pins': 'solder',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/430450218_sd.pdf',\n        'C_minus_B': 11.2,\n        'part_code': \"43045-{n:02}18\",\n        'alternative_codes': [\n            \"43045-{n:02}19\",\n            \"43045-{n:02}20\"\n            ]\n        },\n    'retention_pin':{\n        'mount_pins': 'npth',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/430450217_sd.pdf',\n        'C_minus_B': 4.3,\n        'part_code': \"43045-{n:02}15\",\n        'alternative_codes': [\n            \"43045-{n:02}16\",\n            \"43045-{n:02}17\"\n            ]\n        }\n}\n\npins_per_row_range = range(1,13)\npitch = 3.0\n\n\npad_size = [1.27, 2.54]\npitch_y = 6.86 + pad_size[1]\n\nmount_pad_size = [3.43, 1.65]\nmount_drill = 2.41\n\ndef generate_one_footprint(pins_per_row, variant, configuration):\n    is_solder_mp = variant_params[variant]['mount_pins'] == 'solder'\n\n    mpn = variant_params[variant]['part_code'].format(n=pins_per_row*2)\n    alt_mpn = [code.format(n=pins_per_row*2) for code in variant_params[variant]['alternative_codes']]\n\n    # handle arguments\n    mp_name = \"\"\n    if is_solder_mp:\n        mp_name = \"-1MP\"\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = mp_name,\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s} (compatible alternatives: {:s}), {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, ', '.join(alt_mpn), pins_per_row, variant_params[variant]['datasheet']))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    kicad_mod.setAttribute('smd')\n\n    ########################## Dimensions ##############################\n    B = (pins_per_row-1)*pitch\n    A = B + 6.65\n    C = B + variant_params[variant]['C_minus_B']\n\n    pad_row_1_y = -pitch_y/2\n    pad_row_2_y = pad_row_1_y + pitch_y\n    pad1_x = -B/2\n\n    mount_pad_x = C/2 - (mount_pad_size[0]/2 if is_solder_mp else 0)\n    mount_pad_y = pad_row_1_y + pitch_y/2\n\n    tab_w = 1.4\n    tab_l = 1.4\n\n    body_edge={\n        'left': -A/2,\n        'right': A/2,\n        'bottom': 3.43\n        }\n    body_edge['top'] = body_edge['bottom'] - 6.87\n\n    chamfer={'x': 1.2, 'y': 0.63}\n    y_top_min = body_edge['bottom'] - 7.37\n\n    bounding_box={\n        'left': -C/2 if is_solder_mp else body_edge['left'],\n        'right': C/2 if is_solder_mp else body_edge['right'],\n        'top': pad_row_1_y - pad_size[1]/2,\n        'bottom': pad_row_2_y + pad_size[1]/2\n    }\n\n    ############################# Pads ##################################\n    if is_solder_mp:\n        #\n        # Add solder nails\n        #\n        kicad_mod.append(Pad(at=[-mount_pad_x, mount_pad_y], number=configuration['mounting_pad_number'],\n            type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=mount_pad_size,\n            layers=Pad.LAYERS_SMT))\n        kicad_mod.append(Pad(at=[mount_pad_x, mount_pad_y], number=configuration['mounting_pad_number'],\n            type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=mount_pad_size,\n            layers=Pad.LAYERS_SMT))\n    else:\n        kicad_mod.append(Pad(at=[-mount_pad_x, mount_pad_y], number=\"\",\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=mount_drill,\n            drill=mount_drill, layers=Pad.LAYERS_NPTH))\n        kicad_mod.append(Pad(at=[mount_pad_x, mount_pad_y], number=\"\",\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=mount_drill,\n            drill=mount_drill, layers=Pad.LAYERS_NPTH))\n\n    #\n    # Add pads\n    #\n    kicad_mod.append(PadArray(start=[pad1_x, pad_row_1_y], initial=1,\n        pincount=pins_per_row, increment=1,  x_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(start=[pad1_x, pad_row_2_y], initial=pins_per_row+1,\n        pincount=pins_per_row, increment=1, x_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=Pad.LAYERS_SMT))\n\n\n    ######################## Fabrication Layer ###########################\n    main_body_poly= [\n        {'x': body_edge['left'] + chamfer['x'], 'y': body_edge['top']},\n        {'x': body_edge['left'] + chamfer['x'], 'y': y_top_min},\n        {'x': body_edge['left'], 'y': y_top_min},\n        {'x': body_edge['left'], 'y': body_edge['bottom']},\n        {'x': body_edge['right'], 'y': body_edge['bottom']},\n        {'x': body_edge['right'], 'y': y_top_min},\n        {'x': body_edge['right'] - chamfer['x'], 'y': y_top_min},\n        {'x': body_edge['right'] - chamfer['x'], 'y': body_edge['top']},\n        {'x': body_edge['left'] + chamfer['x'], 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_body_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    kicad_mod.append(Line(\n        start={\n            'x': body_edge['left'],\n            'y': body_edge['top'] + chamfer['y']\n        },\n        end={\n            'x': body_edge['left'] + chamfer['x'],\n            'y': body_edge['top']\n        },\n        width=configuration['fab_line_width'], layer=\"F.Fab\"\n        ))\n\n    kicad_mod.append(Line(\n        start={\n            'x': body_edge['right'],\n            'y': body_edge['top'] + chamfer['y']\n        },\n        end={\n            'x': body_edge['right'] - chamfer['x'],\n            'y': body_edge['top']\n        },\n        width=configuration['fab_line_width'], layer=\"F.Fab\"\n        ))\n\n\n    tab_poly = [\n        {'x': -tab_l/2, 'y': body_edge['bottom']},\n        {'x': -tab_l/2, 'y': body_edge['bottom'] + tab_w},\n        {'x': tab_l/2, 'y': body_edge['bottom'] + tab_w},\n        {'x': tab_l/2, 'y': body_edge['bottom']},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=tab_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    p1m_sl = 1\n    p1m_poly = tab_poly = [\n        {'x': pad1_x - p1m_sl/2, 'y': body_edge['top']},\n        {'x': pad1_x, 'y': body_edge['top'] + p1m_sl/sqrt(2)},\n        {'x': pad1_x + p1m_sl/2, 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=tab_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    ############################ SilkS ##################################\n    # Top left corner\n\n    silk_pad_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    xp1_left = pad1_x - pad_size[0]/2 - silk_pad_off\n    ymp_top = mount_pad_y - mount_pad_size[1]/2 - silk_pad_off\n    ymp_bottom = mount_pad_y + mount_pad_size[1]/2 + silk_pad_off\n    xpn_right = pad1_x + B + pad_size[0]/2 + silk_pad_off\n    off = configuration['silk_fab_offset']\n\n    poly_s_bl = [\n        {'x': body_edge['left'] - off, 'y': ymp_bottom},\n        {'x': body_edge['left'] - off, 'y': body_edge['bottom'] + off},\n        {'x': xp1_left, 'y': body_edge['bottom'] + off}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_s_bl,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    poly_s_br = [\n        {'x': body_edge['right'] + off, 'y': ymp_bottom},\n        {'x': body_edge['right'] + off, 'y': body_edge['bottom'] + off},\n        {'x': xpn_right, 'y': body_edge['bottom'] + off}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_s_br,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    poly_s_tl = [\n        {'x': body_edge['left'] - off, 'y': ymp_top},\n        {'x': body_edge['left'] - off, 'y': y_top_min - off},\n        {'x': body_edge['left'] + chamfer['x'] + off, 'y': y_top_min - off},\n        {'x': body_edge['left'] + chamfer['x'] + off, 'y': body_edge['top'] - off},\n        {'x': xp1_left, 'y': body_edge['top'] - off},\n        {'x': xp1_left, 'y': bounding_box['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_s_tl,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    poly_s_br = [\n        {'x': body_edge['right'] + off, 'y': ymp_top},\n        {'x': body_edge['right'] + off, 'y': y_top_min - off},\n        {'x': body_edge['right'] - chamfer['x'] - off, 'y': y_top_min - off},\n        {'x': body_edge['right'] - chamfer['x'] - off, 'y': body_edge['top'] - off},\n        {'x': xpn_right, 'y': body_edge['top'] - off}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_s_br,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    ############################ CrtYd ##################################\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n\n    cy_top = roundToBase(bounding_box['top'] - CrtYd_offset, CrtYd_grid)\n    cy_body_top = roundToBase(y_top_min - CrtYd_offset, CrtYd_grid)\n    cy_mp_top = roundToBase(mount_pad_y - mount_pad_size[1]/2 - CrtYd_offset, CrtYd_grid)\n    cy_mp_bottom = roundToBase(mount_pad_y + mount_pad_size[1]/2 + CrtYd_offset, CrtYd_grid)\n    cy_body_bottom = roundToBase(body_edge['bottom'] + CrtYd_offset, CrtYd_grid)\n    cy_bottom = roundToBase(bounding_box['bottom'] + CrtYd_offset, CrtYd_grid)\n\n    cy_left = roundToBase(bounding_box['left'] - CrtYd_offset, CrtYd_grid)\n    cy_body_left = roundToBase(body_edge['left'] - CrtYd_offset, CrtYd_grid)\n    cy_pad_left = roundToBase(pad1_x - pad_size[0]/2 - CrtYd_offset, CrtYd_grid)\n    cy_pad_right = roundToBase(pad1_x + B + pad_size[0]/2 + CrtYd_offset, CrtYd_grid)\n    cy_body_right = roundToBase(body_edge['right'] + CrtYd_offset, CrtYd_grid)\n    cy_right = roundToBase(bounding_box['right'] + CrtYd_offset, CrtYd_grid)\n\n    CrtYd_poly_t = [\n        {'x': pad1_x + B/2, 'y':cy_top},\n        {'x': cy_pad_left, 'y':cy_top},\n        {'x': cy_pad_left, 'y':cy_body_top},\n        {'x': cy_body_left, 'y':cy_body_top}\n        ]\n    CrtYd_poly_m = [\n        {'x': cy_body_left, 'y':cy_mp_top},\n        {'x': cy_left, 'y':cy_mp_top},\n        {'x': cy_left, 'y':cy_mp_bottom},\n        {'x': cy_body_left, 'y':cy_mp_bottom}\n        ]\n    CrtYd_poly_b = [\n        {'x': cy_body_left, 'y':cy_body_bottom},\n        {'x': cy_pad_left, 'y':cy_body_bottom},\n        {'x': cy_pad_left, 'y':cy_bottom},\n        {'x': pad1_x+B/2, 'y':cy_bottom}\n    ]\n    CrtYd_poly = CrtYd_poly_t\n    if is_solder_mp:\n        CrtYd_poly.extend(CrtYd_poly_m)\n    CrtYd_poly.extend(CrtYd_poly_b)\n\n    kicad_mod.append(PolygoneLine(polygone=CrtYd_poly,\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    kicad_mod.append(PolygoneLine(polygone=CrtYd_poly,\n        layer='F.CrtYd', width=configuration['courtyard_line_width'],\n        x_mirror= 0.00000001 if pad1_x+B/2 == 0 else pad1_x+B/2))\n    ######################### Text Fields ###############################\n\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy_top, 'bottom':cy_bottom}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n    for variant in variant_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_micro-fit-3.0_tht_side_dual_row.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Micro-Fit_3.0\"\nseries_long = 'Micro-Fit 3.0 Connector System'\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 2\nvariants = {'non-clip': '0', 'clip': '2'}\ndatasheet = 'https://www.molex.com/pdm_docs/sd/4304502{s}1_sd.pdf'\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"43045-{n:02}{s}{finish}\"\n\npins_per_row_range = range(1,13)\npitch = 3.0\ndrill = 1.02\npeg_drill = 3.0\nclip_drill = 2.41\nclip_pad = [clip_drill + 1, clip_drill + 1]\npad_to_pad_clearance = 1.5 # Voltage rating is up to 600V (http://www.molex.com/pdm_docs/ps/PS-43045.pdf)\n\npad_size = [pitch - pad_to_pad_clearance, pitch - pad_to_pad_clearance]\n\ndef generate_one_footprint(pins, configuration, variant):\n    pins_per_row = pins\n\n    mpn = part_code.format(n=pins*2,s=variants[variant],finish=max(int(variants[variant]) - 1, 0))\n    alt_mpn = part_code.format(n=pins*2,s=variants[variant],finish='x')\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = '-1MP' if variant == 'clip' else \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s} (alternative finishes: {:s}), {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, alt_mpn, pins_per_row, datasheet.format(s=variants[variant])))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    ########################## Dimensions ##############################\n    B = (pins_per_row-1)*pitch\n    A = B + 6.65\n\n    #Puts first pin on 0,0 and second row 0, pitch\n    pad_row_1_y = 0\n    pad_row_2_y = pad_row_1_y + pitch\n    pad1_x = 0\n\n    peg_clip_y_offset = 4.32\n    peg_x_offset = 2.16\n    clip_x_offset = -2.15\n    peg_C = 1.7 + pitch*(pins-3) #1º need be 4.7mm\n    clip_C = 4.3 + pitch*(pins-1)\n\n    body_edge={\n        'left':-3.325-0.25,\n        'right':A-3.325+0.25,\n        'top': -12.24+3+0.64/2\n        }\n    body_edge['bottom'] = body_edge['top'] + 9.91\n    \n    bevel = 1\n\n    ############################# Pads ##################################\n    #\n    # Pegs\n    #\n    if variant == 'non-clip':\n        if pins_per_row == 1:\n            kicad_mod.append(Pad(at=[0, pad_row_1_y - peg_clip_y_offset], number=\"\",\n                type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n                drill=peg_drill, layers=Pad.LAYERS_NPTH))\n        elif pins_per_row == 2:\n            kicad_mod.append(Pad(at=[pitch/2, pad_row_1_y - peg_clip_y_offset], number=\"\",\n                type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n                drill=peg_drill, layers=Pad.LAYERS_NPTH))\n        elif pins_per_row == 3:\n            kicad_mod.append(Pad(at=[pitch, pad_row_1_y - peg_clip_y_offset], number=\"\",\n                type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n                drill=peg_drill, layers=Pad.LAYERS_NPTH))\n        else:\n            kicad_mod.append(Pad(at=[pad1_x + peg_x_offset, pad_row_1_y - peg_clip_y_offset], number=\"\",\n                type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n                drill=peg_drill, layers=Pad.LAYERS_NPTH))\n            kicad_mod.append(Pad(at=[pad1_x + peg_x_offset + peg_C, pad_row_1_y - peg_clip_y_offset], number=\"\",\n                type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n                drill=peg_drill, layers=Pad.LAYERS_NPTH))\n    elif variant == 'clip':\n        kicad_mod.append(Pad(at=[pad1_x + clip_x_offset, pad_row_1_y - peg_clip_y_offset], number=\"MP\",\n            type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, size=clip_pad,\n            drill=clip_drill, layers=Pad.LAYERS_THT))\n        kicad_mod.append(Pad(at=[pad1_x + clip_x_offset + clip_C, pad_row_1_y - peg_clip_y_offset], number=\"MP\",\n            type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, size=clip_pad,\n            drill=clip_drill, layers=Pad.LAYERS_THT))\n    \n    #\n    # Add pads\n    #\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(start=[pad1_x, pad_row_1_y], initial=1,\n        pincount=pins_per_row, increment=1,  x_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_THT, drill=drill,\n        **optional_pad_params))\n\n    kicad_mod.append(PadArray(start=[pad1_x, pad_row_2_y], initial=pins_per_row+1,\n        pincount=pins_per_row, increment=1, x_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_THT, drill=drill,\n        **optional_pad_params))\n\n    ######################## Clip copper keepout ###########################\n    if variant == 'clip':\n        keepout_width = 2.45\n        keepout_height = 1.6\n        keepout_center_x = [body_edge['left'] - 0.75 + keepout_width / 2, body_edge['right'] + 0.75 - keepout_width / 2]\n        keepout_center_y = body_edge['bottom'] - 3.25 + keepout_height / 2\n        keepout_text = 'CU KEEPOUT'\n        keepout_text_width = keepout_width / len(keepout_text)\n        keepout_text_thickness = keepout_text_width * 0.15\n        kicad_mod.append(PolygoneLine(polygone=[[keepout_center_x[0] - keepout_width/2, keepout_center_y - keepout_height/2],\n            [keepout_center_x[0] - keepout_width/2, keepout_center_y + keepout_height/2],\n            [keepout_center_x[0] + keepout_width/2, keepout_center_y + keepout_height/2],\n            [keepout_center_x[0] + keepout_width/2, keepout_center_y - keepout_height/2],\n            [keepout_center_x[0] - keepout_width/2, keepout_center_y - keepout_height/2]],\n            layer='Dwgs.User', width=0.1))\n        kicad_mod.append(PolygoneLine(polygone=[[keepout_center_x[1] - keepout_width/2, keepout_center_y - keepout_height/2],\n            [keepout_center_x[1] - keepout_width/2, keepout_center_y + keepout_height/2],\n            [keepout_center_x[1] + keepout_width/2, keepout_center_y + keepout_height/2],\n            [keepout_center_x[1] + keepout_width/2, keepout_center_y - keepout_height/2],\n            [keepout_center_x[1] - keepout_width/2, keepout_center_y - keepout_height/2]],\n            layer='Dwgs.User', width=0.1))\n        kicad_mod.append(Text(type='user', text='CU KEEPOUT', at=[keepout_center_x[0], keepout_center_y],\n            layer='Cmts.User', size=[keepout_text_width, keepout_text_width], thickness=keepout_text_thickness))\n        kicad_mod.append(Text(type='user', text='CU KEEPOUT', at=[keepout_center_x[1], keepout_center_y],\n            layer='Cmts.User', size=[keepout_text_width, keepout_text_width], thickness=keepout_text_thickness))\n\n\n    ######################## Fabrication Layer ###########################\n    main_body_poly= [\n        {'x': body_edge['left'], 'y': body_edge['bottom']},\n        {'x': body_edge['left'], 'y': body_edge['top'] + bevel},\n        {'x': body_edge['left'] + bevel, 'y': body_edge['top']},\n        {'x': body_edge['right'] - bevel, 'y': body_edge['top']},\n        {'x': body_edge['right'], 'y': body_edge['top'] + bevel},\n        {'x': body_edge['right'], 'y': body_edge['bottom']},\n        {'x': body_edge['left'], 'y': body_edge['bottom']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_body_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    main_arrow_poly= [\n        {'x': -.75, 'y': body_edge['bottom']},\n        {'x': 0, 'y': 0},\n        {'x': 0.75, 'y': body_edge['bottom']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_arrow_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    ######################## SilkS Layer ###########################\n    if variant == 'non-clip':\n        poly_s_t= [\n            {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': body_edge['bottom'] + configuration['silk_fab_offset']},\n            {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': body_edge['top'] + bevel - configuration['silk_fab_offset']},\n            {'x': body_edge['left'] + bevel - configuration['silk_fab_offset'], 'y': body_edge['top'] - configuration['silk_fab_offset']},\n            {'x': body_edge['right'] - bevel + configuration['silk_fab_offset'], 'y': body_edge['top'] - configuration['silk_fab_offset']},\n            {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': body_edge['top'] + bevel - configuration['silk_fab_offset']},\n            {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': body_edge['bottom'] + configuration['silk_fab_offset']},\n            {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': body_edge['bottom'] + configuration['silk_fab_offset']},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_s_t,\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    if variant == 'clip':\n        # top side (away from pins)\n        poly_s_t= [\n            {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': pad_row_1_y - peg_clip_y_offset - clip_pad[1]/2 + configuration['silk_fab_offset']},\n            {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': body_edge['top'] + bevel - configuration['silk_fab_offset']},\n            {'x': body_edge['left'] + bevel - configuration['silk_fab_offset'], 'y': body_edge['top'] - configuration['silk_fab_offset']},\n            {'x': body_edge['right'] - bevel + configuration['silk_fab_offset'], 'y': body_edge['top'] - configuration['silk_fab_offset']},\n            {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': body_edge['top'] + bevel - configuration['silk_fab_offset']},\n            {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y':  pad_row_1_y - peg_clip_y_offset - clip_pad[1]/2 + configuration['silk_fab_offset']},\n            #{'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': body_edge['bottom'] + configuration['silk_fab_offset']},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_s_t,\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n        # bottom side (closest to pins)\n        poly_s_t= [\n            {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': pad_row_1_y - peg_clip_y_offset + clip_pad[1]/2 - configuration['silk_fab_offset']},\n            {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': body_edge['bottom'] + configuration['silk_fab_offset']},\n            #{'x': body_edge['left'] + bevel - configuration['silk_fab_offset'], 'y': body_edge['top'] - configuration['silk_fab_offset']},\n            #{'x': body_edge['right'] - bevel + configuration['silk_fab_offset'], 'y': body_edge['top'] - configuration['silk_fab_offset']},\n            #{'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': body_edge['top'] + bevel - configuration['silk_fab_offset']},\n            {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': body_edge['bottom'] + configuration['silk_fab_offset']},\n            {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': pad_row_1_y - peg_clip_y_offset + clip_pad[1]/2 - configuration['silk_fab_offset']}\n            #{'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': body_edge['bottom'] + configuration['silk_fab_offset']},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_s_t,\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    ######################## CrtYd Layer ###########################\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n    CrtYd_left = pad1_x + clip_x_offset - clip_pad[0]/2 if variant == 'clip' else body_edge['left']\n    CrtYd_right = pad1_x + clip_x_offset + clip_C + clip_pad[0]/2 if variant == 'clip' else body_edge['right']\n\n    poly_yd = [\n        {'x': roundToBase(CrtYd_left - CrtYd_offset, CrtYd_grid), 'y': roundToBase(body_edge['bottom'] + CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(CrtYd_left - CrtYd_offset, CrtYd_grid), 'y': roundToBase(body_edge['top'] - CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(CrtYd_right + CrtYd_offset, CrtYd_grid), 'y': roundToBase(body_edge['top'] - CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(CrtYd_right + CrtYd_offset, CrtYd_grid), 'y': roundToBase(body_edge['bottom'] + CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(B + pad_to_pad_clearance/2 + CrtYd_offset, CrtYd_grid), 'y': roundToBase(body_edge['bottom'] + CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(B + pad_to_pad_clearance/2 + CrtYd_offset, CrtYd_grid), 'y': roundToBase(pitch + pad_to_pad_clearance/2 + CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(- pad_to_pad_clearance/2 - CrtYd_offset, CrtYd_grid), 'y': roundToBase(pitch + pad_to_pad_clearance/2 + CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(- pad_to_pad_clearance/2 - CrtYd_offset, CrtYd_grid), 'y': roundToBase(body_edge['bottom'] + CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(CrtYd_left - CrtYd_offset, CrtYd_grid), 'y': roundToBase(body_edge['bottom'] + CrtYd_offset, CrtYd_grid)}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_yd,\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    cy1 = roundToBase(body_edge['top'] - configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(pad_row_2_y + pad_size[1] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Write to File and 3D ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pins_per_row_range:\n        for variant in variants:\n            generate_one_footprint(pincount, configuration, variant)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_micro-fit-3.0_tht_side_single_row.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Micro-Fit_3.0\"\nseries_long = 'Micro-Fit 3.0 Connector System'\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'https://www.molex.com/pdm_docs/sd/436500300_sd.pdf'\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"43650-{n:02}00\"\n\nalternative_codes = [\n\"43650-{n:02}01\",\n\"43650-{n:02}02\"\n]\n\npins_per_row_range = range(2,13)\npitch = 3.0\ndrill = 1.02\npeg_drill = 3.0\npad_to_pad_clearance = 1.5 # Voltage rating is up to 600V (http://www.molex.com/pdm_docs/ps/PS-43045.pdf)\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\nif pad_size[1] - drill < 2*min_annular_ring:\n    pad_size[1] = drill + 2*min_annular_ring\nif pad_size[1] - drill > 2*max_annular_ring:\n    pad_size[1] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\ndef generate_one_footprint(pins, configuration):\n    pins_per_row = pins\n\n    mpn = part_code.format(n=pins)\n    alt_mpn = [code.format(n=pins) for code in alternative_codes]\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s} (compatible alternatives: {:s}), {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, ', '.join(alt_mpn), pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    ########################## Dimensions ##############################\n    B = (pins_per_row-1)*pitch\n    A = B + 6.65\n\n    #Centra os pinos em metade do pitch\n    pad_row_1_y = 0\n    pad_row_2_y = pad_row_1_y + pitch\n    pad1_x = 0\n\n    C = 1.7 + pitch*(pins-3) #1º need be 4.7mm\n\n    body_edge={\n        'left':-3.325,\n        'right':A-3.325,\n        'top': -8.92\n        }\n    body_edge['bottom'] = body_edge['top'] + 9.90\n\n    ############################# Pads ##################################\n    #\n    # Pegs\n    #\n    if pins_per_row == 2:\n        kicad_mod.append(Pad(at=[pitch/2, pad_row_1_y - 4.32], number=\"\",\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n            drill=peg_drill, layers=Pad.LAYERS_NPTH))\n    elif pins_per_row == 3:\n        kicad_mod.append(Pad(at=[pitch, pad_row_1_y - 4.32], number=\"\",\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n            drill=peg_drill, layers=Pad.LAYERS_NPTH))\n    else:\n        kicad_mod.append(Pad(at=[pad1_x + 2.15, pad_row_1_y - 4.32], number=\"\",\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n            drill=peg_drill, layers=Pad.LAYERS_NPTH))\n        kicad_mod.append(Pad(at=[pad1_x + 2.15 + C, pad_row_1_y - 4.32], number=\"\",\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n            drill=peg_drill, layers=Pad.LAYERS_NPTH))\n\n    #\n    # Add pads\n    #\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(start=[pad1_x, pad_row_1_y], initial=1,\n        pincount=pins_per_row, increment=1,  x_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_THT, shape=pad_shape, layers=Pad.LAYERS_THT, drill=drill,\n        **optional_pad_params))\n\n    ######################## Fabrication Layer ###########################\n    main_body_poly= [\n        {'x': body_edge['left'], 'y': body_edge['bottom']},\n        {'x': body_edge['left'], 'y': body_edge['top']+1},\n        {'x': body_edge['left']+1, 'y': body_edge['top']},\n        {'x': body_edge['right']-1, 'y': body_edge['top']},\n        {'x': body_edge['right'], 'y': body_edge['top']+1},\n        {'x': body_edge['right'], 'y': body_edge['bottom']},\n        {'x': body_edge['left'], 'y': body_edge['bottom']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_body_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    main_arrow_poly= [\n        {'x': -.75, 'y': body_edge['bottom']},\n        {'x': 0, 'y': 0},\n        {'x': 0.75, 'y': body_edge['bottom']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_arrow_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    ######################## SilkS Layer ###########################\n\n    off = configuration['silk_fab_offset']\n    pad_silk_off = configuration['silk_line_width']/2 + configuration['silk_pad_clearance']\n\n    r_no_silk = max(pad_size)/2 + pad_silk_off # simplified to circle instead of oval\n    dy = abs(body_edge['bottom']) + off\n    pin_center_silk_x = 0 if dy >= r_no_silk else sqrt(r_no_silk**2-dy**2)\n    pin1_center_silk_x = pad_size[0]/2 + pad_silk_off # simplified to rectangle instead of rounded rect\n\n    poly_s_t= [\n        {'x': body_edge['left'] - off, 'y': body_edge['bottom'] + off},\n        {'x': body_edge['left'] - off, 'y': body_edge['top'] + 1 - off},\n        {'x': body_edge['left'] + 1 - off, 'y': body_edge['top'] - off},\n        {'x': body_edge['right'] - 1 + off, 'y': body_edge['top'] - off},\n        {'x': body_edge['right'] + off, 'y': body_edge['top'] + 1 - off},\n        {'x': body_edge['right'] + off, 'y': body_edge['bottom'] + off}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_s_t,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    if pin_center_silk_x == 0:\n        kicad_mod.append(Line(\n            start=[body_edge['left']-off, body_edge['bottom']],\n            end=[body_edge['right']-off, body_edge['bottom']],\n            layer=\"F.SilkS\", width=configuration['silk_line_width']\n        ))\n    else:\n        kicad_mod.append(Line(\n            start=[body_edge['left']-off, body_edge['bottom']+off],\n            end=[-pin1_center_silk_x, body_edge['bottom']+off],\n            layer=\"F.SilkS\", width=configuration['silk_line_width']\n        ))\n        kicad_mod.append(Line(\n            start=[body_edge['right']+off, body_edge['bottom']+off],\n            end=[(pins_per_row-1)*pitch + pin_center_silk_x, body_edge['bottom']+off],\n            layer=\"F.SilkS\", width=configuration['silk_line_width']\n        ))\n        kicad_mod.append(Line(\n            start=[pin1_center_silk_x, body_edge['bottom']+off],\n            end=[pitch - pin_center_silk_x, body_edge['bottom']+off],\n            layer=\"F.SilkS\", width=configuration['silk_line_width']\n        ))\n        for i in range(1, pins_per_row-1):\n            xl = i*pitch + pin_center_silk_x\n            xr = (i+1)*pitch - pin_center_silk_x\n            kicad_mod.append(Line(\n                start=[xl, body_edge['bottom']+off],\n                end=[xr, body_edge['bottom']+off],\n                layer=\"F.SilkS\", width=configuration['silk_line_width']\n            ))\n\n    ######################## CrtYd Layer ###########################\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n\n    poly_yd = [\n        {'x': roundToBase(body_edge['left'] - CrtYd_offset, CrtYd_grid), 'y': roundToBase(body_edge['bottom'] + CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(body_edge['left'] - CrtYd_offset, CrtYd_grid), 'y': roundToBase(body_edge['top'] - CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(body_edge['right'] + CrtYd_offset, CrtYd_grid), 'y': roundToBase(body_edge['top'] - CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(body_edge['right'] + CrtYd_offset, CrtYd_grid), 'y': roundToBase(body_edge['bottom'] + CrtYd_offset, CrtYd_grid)},\n        {'x': roundToBase(body_edge['left'] - CrtYd_offset, CrtYd_grid), 'y': roundToBase(body_edge['bottom'] + CrtYd_offset, CrtYd_grid)}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_yd,\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    cy1 = roundToBase(body_edge['top'] - configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(pad_size[1] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Write to File and 3D ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pins_per_row_range:\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_micro-fit-3.0_tht_top_dual_row.py",
    "content": "#!/usr/bin/env python\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Micro-Fit_3.0\"\nseries_long = 'Micro-Fit 3.0 Connector System'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\n\nvariant_params = {\n    'solder_mounting':{\n        'mount_pins': 'solder', # remove this\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/430450212_sd.pdf',\n        'C_minus_B': 6,\n        'part_code': \"43045-{n:02}12\",\n        'alternative_codes': [\n            \"43045-{n:02}13\",\n            \"43045-{n:02}24\"\n            ]\n        },\n}\n\npins_per_row_range = range(1,13)\npitch = 3.0\ndrill = 1.02\npeg_drill = 1.02\npad_to_pad_clearance = 1.5 # Voltage rating is up to 600V (http://www.molex.com/pdm_docs/ps/PS-43045.pdf)\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\npad_size = [pitch - pad_to_pad_clearance, pitch - pad_to_pad_clearance]\n\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\nif pad_size[1] - drill < 2*min_annular_ring:\n    pad_size[1] = drill + 2*min_annular_ring\nif pad_size[1] - drill > 2*max_annular_ring:\n    pad_size[1] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\ndef generate_one_footprint(pins_per_row, variant, configuration):\n    mpn = variant_params[variant]['part_code'].format(n=pins_per_row*number_of_rows)\n    alt_mpn = [code.format(n=pins_per_row*number_of_rows) for code in variant_params[variant]['alternative_codes']]\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s} (compatible alternatives: {:s}), {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, ', '.join(alt_mpn), pins_per_row, variant_params[variant]['datasheet']))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #kicad_mod.setAttribute('smd')\n\n    ########################## Dimensions ##############################\n    B = (pins_per_row-1)*pitch\n    A = B + 6.65\n    C = B + variant_params[variant]['C_minus_B']\n\n    pad_row_1_y = 0\n    pad1_x = 0\n\n    peg1_x = (B-C)/2\n    peg2_x = (B+C)/2\n    peg_y = pad_row_1_y + pitch + 0.94\n\n    tab_w = 1.4\n    tab_l = 1.4\n\n    body_edge={\n        'left':  (B-A)/2,\n        'right': (A+B)/2,\n        'top': -2.47+0.5\n        }\n    body_edge['bottom'] = body_edge['top'] + (7.37-0.5)\n\n    y_top_min = -2.47\n    chamfer={'x': 1.2, 'y': 0.63}\n\n    ############################# Pads ##################################\n    #\n    # Pegs\n    #\n    kicad_mod.append(Pad(at=[peg1_x, peg_y], number=\"\",\n        type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n        drill=peg_drill, layers=Pad.LAYERS_NPTH))\n    kicad_mod.append(Pad(at=[peg2_x, peg_y], number=\"\",\n        type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n        drill=peg_drill, layers=Pad.LAYERS_NPTH))\n\n    #\n    # Add pads\n    #\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            start=[pad1_x, pad_row_1_y+pitch*row_idx], initial=row_idx*pins_per_row+1,\n            pincount=pins_per_row, increment=1,  x_spacing=pitch, size=pad_size,\n            type=Pad.TYPE_THT, shape=pad_shape, layers=Pad.LAYERS_THT, drill=drill,\n            **optional_pad_params))\n\n    ######################## Fabrication Layer ###########################\n    main_body_poly= [\n        {'x': body_edge['left'] + chamfer['x'], 'y': body_edge['top']},\n        {'x': body_edge['left'] + chamfer['x'], 'y': y_top_min},\n        {'x': body_edge['left'], 'y': y_top_min},\n        {'x': body_edge['left'], 'y': body_edge['bottom']},\n        {'x': body_edge['right'], 'y': body_edge['bottom']},\n        {'x': body_edge['right'], 'y': y_top_min},\n        {'x': body_edge['right'] - chamfer['x'], 'y': y_top_min},\n        {'x': body_edge['right'] - chamfer['x'], 'y': body_edge['top']},\n        {'x': body_edge['left'] + chamfer['x'], 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_body_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    kicad_mod.append(Line(\n        start={\n            'x': body_edge['left'],\n            'y': body_edge['top'] + chamfer['y']\n        },\n        end={\n            'x': body_edge['left'] + chamfer['x'],\n            'y': body_edge['top']\n        },\n        width=configuration['fab_line_width'], layer=\"F.Fab\"\n        ))\n\n    kicad_mod.append(Line(\n        start={\n            'x': body_edge['right'],\n            'y': body_edge['top'] + chamfer['y']\n        },\n        end={\n            'x': body_edge['right'] - chamfer['x'],\n            'y': body_edge['top']\n        },\n        width=configuration['fab_line_width'], layer=\"F.Fab\"\n        ))\n\n\n    tab_poly = [\n        {'x': B/2-tab_l/2, 'y': body_edge['bottom']},\n        {'x': B/2-tab_l/2, 'y': body_edge['bottom'] + tab_w},\n        {'x': B/2+tab_l/2, 'y': body_edge['bottom'] + tab_w},\n        {'x': B/2+tab_l/2, 'y': body_edge['bottom']},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=tab_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    p1m_sl = 1\n    p1m_poly = tab_poly = [\n        {'x': pad1_x - p1m_sl/2, 'y': body_edge['top']},\n        {'x': pad1_x, 'y': body_edge['top'] + p1m_sl/sqrt(2)},\n        {'x': pad1_x + p1m_sl/2, 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=tab_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    ############################ SilkS ##################################\n    # Top left corner\n\n    silk_pad_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    ymp_top = peg_y - peg_drill/2 - silk_pad_off\n    ymp_bottom = peg_y + peg_drill/2 + silk_pad_off\n    off = configuration['silk_fab_offset']\n\n    poly_s_b = [\n        {'x': body_edge['left'] - off, 'y': ymp_bottom},\n        {'x': body_edge['left'] - off, 'y': body_edge['bottom'] + off},\n        {'x': body_edge['right'] + off, 'y': body_edge['bottom'] + off},\n        {'x': body_edge['right'] + off, 'y': ymp_bottom},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_s_b,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    poly_s_t = [\n        {'x': body_edge['left'] - off, 'y': ymp_top},\n        {'x': body_edge['left'] - off, 'y': y_top_min - off},\n        {'x': body_edge['left'] + chamfer['x'] + off, 'y': y_top_min - off},\n        {'x': body_edge['left'] + chamfer['x'] + off, 'y': body_edge['top'] - off},\n        {'x': body_edge['right'] - chamfer['x'] - off, 'y': body_edge['top'] - off},\n        {'x': body_edge['right'] - chamfer['x'] - off, 'y': y_top_min - off},\n        {'x': body_edge['right'] + off, 'y': y_top_min - off},\n        {'x': body_edge['right'] + off, 'y': ymp_top},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_s_t,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    ############################ CrtYd ##################################\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n\n    cy_top = roundToBase(y_top_min - CrtYd_offset, CrtYd_grid)\n    cy_bottom = roundToBase(body_edge['bottom'] + tab_w + CrtYd_offset, CrtYd_grid)\n    cy_left = roundToBase(body_edge['left'] - CrtYd_offset, CrtYd_grid)\n    cy_right = roundToBase(body_edge['right'] + CrtYd_offset, CrtYd_grid)\n\n    poly_cy = [\n        {'x': cy_left, 'y':cy_top},\n        {'x': cy_right, 'y':cy_top},\n        {'x': cy_right, 'y':cy_bottom},\n        {'x': cy_left, 'y':cy_bottom},\n        {'x': cy_left, 'y':cy_top},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_cy,\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy_top, 'bottom':cy_bottom}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_micro-fit-3.0_tht_top_single_row.py",
    "content": "#!/usr/bin/env python\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Micro-Fit_3.0\"\nseries_long = 'Micro-Fit 3.0 Connector System'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 1\n\nvariant_params = {\n    'solder_mounting':{\n        'mount_pins': 'solder', # remove this\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/436500215_sd.pdf',\n        'C_minus_B': 6,\n        'part_code': \"43650-{n:02}15\",\n        'alternative_codes': [\n            \"43650-{n:02}16\",\n            \"43650-{n:02}17\"\n            ]\n        },\n}\n\npins_per_row_range = range(2,13)\npitch = 3.0\ndrill = 1.02\npeg_drill = 1.27\npad_to_pad_clearance = 1.5 # Voltage rating is up to 600V (http://www.molex.com/pdm_docs/ps/PS-43650.pdf)\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\nif pad_size[1] - drill < 2*min_annular_ring:\n    pad_size[1] = drill + 2*min_annular_ring\nif pad_size[1] - drill > 2*max_annular_ring:\n    pad_size[1] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\ndef generate_one_footprint(pins_per_row, variant, configuration):\n    mpn = variant_params[variant]['part_code'].format(n=pins_per_row*number_of_rows)\n    alt_mpn = [code.format(n=pins_per_row*number_of_rows) for code in variant_params[variant]['alternative_codes']]\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s} (compatible alternatives: {:s}), {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, ', '.join(alt_mpn), pins_per_row, variant_params[variant]['datasheet']))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #kicad_mod.setAttribute('smd')\n\n    ########################## Dimensions ##############################\n    B = (pins_per_row-1)*pitch\n    A = B + 6.65\n    C = B + variant_params[variant]['C_minus_B']\n\n    pad_y = 0\n    pad1_x = 0\n\n    peg1_x = (B-C)/2\n    peg2_x = (B+C)/2\n    peg_y = pad_y - 1.96\n\n    tab_w = 1.4\n    tab_l = 1.4\n\n    body_edge={\n        'left':  (B-A)/2,\n        'right': (A+B)/2,\n        'top': -2.47+0.5\n        }\n    body_edge['bottom'] = body_edge['top'] + (4.37-0.5)\n\n    y_top_min = -2.47\n    chamfer={'x': 1.2, 'y': 0.63}\n\n    ############################# Pads ##################################\n    #\n    # Pegs\n    #\n    kicad_mod.append(Pad(at=[peg1_x, peg_y], number=\"\",\n        type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n        drill=peg_drill, layers=Pad.LAYERS_NPTH))\n    kicad_mod.append(Pad(at=[peg2_x, peg_y], number=\"\",\n        type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n        drill=peg_drill, layers=Pad.LAYERS_NPTH))\n\n    #\n    # Add pads\n    #\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(start=[pad1_x, pad_y], initial=1,\n        pincount=pins_per_row, increment=1,  x_spacing=pitch, size=pad_size,\n        type=Pad.TYPE_THT, shape=pad_shape, layers=Pad.LAYERS_THT, drill=drill,\n        **optional_pad_params))\n\n    ######################## Fabrication Layer ###########################\n    main_body_poly= [\n        {'x': body_edge['left'] + chamfer['x'], 'y': body_edge['top']},\n        {'x': body_edge['left'] + chamfer['x'], 'y': y_top_min},\n        {'x': body_edge['left'], 'y': y_top_min},\n        {'x': body_edge['left'], 'y': body_edge['bottom']},\n        {'x': body_edge['right'], 'y': body_edge['bottom']},\n        {'x': body_edge['right'], 'y': y_top_min},\n        {'x': body_edge['right'] - chamfer['x'], 'y': y_top_min},\n        {'x': body_edge['right'] - chamfer['x'], 'y': body_edge['top']},\n        {'x': body_edge['left'] + chamfer['x'], 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=main_body_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    kicad_mod.append(Line(\n        start={\n            'x': body_edge['left'],\n            'y': body_edge['top'] + chamfer['y']\n        },\n        end={\n            'x': body_edge['left'] + chamfer['x'],\n            'y': body_edge['top']\n        },\n        width=configuration['fab_line_width'], layer=\"F.Fab\"\n        ))\n\n    kicad_mod.append(Line(\n        start={\n            'x': body_edge['right'],\n            'y': body_edge['top'] + chamfer['y']\n        },\n        end={\n            'x': body_edge['right'] - chamfer['x'],\n            'y': body_edge['top']\n        },\n        width=configuration['fab_line_width'], layer=\"F.Fab\"\n        ))\n\n\n    tab_poly = [\n        {'x': B/2-tab_l/2, 'y': body_edge['bottom']},\n        {'x': B/2-tab_l/2, 'y': body_edge['bottom'] + tab_w},\n        {'x': B/2+tab_l/2, 'y': body_edge['bottom'] + tab_w},\n        {'x': B/2+tab_l/2, 'y': body_edge['bottom']},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=tab_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    p1m_sl = 1\n    p1m_poly = tab_poly = [\n        {'x': pad1_x - p1m_sl/2, 'y': body_edge['top']},\n        {'x': pad1_x, 'y': body_edge['top'] + p1m_sl/sqrt(2)},\n        {'x': pad1_x + p1m_sl/2, 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=tab_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    ############################ SilkS ##################################\n    # Top left corner\n\n    silk_pad_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    xmp_top1 = peg1_x + peg_drill/2 + silk_pad_off\n    xmp_top2 = peg2_x - peg_drill/2 - silk_pad_off\n    ymp_bottom = peg_y + peg_drill/2 + silk_pad_off\n    off = configuration['silk_fab_offset']\n\n    poly_s_b = [\n        {'x': body_edge['left'] - off, 'y': ymp_bottom},\n        {'x': body_edge['left'] - off, 'y': body_edge['bottom'] + off},\n        {'x': body_edge['right'] + off, 'y': body_edge['bottom'] + off},\n        {'x': body_edge['right'] + off, 'y': ymp_bottom},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_s_b,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    poly_s_t = [\n        {'x': xmp_top1 + off, 'y': y_top_min - off},\n        {'x': body_edge['left'] + chamfer['x'] + off, 'y': y_top_min - off},\n        {'x': body_edge['left'] + chamfer['x'] + off, 'y': body_edge['top'] - off},\n        {'x': body_edge['right'] - chamfer['x'] - off, 'y': body_edge['top'] - off},\n        {'x': body_edge['right'] - chamfer['x'] - off, 'y': y_top_min - off},\n        {'x': xmp_top2 - off, 'y': y_top_min - off},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_s_t,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    ############################ CrtYd ##################################\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n\n    cy_top = roundToBase(y_top_min - CrtYd_offset, CrtYd_grid)\n    cy_bottom = roundToBase(body_edge['bottom'] + tab_w + CrtYd_offset, CrtYd_grid)\n    cy_left = roundToBase(body_edge['left'] - CrtYd_offset, CrtYd_grid)\n    cy_right = roundToBase(body_edge['right'] + CrtYd_offset, CrtYd_grid)\n\n    poly_cy = [\n        {'x': cy_left, 'y':cy_top},\n        {'x': cy_right, 'y':cy_top},\n        {'x': cy_right, 'y':cy_bottom},\n        {'x': cy_left, 'y':cy_bottom},\n        {'x': cy_left, 'y':cy_top},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_cy,\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy_top, 'bottom':cy_bottom}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_micro-latch_tht_side.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Micro-Latch\"\nseries_long = 'Micro-Latch Wire-to-Board Connector System'\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'http://www.molex.com/pdm_docs/sd/532530770_sd.pdf'\n\n#pins_per_row per row\npins_per_row_range = range(2,16)\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"53254-{n:02d}70\"\n\nalternative_codes = [\n\"53254-{n:02d}50\"\n]\n\npitch = 2\ndrill = 0.8\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\n\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\n\n\ndef generate_one_footprint(pins_per_row, configuration):\n    mpn = part_code.format(n=pins_per_row*number_of_rows)\n    alt_mpn = [code.format(n=pins_per_row*number_of_rows) for code in alternative_codes]\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s} (compatible alternatives: {:s}), {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, ', '.join(alt_mpn), pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n    #calculate fp dimensions\n    A = (pins_per_row - 1) * pitch\n    B = A + 3.1\n    C = A + 4\n\n\n    #connector thickness\n    T = 5.75\n\n    #corners\n    x1 = -2\n    x2 = x1 + C\n\n    y1 = -6\n    y2 = y1 + 7.3\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n\n    #add simple outline to F.Fab layer\n    kicad_mod.append(RectLine(start=[x1,y1], end=[x2,y2],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    #wall-thickness W\n    w = 0.45\n\n    #offset\n    o = configuration['silk_fab_offset']\n    pso = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    x1 -= o\n    y1 -= o\n    x2 += o\n    y2 += o\n\n    #generate the pads\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(\n        pincount=pins_per_row, x_spacing=pitch, type=Pad.TYPE_THT,\n        shape=pad_shape, size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    #draw the connector outline\n    out = [\n    {'x': -0.3,'y': pad_size[1]/2+pso},\n    {'x': -0.5,'y': y2},\n    {'x': x1+0.6,'y': y2},\n    {'x': x1+0.1,'y': 0.5},\n    {'x': x1+0.1,'y': 0},\n    {'x': x1,'y': 0},\n    {'x': x1,'y': y1},\n    {'x': A/2,'y': y1},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=out,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    kicad_mod.append(PolygoneLine(polygone=out,x_mirror=A/2,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    #draw the pin tab bits\n    for i in range(pins_per_row-1):\n        x = i * pitch\n        tab = [\n        {'x': x-0.3,'y': pad_size[1]/2+pso},\n        {'x': x+0.3,'y': pad_size[1]/2+pso},\n        {'x': x+0.5,'y': y2},\n        {'x': x+pitch-0.5,'y': y2},\n        {'x': x+pitch-0.3,'y': pad_size[1]/2+pso},\n        ]\n\n        kicad_mod.append(PolygoneLine(polygone=tab,\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    #add the final tab line\n    x = (pins_per_row-1) * pitch\n    kicad_mod.append(Line(start=[x - 0.3, pad_size[1]/2+pso], end=[x+0.3, pad_size[1]/2+pso]))\n\n    #pin-1 marker\n    y =  y2 + 0.5\n    m = 0.3\n\n    L = 2\n    O = 0.3\n\n    pin = [\n    {'x': x1 + L, 'y': y2 + O},\n    {'x': x1 - O, 'y': y2 + O},\n    {'x': x1 - O, 'y': y2 - L},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    p1m_sl = 1\n    pin =[\n        {'x': -p1m_sl/2, 'y': body_edge['bottom']},\n        {'x': 0, 'y': body_edge['bottom'] - p1m_sl/sqrt(2)},\n        {'x': p1m_sl/2, 'y': body_edge['bottom']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    #wall\n    wall = [\n    {'x': x1+w,'y': y1},\n    {'x': x1+w,'y': -2.1},\n    {'x': x2-w,'y': -2.1},\n    {'x': x2-w,'y': y1},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=wall,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    #draw each pin\n    for i in range(pins_per_row):\n        x = i * pitch\n        ya = -2.1\n        yb = ya - 3.3\n\n        pin = [\n        {'x': x-0.25,'y': ya},\n        {'x': x-0.25,'y': yb + 0.25},\n        {'x': x,'y': yb},\n        {'x': x+0.25,'y': yb + 0.25},\n        {'x': x+0.25,'y': ya},\n        ]\n\n        kicad_mod.append(PolygoneLine(polygone=pin,\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_micro-latch_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Micro-Latch\"\nseries_long = 'Micro-Latch Wire-to-Board Connector System'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.molex.com/pdm_docs/sd/532530770_sd.pdf'\n\n#pins_per_row per row\npins_per_row_range = range(2,16)\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"53253-{n:02d}70\"\n\nalternative_codes = [\n\"53253-{n:02d}50\"\n]\n\npitch = 2\ndrill = 0.8\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\n\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\n\n\ndef generate_one_footprint(pins_per_row, configuration):\n    mpn = part_code.format(n=pins_per_row*number_of_rows)\n    alt_mpn = [code.format(n=pins_per_row*number_of_rows) for code in alternative_codes]\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s} (compatible alternatives: {:s}), {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, ', '.join(alt_mpn), pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n    A = (pins_per_row - 1) * pitch\n    B = A + 3.1\n    C = A + 4\n\n    #connector thickness\n    T = 5.75\n\n    #corners\n    x1 = -2\n    x2 = x1 + C\n\n    T = 3.65\n\n    y1 = -1.5\n    y2 = y1 + T\n\n    off = configuration['silk_fab_offset']\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n\n    #add simple outline to F.Fab layer\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],layer='F.Fab', width=configuration['fab_line_width']))\n\n    #wall-thickness W\n    w = 0.4\n\n    #offset\n    o = configuration['silk_fab_offset']\n    x1 -= o\n    y1 -= o\n    x2 += o\n    y2 += o\n\n    #generate the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(\n        pincount=pins_per_row, x_spacing=pitch, type=Pad.TYPE_THT,\n        shape=pad_shape, size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    #draw the courtyard\n\n    #draw the connector outline\n    out = RectLine(start=[x1,y1], end=[x2,y2],\n        width=configuration['silk_line_width'], layer=\"F.SilkS\")\n    kicad_mod.append(out)\n\n    #pin-1 marker\n    y =  -2\n    m = 0.3\n\n    O = 0.3\n    L = 2\n    pin = [\n        {'x': x1 + L, 'y': y1 - O},\n        {'x': x1 - O, 'y': y1 - O},\n        {'x': x1 - O, 'y': y1 + L},\n        ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    p1m_sl = 1\n    pin =[\n        {'x': -p1m_sl/2, 'y': body_edge['top']},\n        {'x': 0, 'y': body_edge['top'] + p1m_sl/sqrt(2)},\n        {'x': p1m_sl/2, 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin, width=configuration['fab_line_width'], layer='F.Fab'))\n\n    kicad_mod.append(Line(start=[x1,2*w],end=[x1+w,2*w],\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    kicad_mod.append(Line(start=[x2,2*w],end=[x2-w,2*w],\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    #add the 'wall'\n    wall = [\n    {'x': A/2,'y': y1+w},\n    {'x': x1+w,'y': y1+w},\n    {'x': x1+w,'y': 0},\n    {'x': x1+2*w,'y': 0},\n    {'x': x1+2*w,'y': w},\n    {'x': x1+w,'y': w},\n    {'x': x1+w,'y': y2},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=wall,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    kicad_mod.append(PolygoneLine(polygone=wall,x_mirror=A/2,\n        width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_mini-fit-sr_tht_side.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Mini-Fit_Sr\"\nseries_long = 'Mini-Fit Sr. Power Connectors'\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'http://www.molex.com/pdm_docs/sd/428202214_sd.pdf'\n\n#pins_per_row per row\npins_per_row_range = [2, 3, 4, 5, 6]\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"42820-{n}2XX\"\n\npitch = 10\ndrill = 2.8\n\noffset_second_pad = 5\n\npad_to_pad_clearance = 3\nmax_annular_ring = 1\nmin_annular_ring = 0.15\n\n#locating pins\nret_dy = 5.73\nret_dx = 9.00 + offset_second_pad\nret_drill = 3.00\nret_size = 4.00\n\n\n\npad_size = [offset_second_pad + 0.1, pitch - pad_to_pad_clearance]\nif pad_size[1] - drill < 2*min_annular_ring:\n    pad_size[1] = drill + 2*min_annular_ring\nif pad_size[1] - drill > 2*max_annular_ring:\n    pad_size[1] = drill + 2*max_annular_ring\n\nversion_params = {\n    'with_thermals':{\n        'description': ', With thermal vias in pads',\n        'fp_name_suffix': '_ThermalVias',\n        'thermals': True\n    },\n    'only_pads':{\n        'description': '',\n        'fp_name_suffix': '',\n        'thermals': False\n    }\n}\n\n\n\ndef generate_one_footprint(pins, params, configuration):\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    mpn = part_code.format(n=pins*number_of_rows)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n    footprint_name += params['fp_name_suffix']\n\n    kicad_mod = Footprint(footprint_name)\n    desc_format_str = \"Molex {:s}, {:s}{:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(desc_format_str.format(series_long, mpn, params['description'], pins, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n\n    # Dimensions\n    P = (pins - 1) * pitch\n    B = pins * pitch + 0.90 # connector length\n    W = 21.00 # connector width\n\n    tab_side_w = 1.46\n\n    yt1 = 0 - (B - P) / 2 # left\n    yt2 = yt1 - tab_side_w\n    yb1 = P + (B - P) / 2 # right\n    yb2 = yb1 + tab_side_w\n    xr1 = ret_dx + 13.56 # bottom\n    xl1 = xr1 - W # top\n    xl2 = xl1 - 7.6\n\n    body_edge={\n        'left':xl1,\n        'right':xr1,\n        'bottom':yb1,\n        'top': yt1\n        }\n    bounding_box = {\n        'top': -(ret_dy + ret_size/2),\n        'bottom': P + (ret_dy + ret_size/2),\n        'left': -pad_size[0]/2,\n        'right': body_edge['right']\n    }\n\n    ##################################  Pins ##################################\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(pincount=pins, start=[row_idx*offset_second_pad, 0],\n            y_spacing=pitch, size=pad_size, drill=drill,\n            shape=Pad.SHAPE_RECT, type=Pad.TYPE_THT, layers=Pad.LAYERS_THT,\n            tht_pad1_shape=Pad.SHAPE_RECT))\n\n    d_small = 0.3\n    s_small = d_small + 2*min_annular_ring\n    thermal_to_pad_edge = s_small/2 + 0.15\n\n    if params['thermals']:\n        for yi in range(pins):\n            n = yi + 1\n            pad_center_x = offset_second_pad/2\n            pad_center_y = yi*pitch\n            pad_l = offset_second_pad + pad_size[0]\n            dy = (pad_size[1] - 2*thermal_to_pad_edge)/2\n            dx = (pad_l - 2*thermal_to_pad_edge)/4\n\n            #draw rectangle on F.Fab layer\n\n            # kicad_mod.append(RectLine(\n            #     start=[pad_center_x - pad_l/2, pad_center_y - pad_size[1]/2],\n            #     end=[pad_center_x + pad_l/2, pad_center_y + pad_size[1]/2],\n            #     layer='F.Fab', width=configuration['fab_line_width']))\n\n            kicad_mod.append(PadArray(center=[pad_center_x, pad_center_y],\n                pincount=3, x_spacing=dx*2,\n                drill=d_small, size=s_small, initial=n, increment=0,\n                shape=Pad.SHAPE_CIRCLE, type=Pad.TYPE_THT, layers=Pad.LAYERS_THT))\n            kicad_mod.append(PadArray(center=[pad_center_x, pad_center_y - dy],\n                pincount=5, x_spacing=dx,\n                drill=d_small, size=s_small, initial=n, increment=0,\n                type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_THT))\n            kicad_mod.append(PadArray(center=[pad_center_x, pad_center_y + dy],\n                pincount=5, x_spacing=dx,\n                drill=d_small, size=s_small, initial=n, increment=0,\n                type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_THT))\n\n    kicad_mod.append(Pad(at=[ret_dx, -ret_dy], type=Pad.TYPE_THT,\n        shape=Pad.SHAPE_CIRCLE, size=ret_size, drill=ret_drill, layers=Pad.LAYERS_THT))\n    kicad_mod.append(Pad(at=[ret_dx, P+ret_dy], type=Pad.TYPE_THT,\n        shape=Pad.SHAPE_CIRCLE, size=ret_size, drill=ret_drill, layers=Pad.LAYERS_THT))\n\n    kicad_mod.append(RectLine(start=[-pad_size[0]/2, -pad_size[1]/2],\n        end=[offset_second_pad + pad_size[0]/2,pad_size[1]/2],offset=pad_silk_off,\n        width=configuration['silk_line_width'], layer='B.SilkS'))\n\n    ############################ Outline ##############################\n    #kicad_mod.append(RectLine(start=[xl1, yt1], end=[xr1, yb1], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(RectLine(start=[xl1, yt2], end=[xr1, yb2], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Line(start=[xl1, yt1], end=[xr1, yt1], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Line(start=[xl1, yb1], end=[xr1, yb1], layer='F.Fab', width=configuration['fab_line_width']))\n\n    off = configuration['silk_fab_offset']\n    silk1 = [\n        {'y': -pad_size[1]/2 - pad_silk_off, 'x': xl1-off},\n        {'y': yt2-off, 'x': xl1-off},\n        {'y': yt2-off, 'x': ret_dx-ret_size/2},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=silk1, layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=silk1, layer='F.SilkS', width=configuration['silk_line_width'], y_mirror=P/2))\n    silk2 = [\n        {'y': yt2-off, 'x': ret_dx+ret_size/2},\n        {'y': yt2-off, 'x': xr1+off},\n        {'y': P/2, 'x': xr1+off},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=silk2, layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=silk2, layer='F.SilkS', width=configuration['silk_line_width'], y_mirror=P/2))\n\n    for i in range(pins - 1):\n        kicad_mod.append(Line(start=[xl1-off, i*pitch+pad_size[1]/2+pad_silk_off],\n            end=[xl1-off, (i+1)*pitch-pad_size[1]/2-pad_silk_off],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    for i in range(pins):\n        w_pin = 3.8\n        kicad_mod.append(RectLine(start=[xl1, i*pitch-w_pin/2], end=[xl2, i*pitch+w_pin/2],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    ############################ Pin 1 ################################\n    # Pin 1 designator\n    pin1_sl = 2.4\n    pin1 = [\n        {'x': body_edge['left'], 'y': -pin1_sl/2},\n        {'x': body_edge['left'] - pin1_sl/sqrt(2), 'y': 0},\n        {'x': body_edge['left'], 'y': pin1_sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin1, layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=pin1, layer='F.Fab', width=configuration['fab_line_width'],\n        x_mirror=(body_edge['left']+xl2)/2))\n\n    pin1 = [\n        {'y': -pad_size[1]/2 - pad_silk_off, 'x': xl1-off},\n        {'y': -pad_size[1]/2 - pad_silk_off, 'x': -pad_size[0]/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin1, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    # pin1 = [\n    #     {'x': 0, 'y': 8},\n    #     {'x': 0.5, 'y': 9},\n    #     {'x': -0.5, 'y': 9},\n    #     {'x': 0, 'y': 8},\n    # ]\n    # kicad_mod.append(PolygoneLine(polygone=pin1, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n    for version in version_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, version_params[version], configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_mini-fit-sr_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Mini-Fit_Sr\"\nseries_long = 'Mini-Fit Sr. Power Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.molex.com/pdm_docs/sd/428192214_sd.pdf'\n\n#pins_per_row per row\npins_per_row_range = [2, 3, 4, 5, 6]\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"42819-{n}2XX\"\n\npitch = 10\ndrill = 2.8\n\noffset_second_pad = 4.4\n\npad_to_pad_clearance = 3\nmax_annular_ring = 1\nmin_annular_ring = 0.15\n\n#locating pins\nret_dy = 5.73\nret_dx = offset_second_pad - 0.35\nret_drill = 3.00\nret_size = 4.00\n\n\n\npad_size = [offset_second_pad + 0.1, pitch - pad_to_pad_clearance]\nif pad_size[1] - drill < 2*min_annular_ring:\n    pad_size[1] = drill + 2*min_annular_ring\nif pad_size[1] - drill > 2*max_annular_ring:\n    pad_size[1] = drill + 2*max_annular_ring\n\nversion_params = {\n    'with_thermals':{\n        'description': ', With thermal vias in pads',\n        'fp_name_suffix': '_ThermalVias',\n        'thermals': True\n    },\n    'only_pads':{\n        'description': '',\n        'fp_name_suffix': '',\n        'thermals': False\n    }\n}\n\ndef generate_one_footprint(pins, params, configuration):\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    mpn = part_code.format(n=pins*number_of_rows)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n    footprint_name += params['fp_name_suffix']\n\n    kicad_mod = Footprint(footprint_name)\n    desc_format_str = \"Molex {:s}, {:s}{:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(desc_format_str.format(series_long, mpn, params['description'], pins, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n\n    # Dimensions\n    P = (pins - 1) * pitch\n    B = pins * pitch + 0.90 # connector length\n    W = 9.2 # connector width\n\n    tab_side_w = 1.46\n\n    lock_tab_w1 = 1.8\n    lock_tab_w2 = 3.3 - lock_tab_w1\n\n    yt1 = 0 - (B - P) / 2 # left\n    yt2 = yt1 - tab_side_w\n    yb1 = P + (B - P) / 2 # right\n    yb2 = yb1 + tab_side_w\n    xl1 = -1.34 # bottom\n    xr1 = xl1 + W # top\n    xr2 = xl1 + 10.80\n\n    body_edge={\n        'left':xl1,\n        'right':xr1,\n        'bottom':yb1,\n        'top': yt1\n        }\n    bounding_box = {\n        'top': -(ret_dy + ret_size/2),\n        'bottom': P + (ret_dy + ret_size/2),\n        'left': body_edge['left'] - (lock_tab_w1 + lock_tab_w2),\n        'right': body_edge['right']\n    }\n\n    ##################################  Pins ##################################\n    for pin_idx in range(2):\n        kicad_mod.append(PadArray(\n            pincount=pins, start=[pin_idx*offset_second_pad, 0],\n            y_spacing=pitch, size=pad_size, drill=drill,\n            shape=Pad.SHAPE_RECT, type=Pad.TYPE_THT, layers=Pad.LAYERS_THT,\n            tht_pad1_shape=Pad.SHAPE_RECT))\n\n    d_small = 0.3\n    s_small = d_small + 2*min_annular_ring\n    thermal_to_pad_edge = s_small/2 + 0.15\n\n    if params['thermals']:\n        for yi in range(pins):\n            n = yi + 1\n            pad_center_x = offset_second_pad/2\n            pad_center_y = yi*pitch\n            pad_l = offset_second_pad + pad_size[0]\n            dy = (pad_size[1] - 2*thermal_to_pad_edge)/2\n            dx = (pad_l - 2*thermal_to_pad_edge)/4\n\n            #draw rectangle on F.Fab layer\n\n            # kicad_mod.append(RectLine(\n            #     start=[pad_center_x - pad_l/2, pad_center_y - pad_size[1]/2],\n            #     end=[pad_center_x + pad_l/2, pad_center_y + pad_size[1]/2],\n            #     layer='F.Fab', width=configuration['fab_line_width']))\n\n            kicad_mod.append(PadArray(center=[pad_center_x, pad_center_y],\n                pincount=3, x_spacing=dx*2,\n                drill=d_small, size=s_small, initial=n, increment=0,\n                shape=Pad.SHAPE_CIRCLE, type=Pad.TYPE_THT, layers=Pad.LAYERS_THT))\n            kicad_mod.append(PadArray(center=[pad_center_x, pad_center_y - dy],\n                pincount=5, x_spacing=dx,\n                drill=d_small, size=s_small, initial=n, increment=0,\n                type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_THT))\n            kicad_mod.append(PadArray(center=[pad_center_x, pad_center_y + dy],\n                pincount=5, x_spacing=dx,\n                drill=d_small, size=s_small, initial=n, increment=0,\n                type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_THT))\n\n    kicad_mod.append(Pad(at=[ret_dx, -ret_dy], type=Pad.TYPE_THT,\n        shape=Pad.SHAPE_CIRCLE, size=ret_size, drill=ret_drill, layers=Pad.LAYERS_THT))\n    kicad_mod.append(Pad(at=[ret_dx, P+ret_dy], type=Pad.TYPE_THT,\n        shape=Pad.SHAPE_CIRCLE, size=ret_size, drill=ret_drill, layers=Pad.LAYERS_THT))\n\n    kicad_mod.append(RectLine(start=[-pad_size[0]/2, -pad_size[1]/2],\n        end=[offset_second_pad + pad_size[0]/2,pad_size[1]/2],offset=pad_silk_off,\n        width=configuration['silk_line_width'], layer='B.SilkS'))\n\n    ############################ Outline ##############################\n    #kicad_mod.append(RectLine(start=[xl1, yt1], end=[xr1, yb1], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(RectLine(start=[xl1, yt2], end=[xr1, yb2], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Line(start=[xl1, yt1], end=[xr1, yt1], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(Line(start=[xl1, yb1], end=[xr1, yb1], layer='F.Fab', width=configuration['fab_line_width']))\n\n    off = configuration['silk_fab_offset']\n    silk1 = [\n        {'y': -pad_size[1]/2 - pad_silk_off, 'x': xl1-off},\n        {'y': yt2-off, 'x': xl1-off},\n        {'y': yt2-off, 'x': ret_dx-ret_size/2},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=silk1, layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=silk1, layer='F.SilkS', width=configuration['silk_line_width'], y_mirror=P/2))\n    silk2 = [\n        {'y': yt2-off, 'x': ret_dx+ret_size/2},\n        {'y': yt2-off, 'x': xr1+off},\n        {'y': P/2, 'x': xr1+off},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=silk2, layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=silk2, layer='F.SilkS', width=configuration['silk_line_width'], y_mirror=P/2))\n\n    for i in range(pins - 1):\n        kicad_mod.append(Line(start=[xl1-off, i*pitch+pad_size[1]/2+pad_silk_off],\n            end=[xl1-off, (i+1)*pitch-pad_size[1]/2-pad_silk_off],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    # Flanges\n    for i in range(pins):\n        yt = i * pitch - 1.6 / 2\n        yb = i * pitch + 1.6 / 2\n        # kicad_mod.append(RectLine(start=[xr1, yt], end=[xr2, yb], layer='F.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=[\n                {'x': xr1, 'y': yt},\n                {'x': xr2, 'y': yt},\n                {'x': xr2, 'y': yb},\n                {'x': xr1, 'y': yb},\n            ], layer='F.Fab', width=configuration['fab_line_width']))\n        # kicad_mod.append(RectLine(start=[xr1+off, yt-off], end=[xr2+off, yb+off], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=[\n                {'x': xr1+off, 'y': yt-off},\n                {'x': xr2+off, 'y': yt-off},\n                {'x': xr2+off, 'y': yb+off},\n                {'x': xr1+off, 'y': yb+off},\n            ], layer='F.SilkS', width=configuration['silk_line_width']))\n\n    tab_l = 3.60 # tab length\n    #tab_w = 3.30 # tab width\n    xl2 = xl1 - lock_tab_w1\n    xl3 = xl2 - lock_tab_w2\n    yt4 = P / 2 - tab_l / 2 # left\n    yb4 = P / 2 + tab_l / 2 # right\n    if pins % 2:\n        kicad_mod.append(RectLine(start=[xl1, yt4], end=[xl3, yb4], layer='F.Fab', width=configuration['fab_line_width']))\n    else:\n        yt3 = (pins // 2 - 1) * pitch\n        yb3 = (pins // 2) * pitch\n        kicad_mod.append(RectLine(start=[xl1, yt3], end=[xl2, yb3], layer='F.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(RectLine(start=[xl2, yt4], end=[xl3, yb4], layer='F.Fab', width=configuration['fab_line_width']))\n    tab = [\n        {'x': xl2-off, 'y': yt4-off},\n        {'x': xl3-off, 'y': yt4-off},\n        {'x': xl3-off, 'y': yb4+off},\n        {'x': xl2-off, 'y': yb4+off},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=tab, layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n    ############################ Pin 1 ################################\n    # Pin 1 designator\n    pin1_sl = 2.4\n    pin1 = [\n        {'x': body_edge['left'], 'y': -pin1_sl/2},\n        {'x': body_edge['left'] + pin1_sl/sqrt(2), 'y': 0},\n        {'x': body_edge['left'], 'y': pin1_sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin1, layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=pin1, layer='F.Fab', width=configuration['fab_line_width'],\n        x_mirror=(body_edge['left']+body_edge['right'])/2))\n\n    x = -pad_size[0]/2 - pad_silk_off\n    m = 0.4\n\n    pin = [\n    {'x': x,'y': 0},\n    {'x': x-2*m,'y': -m},\n    {'x': x-2*m,'y': +m},\n    {'x': x,'y': 0},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['silk_line_width'], layer='F.SilkS'))\n\n    # pin1 = [\n    #     {'x': 0, 'y': 8},\n    #     {'x': 0.5, 'y': 9},\n    #     {'x': -0.5, 'y': 9},\n    #     {'x': 0, 'y': 8},\n    # ]\n    # kicad_mod.append(PolygoneLine(polygone=pin1, layer='F.SilkS', width=0.12))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for version in version_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, version_params[version], configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_mini-fit-sr_tht_top_dual.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Mini-Fit_Sr\"\nseries_long = 'Mini-Fit Sr. Power Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'http://www.molex.com/pdm_docs/sd/439151404_sd.pdf'\n\n#pins_per_row per row\npins_per_row_range = [3, 4, 5, 6, 7]\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"43915-xx{n:02}\"\n\npitch = 10\ndrill = 2.8\n\noffset_second_pad = 4.4\npitch_row = offset_second_pad + 8.06\n\npad_to_pad_clearance = 3\nmax_annular_ring = 1\nmin_annular_ring = 0.15\n\n#locating pins\nx_loc = 8.43\nr_loc = 3.0\n\n\n\npad_size = [offset_second_pad + 0.1, pitch - pad_to_pad_clearance]\nif pad_size[1] - drill < 2*min_annular_ring:\n    pad_size[1] = drill + 2*min_annular_ring\nif pad_size[1] - drill > 2*max_annular_ring:\n    pad_size[1] = drill + 2*max_annular_ring\n\nversion_params = {\n    'with_thermals':{\n        'description': ', With thermal vias in pads',\n        'fp_name_suffix': '_ThermalVias',\n        'thermals': True\n    },\n    'only_pads':{\n        'description': '',\n        'fp_name_suffix': '',\n        'thermals': False\n    }\n}\n\ndef generate_one_footprint(pins, params, configuration):\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    mpn = part_code.format(n=pins*number_of_rows)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n    footprint_name += params['fp_name_suffix']\n\n    kicad_mod = Footprint(footprint_name)\n    desc_format_str = \"Molex {:s}, {:s}{:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(desc_format_str.format(series_long, mpn, params['description'], pins, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n    #ref: http://www.molex.com/pdm_docs/sd/439151404_sd.pdf\n    #A = distance between mounting holes\n    A = pins * pitch + 1.41\n\n    #B = distance between end pin centers\n    B = (pins - 1) * pitch\n\n    #E = length of part\n    E = pins * pitch + 0.9\n\n    #connector width\n    W = 19.16\n\n    #corner positions\n    y1 = -(E-B)/2\n    y2 = y1 + E\n\n    x1 = -1.15\n    x2 = x1 + W\n\n    TL = 5\n    TW = 13\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = {\n        'left': -pad_size[0]/2,\n        'right': pitch_row + offset_second_pad + pad_size[0]/2\n    }\n\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    #generate the pads\n    for row_idx in range(2):\n        for pad_idx in range(2):\n            kicad_mod.append(PadArray(\n                pincount=pins, start=[row_idx*pitch_row + pad_idx*offset_second_pad, 0],\n                initial=row_idx*pins+1, y_spacing=pitch, size=pad_size, drill=drill,\n                type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, layers=Pad.LAYERS_THT,\n                tht_pad1_shape=Pad.SHAPE_RECT))\n\n    #thermal vias\n\n    d_small = 0.3\n    s_small = d_small + 2*min_annular_ring\n    thermal_to_pad_edge = s_small/2 + 0.15\n\n    if params['thermals']:\n        for yi in range(pins):\n            for xi in range(number_of_rows):\n                n = xi*pins + yi + 1\n                pad_center_x = xi*pitch_row + offset_second_pad/2\n                pad_center_y = yi*pitch\n                pad_l = offset_second_pad + pad_size[0]\n                dy = (pad_size[1] - 2*thermal_to_pad_edge)/2\n                dx = (pad_l - 2*thermal_to_pad_edge)/4\n\n                #draw rectangle on F.Fab layer\n\n                # kicad_mod.append(RectLine(\n                #     start=[pad_center_x - pad_l/2, pad_center_y - pad_size[1]/2],\n                #     end=[pad_center_x + pad_l/2, pad_center_y + pad_size[1]/2],\n                #     layer='F.Fab', width=configuration['fab_line_width']))\n\n                kicad_mod.append(PadArray(center=[pad_center_x, pad_center_y],\n                    pincount=3, x_spacing=dx*2,\n                    drill=d_small, size=s_small, initial=n, increment=0,\n                    shape=Pad.SHAPE_CIRCLE, type=Pad.TYPE_THT, layers=Pad.LAYERS_THT))\n                kicad_mod.append(PadArray(center=[pad_center_x, pad_center_y - dy],\n                    pincount=5, x_spacing=dx,\n                    drill=d_small, size=s_small, initial=n, increment=0,\n                    type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_THT))\n                kicad_mod.append(PadArray(center=[pad_center_x, pad_center_y + dy],\n                    pincount=5, x_spacing=dx,\n                    drill=d_small, size=s_small, initial=n, increment=0,\n                    type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_THT))\n\n    # locating pins\n    kicad_mod.append(Pad(at=[x_loc, 5], type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n        size=r_loc, drill=r_loc, layers=Pad.LAYERS_NPTH))\n    kicad_mod.append(Pad(at=[x_loc, B/2-A/2], type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n        size=r_loc+0.5, drill=r_loc, layers=Pad.LAYERS_THT))\n    kicad_mod.append(Pad(at=[x_loc, B/2+A/2], type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n        size=r_loc+0.5, drill=r_loc, layers=Pad.LAYERS_THT))\n\n    #mark pin-1 (bottom layer)\n    kicad_mod.append(RectLine(start=[-pad_size[0]/2, -pad_size[1]/2],\n        end=[offset_second_pad + pad_size[0]/2,pad_size[1]/2],offset=pad_silk_off,\n        width=configuration['silk_line_width'], layer='B.SilkS'))\n\n    #draw connector outline (basic)\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    #connector outline on F.SilkScreen\n    off = configuration['silk_line_width']\n    corner = [\n        {'y': -pad_size[1]/2 - pad_silk_off, 'x': x1-off},\n        {'y': y1 - off, 'x': x1-off},\n        {'y': y1 - off, 'x': x_loc-r_loc/2-0.5},\n    ]\n\n    # kicad_mod.append(PolygoneLine(polygone=corner,\n    #     width=configuration['silk_line_width'], layer='F.SilkS'))\n    kicad_mod.append(Line(start=[x_loc-r_loc/2-0.5, y1 - off],\n        end=[x_loc-TW/2-off, y1 - off],\n        width=configuration['silk_line_width'], layer='F.SilkS'))\n\n    kicad_mod.append(PolygoneLine(polygone=corner,y_mirror=B/2,\n        width=configuration['silk_line_width'], layer='F.SilkS'))\n    kicad_mod.append(PolygoneLine(polygone=corner,x_mirror=x_loc,\n        width=configuration['silk_line_width'], layer='F.SilkS'))\n    kicad_mod.append(PolygoneLine(polygone=corner,y_mirror=B/2,x_mirror=x_loc,\n        width=configuration['silk_line_width'], layer='F.SilkS'))\n\n    #silk-screen between each pad\n\n    for i in range(pins-1):\n        ya = i * pitch + pad_size[1]/2 + pad_silk_off\n        yb = (i+1) * pitch - pad_size[1]/2 - pad_silk_off\n\n        kicad_mod.append(Line(start=[x1-off, ya],end=[x1-off, yb],\n            width=configuration['silk_line_width'], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[x2+off, ya],end=[x2+off, yb],\n            width=configuration['silk_line_width'], layer='F.SilkS'))\n\n    #draw the tabs at each end\n    def offsetPoly(poly_points, o , center_x, center_y):\n        new_points = []\n        for point in poly_points:\n            new_points.append(\n                {\n                'y': point['y'] + (o if point['y'] > center_y else -o),\n                'x': point['x'] + (o if point['x'] > center_x else -o)\n                }\n            )\n        return new_points\n\n    tab = [\n        {'y': y1,'x': x_loc-TW/2},\n        {'y': y1-TL,'x': x_loc-TW/2},\n        {'y': y1-TL,'x': x_loc+TW/2},\n        {'y': y1,'x': x_loc+TW/2},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=tab,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n    kicad_mod.append(PolygoneLine(polygone=tab, y_mirror=B/2,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    tap_off = offsetPoly(tab, off, x_loc, B/2)\n    kicad_mod.append(PolygoneLine(polygone=tap_off,\n        width=configuration['silk_line_width'], layer='F.SilkS'))\n    kicad_mod.append(PolygoneLine(polygone=tap_off, y_mirror=B/2,\n        width=configuration['silk_line_width'], layer='F.SilkS'))\n\n    bounding_box['top'] = y1 - TL\n    bounding_box['bottom'] = y2 + TL\n\n    #inner-tab\n    T = 2\n    tab = [\n        {'y': y1-off,'x': x_loc-TW/2-off+T},\n        {'y': y1-off-TL+T,'x': x_loc-TW/2-off+T},\n        {'y': y1-off-TL+T,'x': x_loc+TW/2+off-T},\n        {'y': y1-off,'x': x_loc+TW/2+off-T},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=tab,\n        width=configuration['silk_line_width'], layer='F.SilkS'))\n    kicad_mod.append(PolygoneLine(polygone=tab,y_mirror=B/2,\n        width=configuration['silk_line_width'], layer='F.SilkS'))\n\n    #pin-1 marker\n    x = x1 - 1.5\n    m = 0.4\n\n    pin = [\n    {'x': x,'y': 0},\n    {'x': x-2*m,'y': -m},\n    {'x': x-2*m,'y': +m},\n    {'x': x,'y': 0},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['silk_line_width'], layer='F.SilkS'))\n\n    sl=3\n    pin = [\n        {'x': body_edge['left'], 'y': -sl/2},\n        {'x': body_edge['left'] + sl/sqrt(2), 'y': 0},\n        {'x': body_edge['left'], 'y': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for version in version_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, version_params[version], configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_mini-fit_Jr_tht_side_dual-row.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\ndraw_inner_details = False\n\nseries = \"Mini-Fit_Jr\"\nseries_long = 'Mini-Fit Jr. Power Connectors'\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 2\n\n\n#pins_per_row_per_row per row\npins_per_row_range = range(1,13)\n\n#Molex part number\n#n = number of circuits per row\nvariant_params = {\n    'peg':{\n        'mount_pins': 'plastic_peg',\n        'descriptive_name': 'Snap-in Plastic Peg PCB Lock',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/039300020_sd.pdf',\n        'part_code': {'mpn':\"39-30-0{n:02d}0\",'eng_num':\"5569-{n:02}A2\"},\n        },\n    'flange':{\n        'mount_pins': 'screw_flange',\n        'descriptive_name': 'PCB Mounting Flange',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/039291047_sd.pdf',\n        'part_code': {'mpn':\"39-29-4{n:02d}9\",'eng_num':\"5569-{n:02}A1\"},\n        }\n}\n\npitch = 4.2\ndrill = 1.8\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 1.5\nmax_annular_ring = 0.95\nmin_annular_ring = 0.15\n\n\nrow = 5.5\n\npad_size = [pitch - pad_to_pad_clearance, row - pad_to_pad_clearance]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\nif pad_size[1] - drill < 2*min_annular_ring:\n    pad_size[1] = drill + 2*min_annular_ring\nif pad_size[1] - drill > 2*max_annular_ring:\n    pad_size[1] = drill + 2*max_annular_ring\n\npad_shape = Pad.SHAPE_OVAL\nif pad_size[0] == pad_size[1]:\n    pad_shape = Pad.SHAPE_CIRCLE\n\n\ndef generate_one_footprint(pins_per_row, variant, configuration):\n    silk_pad_off = configuration['silk_pad_clearance']+configuration['silk_line_width']/2\n\n    mpn = variant_params[variant]['part_code']['mpn'].format(n=pins_per_row*2)\n    old_mpn = variant_params[variant]['part_code']['eng_num'].format(n=pins_per_row*2)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=old_mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    descr_format_str = \"Molex {:s}, old mpn/engineering number: {:s}, example for new mpn: {:s}, {:d} Pins per row, Mounting: {:s} ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(descr_format_str.format(\n        series_long, old_mpn, mpn, pins_per_row,\n        variant_params[variant]['descriptive_name'], variant_params[variant]['datasheet']))\n    tags = configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation])\n    tags += variant_params[variant]['mount_pins']\n    kicad_mod.setTags(tags)\n\n    peg = variant_params[variant]['mount_pins'] == 'plastic_peg'\n\n    #calculate fp dimensions\n\n    #connector length\n    A = pins_per_row * pitch + 1.2\n\n    #pin centers\n    B = (pins_per_row - 1) * pitch\n\n    #plasic pin-lock\n    C = A + 4\n\n    #connector width\n    W = 9.6\n\n    #corner positions\n    x1 = -(A-B)/2\n    x2 = x1 + A\n\n    y1 = -7.3 - 6.6\n    y2 = y1 + 12.8\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n    bounding_box['bottom'] = row + pad_size[1]/2\n\n    #generate the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            pincount=pins_per_row, initial=row_idx*pins_per_row+1,\n            start=[0, row_idx*row], x_spacing=pitch,\n            type=Pad.TYPE_THT, shape=pad_shape,\n            size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n\n    off = configuration['silk_fab_offset']\n    #draw the 'peg' version\n    #http://www.molex.com/pdm_docs/sd/026013127_sd.pdf\n    #draw the outline of the shape\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    if peg:\n        loc = 3.00\n        if pins_per_row > 2: # two mounting holes\n            kicad_mod.append(Pad(at=[0,-7.3],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=loc,drill=loc, layers=Pad.LAYERS_NPTH))\n            #kicad_mod.append(Circle(center=[0,-7.3],radius=loc/2+0.1))\n            kicad_mod.append(Pad(at=[B,-7.3],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=loc,drill=loc, layers=Pad.LAYERS_NPTH))\n            #kicad_mod.append(Circle(center=[B,-7.3],radius=loc/2+0.1))\n        else: #single hole\n            kicad_mod.append(Pad(at=[B/2,-7.3],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=loc,drill=loc, layers=Pad.LAYERS_NPTH))\n            #kicad_mod.append(Circle(center=[B/2,-7.3],radius=loc/2+0.1))\n\n\n        #draw the outline of the connector on the silkscreen\n        poly = [\n        {'x': -2,'y': y2+off},\n        {'x': x1-off,'y': y2+off},\n        {'x': x1-off,'y': y1-off},\n        {'x': B/2,'y': y1-off},\n        ]\n\n        kicad_mod.append(PolygoneLine(polygone=poly,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=poly, x_mirror=B/2,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #draw the 'screw' version\n    #http://www.molex.com/pdm_docs/sd/039291027_sd.pdf\n    else:\n        loc = 3.2\n        kicad_mod.append(Pad(at=[-4.5,  -4.2],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=loc, drill=loc, layers=Pad.LAYERS_NPTH))\n        kicad_mod.append(Pad(at=[B+4.5, -4.2],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=loc, drill=loc, layers=Pad.LAYERS_NPTH))\n        bounding_box['left'] = -15.4/2\n        bounding_box['right'] = B + 15.4/2\n\n        #draw the connector outline on silkscreen layer\n        poly = [\n        {'x': x1,'y': y2-6.2},\n        {'x': -15.4/2,'y': y2-6.2},\n        {'x': -15.4/2,'y': y2},\n        {'x': x1,'y': y2}\n        ]\n\n        kicad_mod.append(PolygoneLine(polygone=poly,\n            layer='F.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=poly, x_mirror=B/2,\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n        poly = [\n        {'x': B/2,'y': y1-off},\n        {'x': x1-off,'y': y1-off},\n        {'x': x1-off,'y': y2-6.2-off},\n        {'x': -15.4/2 - off,'y': y2-6.2-off},\n        {'x': -15.4/2 - off,'y': y2+off},\n        {'x': -2,'y': y2+off},\n        ]\n\n        kicad_mod.append(PolygoneLine(polygone=poly))\n        kicad_mod.append(PolygoneLine(polygone=poly, x_mirror=B/2,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n\n\n\n    #draw the pins_per_row on the Silkscreen layer\n    o = pad_size[1]/2+silk_pad_off\n    w = 0.3\n    for i in range(pins_per_row):\n        x = i * pitch\n        ya = o\n        yb = row - o\n        kicad_mod.append(Line(start=[x-w,ya],end=[x-w,yb],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[x+w,ya],end=[x+w,yb],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #draw lines between each pin\n    off = 0.1\n    for i in range(pins_per_row-1):\n        xa = i * pitch + pad_size[0] / 2 + silk_pad_off\n        xb = (i+1) * pitch - pad_size[0] / 2 - silk_pad_off\n\n        kicad_mod.append(Line(start=[xa,y2+off],end=[xb,y2+off],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #pin-1 marker\n    x =  -2\n    m = 0.3\n\n    arrow = [\n    {'x': x,'y': 0},\n    {'x': x-2*m,'y': +m},\n    {'x': x-2*m,'y': -m},\n    {'x': x,'y': 0},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=arrow,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n    sl = 2\n    pin = [\n        {'x': -sl/2, 'y': body_edge['bottom']},\n        {'x': 0, 'y': body_edge['bottom']-sl/sqrt(2)},\n        {'x': sl/2, 'y': body_edge['bottom']},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n\n    cx1 = roundToBase(bounding_box['left'] - CrtYd_offset, CrtYd_grid)\n    cy1 = roundToBase(bounding_box['top'] - CrtYd_offset, CrtYd_grid)\n\n    cx2 = roundToBase(bounding_box['right'] + CrtYd_offset, CrtYd_grid)\n    cy2 = roundToBase(bounding_box['bottom'] + CrtYd_offset, CrtYd_grid)\n\n    if peg:\n        kicad_mod.append(RectLine(\n            start=[cx1, cy1], end=[cx2, cy2],\n            layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    else:\n        cxb_left = roundToBase(body_edge['left'] - CrtYd_offset, CrtYd_grid)\n        cxp_left = roundToBase(-pad_size[0]/2 - CrtYd_offset, CrtYd_grid)\n\n        cyb_bottom = roundToBase(body_edge['bottom'] + CrtYd_offset, CrtYd_grid)\n        cyb_mount_top = roundToBase(body_edge['bottom'] -6.2 - CrtYd_offset, CrtYd_grid)\n\n        poly_crtyd = [\n                {'x': B/2, 'y': cy1},\n                {'x': cxb_left, 'y': cy1},\n                {'x': cxb_left, 'y': cyb_mount_top},\n                {'x': cx1, 'y': cyb_mount_top},\n                {'x': cx1, 'y': cyb_bottom},\n                {'x': cxp_left, 'y': cyb_bottom},\n                {'x': cxp_left, 'y': cy2},\n                {'x': B/2, 'y': cy2},\n            ]\n        kicad_mod.append(PolygoneLine(\n            polygone=poly_crtyd,\n            layer='F.CrtYd', width=configuration['courtyard_line_width']))\n        kicad_mod.append(PolygoneLine(\n            polygone=poly_crtyd, x_mirror=B/2 if B/2 != 0 else 0.000000001,\n            layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_mini-fit_Jr_tht_top_dual-row.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\ndraw_inner_details = False\n\nseries = \"Mini-Fit_Jr\"\nseries_long = 'Mini-Fit Jr. Power Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\n\n\n#pins_per_row_per_row per row\npins_per_row_range = range(1,13)\n\n#Molex part number\n#n = number of circuits per row\nvariant_params = {\n    'peg':{\n        'mount_pins': 'plastic_peg',\n        'descriptive_name': 'Snap-in Plastic Peg PCB Lock',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/039289068_sd.pdf',\n        'part_code': {'mpn':\"39-28-9{n:02d}x\",'eng_num':\"5566-{n:02}A2\"},\n        },\n    'no-peg':{\n        'mount_pins': '',\n        'descriptive_name': '',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/039281043_sd.pdf',\n        'part_code': {'mpn':\"39-28-x{n:02d}x\",'eng_num':\"5566-{n:02}A\"},\n        }\n}\n\npitch = 4.2\ndrill = 1.4\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 1.5\nmax_annular_ring = 0.95\nmin_annular_ring = 0.15\n\n\nrow = 5.5\n\npad_size = [pitch - pad_to_pad_clearance, row - pad_to_pad_clearance]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\nif pad_size[1] - drill < 2*min_annular_ring:\n    pad_size[1] = drill + 2*min_annular_ring\nif pad_size[1] - drill > 2*max_annular_ring:\n    pad_size[1] = drill + 2*max_annular_ring\n\npad_shape = Pad.SHAPE_OVAL\nif pad_size[0] == pad_size[1]:\n    pad_shape = Pad.SHAPE_CIRCLE\n\n\ndef generate_one_footprint(pins_per_row, variant, configuration):\n    peg = variant_params[variant]['mount_pins'] == 'plastic_peg'\n\n    silk_pad_off = configuration['silk_pad_clearance']+configuration['silk_line_width']/2\n\n    mpn = variant_params[variant]['part_code']['mpn'].format(n=pins_per_row*2)\n    old_mpn = variant_params[variant]['part_code']['eng_num'].format(n=pins_per_row*2)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=old_mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    descr_format_str = \"Molex {:s}, old mpn/engineering number: {:s}, example for new mpn: {:s}, {:d} Pins per row, Mounting: {:s} ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(descr_format_str.format(\n        series_long, old_mpn, mpn, pins_per_row,\n        variant_params[variant]['descriptive_name'], variant_params[variant]['datasheet']))\n    tags = configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation])\n    tags += variant_params[variant]['mount_pins']\n    kicad_mod.setTags(tags)\n\n\n    #calculate fp dimensions\n\n    #connector length\n    A = pins_per_row * pitch + 1.2\n\n    #pin centers\n    B = (pins_per_row - 1) * pitch\n\n    #plasic pin-lock\n    C = A + 4\n\n    #connector width\n    W = 9.6\n\n    #corner positions\n    x1 = -(A-B)/2\n    x2 = x1 + A\n\n    y2 = row + 1.85\n    y1 = y2 - W\n\n    #tab length\n    tab_l = 3.4\n    #tab width\n    tab_w = 1.4\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n    bounding_box['bottom'] = body_edge['bottom'] + tab_w\n\n    off = configuration['silk_fab_offset']\n\n    #generate the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            pincount=pins_per_row, initial=row_idx*pins_per_row+1,\n            start=[0, row_idx*row], x_spacing=pitch,\n            type=Pad.TYPE_THT, shape=pad_shape,\n            size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    #add PCB locators if needed\n    pad_silk_offset = configuration['silk_pad_clearance']+configuration['silk_line_width']/2\n    if peg:\n        loc = 3.00\n        mounting_pin_y = row - 0.46\n        lx1 = B/2-C/2\n        lx2 = B/2+C/2\n        kicad_mod.append(Pad(at=[lx1, mounting_pin_y],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=loc,drill=loc, layers=Pad.LAYERS_NPTH))\n        kicad_mod.append(Pad(at=[lx2, mounting_pin_y],type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=loc,drill=loc, layers=Pad.LAYERS_NPTH))\n\n        bounding_box['left'] = lx1-loc/2\n        bounding_box['right'] = lx2+loc/2\n        ######################## Fab ############################\n        mount_pin_radius = loc/2\n\n        kicad_mod.append(Arc(center=[lx1,mounting_pin_y],\n            start=[lx1,mounting_pin_y+mount_pin_radius], angle=180,\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n        kicad_mod.append(Line(start=[lx1,mounting_pin_y-mount_pin_radius],\n            end=[x1,mounting_pin_y-mount_pin_radius],\n            layer='F.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(Line(start=[lx1,mounting_pin_y+mount_pin_radius],\n            end=[x1,mounting_pin_y+mount_pin_radius],\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n\n        kicad_mod.append(Arc(center=[lx2,mounting_pin_y],\n            start=[lx2,mounting_pin_y-mount_pin_radius], angle=180,\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n        kicad_mod.append(Line(start=[lx2,mounting_pin_y-mount_pin_radius],\n            end=[x2,mounting_pin_y-mount_pin_radius],\n            layer='F.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(Line(start=[lx2,mounting_pin_y+mount_pin_radius],\n            end=[x2,mounting_pin_y+mount_pin_radius],\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n        ######################## Silk ############################\n        mount_pin_radius = loc/2 + silk_pad_off\n        kicad_mod.append(Arc(center=[lx1,mounting_pin_y],\n            start=[lx1,mounting_pin_y+mount_pin_radius], angle=180,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Line(start=[lx1,mounting_pin_y-mount_pin_radius],\n            end=[x1-off,mounting_pin_y-mount_pin_radius],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[lx1,mounting_pin_y+mount_pin_radius],\n            end=[x1-off,mounting_pin_y+mount_pin_radius],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n        kicad_mod.append(Arc(center=[lx2,mounting_pin_y],\n            start=[lx2,mounting_pin_y-mount_pin_radius], angle=180,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Line(start=[lx2,mounting_pin_y-mount_pin_radius],\n            end=[x2+off,mounting_pin_y-mount_pin_radius],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[lx2,mounting_pin_y+mount_pin_radius],\n            end=[x2+off,mounting_pin_y+mount_pin_radius],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #draw the outline of the shape\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],layer='F.Fab',width=configuration['fab_line_width']))\n\n    #draw the outline of the tab\n    kicad_mod.append(PolygoneLine(polygone=[\n        {'x': B/2 - tab_l/2,'y': y2},\n        {'x': B/2 - tab_l/2,'y': y2 + tab_w},\n        {'x': B/2 + tab_l/2,'y': y2 + tab_w},\n        {'x': B/2 + tab_l/2,'y': y2},\n    ], layer='F.Fab', width=configuration['fab_line_width']))\n\n    #draw the outline of each pin slot (alternating shapes)\n    #slot size\n    S = 3.3\n\n    def square_slot(x,y):\n        kicad_mod.append(RectLine(start=[x-S/2,y-S/2], end=[x+S/2,y+S/2],\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n    def notch_slot(x,y):\n        kicad_mod.append(PolygoneLine(polygone=[\n        {'x': x-S/2, 'y': y+S/2},\n        {'x': x-S/2, 'y': y-S/4},\n        {'x': x-S/4, 'y': y-S/2},\n        {'x': x+S/4, 'y': y-S/2},\n        {'x': x+S/2, 'y': y-S/4},\n        {'x': x+S/2, 'y': y+S/2},\n        {'x': x-S/2, 'y': y+S/2},\n        ], layer='F.Fab', width=configuration['fab_line_width']))\n\n    q = 1\n    notch = True\n    for i in range(pins_per_row):\n        if notch:\n            y_square = row/2 - 4.2/2\n            y_notch = row/2 + 4.2/2\n        else:\n            y_square = row/2 + 4.2/2\n            y_notch = row/2 - 4.2/2\n\n        square_slot(i * pitch, y_square)\n        notch_slot(i*pitch, y_notch)\n\n        q -= 1\n\n        if (q == 0):\n            q = 2\n            notch = not notch\n\n\n    #draw the outline of the connector on the silkscreen\n    outline = [\n    {'x': B/2,'y': y1-off},\n    {'x': x1-off,'y': y1-off},\n    {'x': x1-off,'y': y2+off},\n    {'x': B/2 - tab_l/2 - off,'y': y2+off},\n    {'x': B/2 - tab_l/2 - off,'y': y2 + off + tab_w},\n    {'x': B/2, 'y': y2 + off + tab_w},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=outline, layer=\"F.SilkS\", width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=outline, x_mirror=B/2, layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    #pin-1 marker\n\n    L = 2.5\n    O = 0.35\n\n    pin = [\n        {'x': x1 + L,'y': y1 - O},\n        {'x': x1 - O,'y': y1 - O},\n        {'x': x1 - O,'y': y1 + L},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin, layer=\"F.SilkS\", width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=pin, width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n\n    cx1 = roundToBase(bounding_box['left'] - CrtYd_offset, CrtYd_grid)\n    cy1 = roundToBase(bounding_box['top'] - CrtYd_offset, CrtYd_grid)\n\n    cx2 = roundToBase(bounding_box['right'] + CrtYd_offset, CrtYd_grid)\n    cy2 = roundToBase(bounding_box['bottom'] + CrtYd_offset, CrtYd_grid)\n\n\n    if peg:\n        cx3 = roundToBase(body_edge['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n        cx4 = roundToBase(body_edge['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n        mount_pin_radius = loc/2\n        cy3=roundToBase(mounting_pin_y - mount_pin_radius - configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n        poly_crtyd = [\n            {'x': cx3, 'y': cy1},\n            {'x': cx3, 'y': cy3},\n            {'x': cx1, 'y': cy3},\n            {'x': cx1, 'y': cy2},\n            {'x': cx2, 'y': cy2},\n            {'x': cx2, 'y': cy3},\n            {'x': cx4, 'y': cy3},\n            {'x': cx4, 'y': cy1},\n            {'x': cx3, 'y': cy1}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_crtyd,\n            layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    else:\n        kicad_mod.append(RectLine(\n            start=[cx1, cy1], end=[cx2, cy2],\n            layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_nano-fit_tht_side.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Nano-Fit\"\nseries_long = 'Nano-Fit Power Connectors'\nmanufacturer = 'Molex'\norientation = 'H'\n\n#pins_per_row per row\npins_per_row_range = range(2,9)\n\n#Molex part number\n#n = number of circuits per row\n\n\npitch = 2.5\ndrill = 1.2\n\npitch_row = 2.5\n\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\nversion_params = {\n    'dual':{\n        'number_of_rows': 2,\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/1053141208_sd.pdf',\n        'mpn': \"105314-xx{n:02}\"\n    },\n    'single':{\n        'number_of_rows': 1,\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/1053131208_sd.pdf',\n        'mpn': \"105313-xx{n:02}\"\n    }\n}\n\ndef generate_one_footprint(pins, params, configuration):\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    mpn = params['mpn'].format(n=pins*params['number_of_rows'])\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=params['number_of_rows'], pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    desc_format_str = \"Molex {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(desc_format_str.format(series_long, mpn, pins, params['datasheet']))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    if params['number_of_rows'] == 2:\n        pad_size = [pitch_row - pad_to_pad_clearance, pitch - pad_to_pad_clearance]\n    else:\n        pad_size = [drill + 2*max_annular_ring, pitch - pad_to_pad_clearance]\n\n    if pad_size[1] - drill < 2*min_annular_ring:\n        pad_size[1] = drill + 2*min_annular_ring\n    if pad_size[1] - drill > 2*max_annular_ring:\n        pad_size[1] = drill + 2*max_annular_ring\n\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n    if pad_size[0] - drill > 2*max_annular_ring:\n        pad_size[0] = drill + 2*max_annular_ring\n\n    pad_shape=Pad.SHAPE_OVAL\n    if pad_size[0] == pad_size[1]:\n        pad_shape=Pad.SHAPE_CIRCLE\n\n    #A = connector length\n    A = pins * pitch + 0.94\n\n    #B = pin center distance\n    B = (pins - 1) * pitch\n\n    #W = thickness of plastic base\n    W = 8.46\n\n    #locating pin position\n    C = B\n\n    #corner positions for plastic housing outline\n    y1 = -(A-B)/2\n    y2 = y1 + A\n\n    x2 = (params['number_of_rows'] - 1) * pitch_row + 10.38\n    x1 = x2 - W\n\n    off = configuration['silk_fab_offset']\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n\n    bounding_box['left'] = -pad_size[0]/2\n\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    #generate the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for r in range(params['number_of_rows']):\n        kicad_mod.append(PadArray(\n            pincount=pins, initial=r*pins+1, start=[r*pitch_row,0],\n            y_spacing=pitch, type=Pad.TYPE_THT, shape=pad_shape,\n            size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    #add the locating pins\n    y_loc_a = B/2 - C/2\n    y_loc_b = B/2 + C/2\n    x_loc = (params['number_of_rows']-1)*pitch_row+7.18\n    r_loc = 1.7\n    kicad_mod.append(Pad(at=[x_loc,y_loc_a],size=r_loc,drill=r_loc,type=Pad.TYPE_NPTH,shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_NPTH))\n    kicad_mod.append(Pad(at=[x_loc,y_loc_b],size=r_loc,drill=r_loc,type=Pad.TYPE_NPTH,shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_NPTH))\n\n    #add outline to F.Fab\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],layer='F.Fab', width=configuration['fab_line_width']))\n\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],offset=off, width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    #draw the pins\n    for i in range(pins):\n        y = i * pitch\n        x = (params['number_of_rows'] - 1) * pitch_row + pad_size[0]/2 + pad_silk_off\n        w = 0.15\n        kicad_mod.append(RectLine(start=[x1-off,y+w],end=[x,y-w], width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    #pin-1 marker\n    y = - pad_size[1]/2- pad_silk_off\n    m = 0.3\n\n    pin = [\n    {'x': 0,'y': y},\n    {'x': m,'y': y-m*sqrt(2)},\n    {'x': -m,'y': y-m*sqrt(2)},\n    {'x': 0,'y': y},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin, width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n    kicad_mod.append(PolygoneLine(polygone=pin, width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for version in version_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, version_params[version], configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_nano-fit_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Nano-Fit\"\nseries_long = 'Nano-Fit Power Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\n\n#pins_per_row per row\npins_per_row_range = range(2,9)\n\n#Molex part number\n#n = number of circuits per row\n\n\npitch = 2.5\ndrill = 1.2\n\npitch_row = 2.5\n\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\nversion_params = {\n    'dual':{\n        'number_of_rows': 2,\n        'datasheet': \"http://www.molex.com/pdm_docs/sd/1053101208_sd.pdf\",\n        'mpn': \"105310-xx{n:02}\"\n    },\n    'single':{\n        'number_of_rows': 1,\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/1053091203_sd.pdf',\n        'mpn': \"105309-xx{n:02}\"\n    }\n}\n\ndef generate_one_footprint(pins, params, configuration):\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    mpn = params['mpn'].format(n=pins*params['number_of_rows'])\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=params['number_of_rows'], pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    desc_format_str = \"Molex {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(desc_format_str.format(series_long, mpn, pins, params['datasheet']))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    if params['number_of_rows'] == 2:\n        pad_size = [pitch_row - pad_to_pad_clearance, pitch - pad_to_pad_clearance]\n    else:\n        pad_size = [drill + 2*max_annular_ring, pitch - pad_to_pad_clearance]\n\n    if pad_size[1] - drill < 2*min_annular_ring:\n        pad_size[1] = drill + 2*min_annular_ring\n    if pad_size[1] - drill > 2*max_annular_ring:\n        pad_size[1] = drill + 2*max_annular_ring\n\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n    if pad_size[0] - drill > 2*max_annular_ring:\n        pad_size[0] = drill + 2*max_annular_ring\n\n    pad_shape=Pad.SHAPE_OVAL\n    if pad_size[0] == pad_size[1]:\n        pad_shape=Pad.SHAPE_CIRCLE\n\n    #A = connector length\n    A = pins * pitch + 0.94\n\n    #B = pin center distance\n    B = (pins - 1) * pitch\n\n    #W = thickness of plastic base\n    W = params['number_of_rows'] * pitch_row + 0.98\n\n    #locating pin position\n    if pins in [3,5,7]:\n        C = B/2 - 1.25\n    else:\n        C = B/2\n\n    #corner positions for plastic housing outline\n    y1 = -(A-B)/2\n    y2 = y1 + A\n\n    x2 = (params['number_of_rows'] - 1)* pitch_row+1.74\n    x1 = x2 - W\n\n    TL = 5.2\n    TW = 2.86\n\n    off = configuration['silk_fab_offset']\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n\n    bounding_box['left'] = body_edge['left']-TW\n\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    #generate the pads\n    if pins <= 3:\n        if configuration['kicad4_compatible']:\n            kicad_mod.append(Pad(number=1, at=[0, 0],\n                size=pad_size, drill=drill,\n                type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT))\n\n            kicad_mod.append(Pad(number=1, at=[0, -pad_size[1]/4],\n                size=[pad_size[0],pad_size[1]/2],\n                type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=['F.Cu', 'F.Mask']))\n            kicad_mod.append(Pad(number=1, at=[0, -pad_size[1]/4],\n                size=[pad_size[0],pad_size[1]/2],\n                type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=['B.Cu', 'B.Mask']))\n\n        else:\n            kicad_mod.append(ChamferedPad(number=1, at=[0, 0],\n                size=pad_size, drill=drill,\n                type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n                chamfer_size=0.4, radius_ratio=0.25, maximum_radius=0.25,\n                corner_selection=CornerSelection({CornerSelection.BOTTOM_LEFT:True})))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for r in range(params['number_of_rows']):\n        pincount = pins\n        initial = r*pins+1\n        start=[r*pitch_row, 0]\n        if r == 0 and pins <= 3:\n            pincount = pins -1\n            initial = 2\n            start=[0, pitch]\n\n        kicad_mod.append(PadArray(\n            pincount=pincount, initial=initial, start=start,\n            y_spacing=pitch, type=Pad.TYPE_THT, shape=pad_shape,\n            size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    #add the locating pin\n    kicad_mod.append(Pad(at=[-1.34, C], size=1.3, drill=1.3,\n        type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_NPTH))\n\n    #add outline to F.Fab\n    #kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],layer='F.Fab'))\n\n    #and to the silkscreen\n    #and draw the tab\n\n    def outline(off = 0, grid = 0):\n        out = [\n        {'y': roundToBase(B/2, grid),\n        'x': roundToBase(x2+off, grid)},\n        {'y': roundToBase(y1-off, grid),\n        'x': roundToBase(x2+off, grid)},\n        {'y': roundToBase(y1-off, grid),\n        'x': roundToBase(x1-off, grid)},\n        {'y': roundToBase(B/2-TL/2-off, grid),\n        'x': roundToBase(x1-off, grid)},\n        {'y': roundToBase(B/2-TL/2-off, grid),\n        'x': roundToBase(x1-TW-off, grid)},\n        {'y': roundToBase(B/2, grid),\n        'x': roundToBase(x1-TW-off, grid)}\n        ]\n\n        return out\n\n    kicad_mod.append(PolygoneLine(polygone=outline(), layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=outline(), layer='F.Fab', width=configuration['fab_line_width'], y_mirror=B/2))\n\n    kicad_mod.append(PolygoneLine(polygone=outline(off = off), layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=outline(off = off), layer='F.SilkS', width=configuration['silk_line_width'], y_mirror=B/2))\n\n    CrtYd_off = configuration['courtyard_offset']['connector']\n    kicad_mod.append(PolygoneLine(\n        polygone=outline(off = CrtYd_off, grid=configuration['courtyard_grid']),\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(PolygoneLine(\n        polygone=outline(off = CrtYd_off, grid=configuration['courtyard_grid']),\n        layer='F.CrtYd', width=configuration['courtyard_line_width'], y_mirror=B/2))\n\n    # draw the tab\n    kicad_mod.append(RectLine(start=[x1+2*off, B/2-TL/2],end=[x1-TW, B/2+TL/2],\n        offset=-0.5, width=configuration['fab_line_width'], layer='F.Fab'))\n\n    #draw the pins!\n    # o = 0.475 * pitch\n    # for i in range(pins):\n    #     for j in range(params['number_of_rows']):\n    #         y = i * pitch\n    #         x = j * pitch\n    #\n    #         kicad_mod.append(RectLine(start=[x-o,y-o],end=[x+o,y+o], layer='F.Fab', width=configuration['fab_line_width']))\n\n    #pin-1 marker\n    p1m_off = configuration['silk_fab_offset'] + 0.3\n    p1m_b = B/2-TL/2 - off\n    if p1m_b > 0:\n        p1m_b = 0\n\n    pin = [\n    {'x': 0,'y': body_edge['top'] - p1m_off},\n    {'x': body_edge['left'] - p1m_off,'y': body_edge['top'] - p1m_off},\n    {'x': body_edge['left'] - p1m_off,'y': p1m_b}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    sl=1\n    pin = [\n        {'y': body_edge['top'], 'x': -sl/2},\n        {'y': body_edge['top'] + sl/sqrt(2), 'x': 0},\n        {'y': body_edge['top'], 'x': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':bounding_box['top'] - CrtYd_off, 'bottom':bounding_box['bottom'] + CrtYd_off}, fp_name=footprint_name, text_y_inside_position='right')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for version in version_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, version_params[version], configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_picoblade_tht_side.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"PicoBlade\"\nseries_long = 'PicoBlade Connector System'\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'http://www.molex.com/pdm_docs/sd/530480210_sd.pdf'\n\n#pins_per_row per row\npins_per_row_range = range(2,16)\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"53048-{n:02}10\"\n\npitch = 1.25\ndrill = 0.5\n\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.4\nmin_annular_ring = 0.15\n\n\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\n\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_code.format(n=pins)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n\n    B = (pins - 1) * pitch\n    C = B + 1.8\n    A = B + 3\n\n    #connector width\n    W = 5.5\n\n    #corner positions\n    x1 = (B-A) / 2\n    x2 = x1 + A\n\n    y1 = -1.05\n    y2 = y1 + W\n\n    # distance from pins in y dir\n    P = 0.75\n\n    # thickness of end bosses\n    T = 0.85\n\n    off = configuration['silk_fab_offset']\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': -P\n        }\n    bounding_box = body_edge.copy()\n\n    # generate the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(start=[0,0], pincount=pins, x_spacing=pitch,\n        type=Pad.TYPE_THT, shape=pad_shape, size=pad_size,\n        drill=drill, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    #pin-1 marker\n    o = 0.4\n    pin1 = [\n    {'x': x1 + T + o,'y': -P - o},\n    {'x': x1 + T + o,'y': y1 - o},\n    {'x': x1 + T + o - 0.5,'y': y1 - o},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin1,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    sl=1\n    pin = [\n        {'y': body_edge['top'], 'x': -sl/2},\n        {'y': body_edge['top'] + sl/sqrt(2), 'x': 0},\n        {'y': body_edge['top'], 'x': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    #component outline (configurable offset)\n    def outline(off = 0, grid = 0):\n\n\n        out = [\n        {'x': roundToBase(B/2, grid),\n         'y': roundToBase(-P - off, grid)},\n        {'x': roundToBase(x1 + T + off, grid),\n         'y': roundToBase(-P  - off, grid)},\n        {'x': roundToBase(x1 + T + off, grid),\n         'y': roundToBase(y1 - off, grid)},\n        {'x': roundToBase(x1 - off, grid),\n         'y': roundToBase(y1 - off, grid)},\n        {'x': roundToBase(x1 - off, grid),\n         'y': roundToBase(y2 + off, grid)},\n        {'x': roundToBase(B/2, grid),\n         'y': roundToBase(y2 + off, grid)},\n        ]\n\n        return out\n\n    #courtyard\n    CrtYd_off = configuration['courtyard_offset']['connector']\n    grid = configuration['courtyard_grid']\n    kicad_mod.append(PolygoneLine(polygone=outline(off=CrtYd_off, grid=grid),\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=outline(off=CrtYd_off, grid=grid),\n        layer='F.CrtYd', width=configuration['courtyard_line_width'], x_mirror=B/2))\n\n    #outline F.Fab\n    kicad_mod.append(PolygoneLine(polygone=outline(),\n        layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=outline(),\n        layer='F.Fab', width=configuration['fab_line_width'], x_mirror=B/2))\n\n    #outline F.SilkS\n    kicad_mod.append(PolygoneLine(polygone=outline(off=off),\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=outline(off=off), x_mirror=B/2,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':bounding_box['top']-CrtYd_off,\n            'bottom':bounding_box['bottom']+CrtYd_off},\n        fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_picoblade_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"PicoBlade\"\nseries_long = 'PicoBlade Connector System'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.molex.com/pdm_docs/sd/530470610_sd.pdf'\n\n#pins_per_row per row\npins_per_row_range = range(2,16)\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"53047-{n:02}10\"\n\npitch = 1.25\ndrill = 0.5\n\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.4\nmin_annular_ring = 0.15\n\n\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\n\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_code.format(n=pins)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    A = (pins - 1) * pitch\n    B = A + 1.8\n    C = A + 3\n\n    #connector width\n    W = 3.2\n\n    #side thickness\n    T = 0.4\n\n    #corner positions\n    x1 = (A - C) / 2\n    x2 = x1 + C\n\n    y2 = 1.15\n    y1 = y2 - W\n\n    off = configuration['silk_fab_offset']\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n\n    # generate the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(start=[0,0], pincount=pins, x_spacing=pitch,\n        type=Pad.TYPE_THT, shape=pad_shape, size=pad_size, drill=drill,\n        layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    # outline on Fab\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    # outline on SilkScreen\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],offset=off,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    inline = [\n    {'x': A/2,'y': y2 - T},\n    {'x': x1 + T,'y': y2 - T},\n    {'x': x1 + T,'y': 0},\n    {'x': x1 + T/2,'y': 0},\n    {'x': x1 + T/2,'y': -2*T},\n    {'x': x1 + T,'y': -2*T},\n    {'x': x1 + T,'y': y1 + T},\n    {'x': A/2,'y': y1 + T},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=inline,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=inline, x_mirror=A/2,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #pin-1 mark\n\n    L = 1\n    kicad_mod.append(Line(start=[x1-0.4,y2+0.4], end=[x1-0.4,y2+0.4-L],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(Line(start=[x1-0.4,y2+0.4], end=[x1-0.4+L,y2+0.4],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    sl=1\n    pin = [\n        {'y': body_edge['bottom'], 'x': -sl/2},\n        {'y': body_edge['bottom'] - sl/sqrt(2), 'x': 0},\n        {'y': body_edge['bottom'], 'x': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2},\n        fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_picoflex_smd_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Picoflex\"\nseries_long = 'Picoflex Ribbon-Cable Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'http://www.molex.com/pdm_docs/sd/908140004_sd.pdf'\n\n#pins_per_row per row\npins_range = (4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26)\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"90814-00{n:02}\"\n\npitch = 1.27\npitch_row = 2.54\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_code.format(n=pins)\n\n    CrtYd_off = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n    body_edge = {}\n    bounding_box = {}\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins//2, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pins, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    kicad_mod.setAttribute('smd')\n\n    #\n    # Draw all graphical objects\n    #\n    BodyWidth = 4.1\n    BodyHeight = ((pins - 1) * pitch) + (2 * 2.525)\n    #\n    HalfBodyWidth = BodyWidth / 2\n    HalfBodyHeight = BodyHeight / 2\n\n    PadWidth = 2\n    PadHeight = 1.2\n\t#\n    AllPadsWidth = 6\n    AllPadsHeight = ((pins - 1) * pitch)\n    #\n    HalfAllPadsWidth = AllPadsWidth / 2\n    HalfAllPadsHeight = AllPadsHeight / 2\n\n    GuideHoleDrillSize = 1.9\n\n    GuideHoleX1 = 1.1 - HalfAllPadsWidth\n    GuideHoleY1 = -1.925 - HalfAllPadsHeight\n\n    GuideHoleX1 = 1.1 - HalfAllPadsWidth\n    GuideHoleY2 = 1.925 + HalfAllPadsHeight\n\n    KeepOutAreaWidth = 7.9\n    KeepOutAreaHeight = BodyHeight\n\n    body_edge['right'] = HalfBodyWidth\n    body_edge['left'] = -HalfBodyWidth\n    body_edge['top'] = -HalfBodyHeight\n    body_edge['bottom'] = HalfBodyHeight\n\n    bounding_box['right'] = HalfAllPadsWidth + PadWidth/2\n    bounding_box['left'] = -bounding_box['right']\n    bounding_box['bottom'] = GuideHoleY2 + GuideHoleDrillSize/2 + 0.175\n    bounding_box['top'] = -bounding_box['bottom']\n    #\n    # Generate the pads\n    #\n    tpc = int(pins / 2)\n    kicad_mod.append(PadArray(\n        start=[round(0 - HalfAllPadsWidth, 2), round(0 - HalfAllPadsHeight, 2)],\n        pincount=tpc, initial=1, increment=2, x_spacing=0, y_spacing=2*pitch,\n        size=[PadWidth, PadHeight], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n        layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(\n        start=[round(HalfAllPadsWidth, 2), round(pitch - HalfAllPadsHeight, 2)],\n        pincount=tpc, initial=2, increment=2, x_spacing=0,  y_spacing=2*pitch,\n        size=[PadWidth, PadHeight], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n        layers=Pad.LAYERS_SMT))\n\n    #\n    # Generate the drill holes\n    #\n    kicad_mod.append(Pad(at=[GuideHoleX1, GuideHoleY1],type=Pad.TYPE_NPTH,\n        shape=Pad.SHAPE_CIRCLE, size=GuideHoleDrillSize,\n        drill=GuideHoleDrillSize, layers=Pad.LAYERS_NPTH))\n    kicad_mod.append(Pad(at=[GuideHoleX1, GuideHoleY2],type=Pad.TYPE_NPTH,\n        shape=Pad.SHAPE_CIRCLE, size=GuideHoleDrillSize,\n        drill=GuideHoleDrillSize, layers=Pad.LAYERS_NPTH))\n\n    #\n    # Add the Fab line\n    #\n    # Start in upper right corner\n    x1 = HalfBodyWidth\n    y1 = 0 - HalfBodyHeight\n    x2 = x1\n    y2 = y1 + BodyHeight\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    #\n    # Bottom line to bottom drill hole\n    x1 = x2\n    y1 = y2\n    x2 = GuideHoleX1 + (GuideHoleDrillSize / 2)\n    y2 = y2\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    # Arc around bottom drill hole\n    ccx = GuideHoleX1\n    ccy = GuideHoleY2\n    csx = x2\n    csy = HalfAllPadsHeight + 2.525\n    kicad_mod.append(Arc(\n        center=[round(ccx, 2), round(ccy, 2)], start=[round(csx, 2), round(csy, 2)],\n        angle=230.0, layer='F.Fab', width=configuration['fab_line_width']))\n    # Left line from bottom drill hole to top drill hole including the Fab Pin 1 marker\n    x1 = -HalfBodyWidth\n    y1 = GuideHoleY2 - (GuideHoleDrillSize / 2) - 0.17\n    x2 = x1\n    y2 = 0 - (HalfAllPadsHeight - (PadHeight / 2))\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    x1 = x2\n    y1 = y2\n    x2 = x1 + (PadHeight / 2)\n    y2 = y2 - (PadHeight / 2)\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    x1 = x2\n    y1 = y2\n    x2 = x1 - (PadHeight / 2)\n    y2 = y2 - (PadHeight / 2)\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    x1 = x2\n    y1 = y2\n    x2 = x1\n    y2 = GuideHoleY1 + (GuideHoleDrillSize / 2) + 0.17\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    # Arc around top drill hole\n    ccx = GuideHoleX1\n    ccy = GuideHoleY1\n    csx = x1\n    csy = y2\n    kicad_mod.append(Arc(\n        center=[round(ccx, 2), round(ccy, 2)], start=[round(csx, 2), round(csy, 2)],\n        angle=230.0, layer='F.Fab', width=configuration['fab_line_width']))\n    # Top line to top drill hole\n    x1 = HalfBodyWidth\n    y1 = 0 - HalfBodyHeight\n    x2 = GuideHoleX1 + (GuideHoleDrillSize / 2) + 0.02\n    y2 = y1\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    #\n    # Add the Silk line\n    #\n    # Start in upper right corner\n    x1 = HalfBodyWidth + 0.13\n    y1 = 0 - HalfBodyHeight - 0.13\n    x2 = x1\n    y2 = 0 - ((HalfAllPadsHeight - pitch) + (PadHeight / 2) + 0.3)\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    y1 = 0 - ((HalfAllPadsHeight - pitch) - (PadHeight / 2) - 0.4)\n    y2 = 0 - ((HalfAllPadsHeight - (3 *pitch)) + (PadHeight / 2) + 0.4)\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    if (pins > 3):\n        for halfpins in range(int((pins / 2)) - 2):\n            y1 = y1 + (2 * pitch)\n            y2 = y2 + (2 * pitch)\n            kicad_mod.append(PolygoneLine(\n                polygone=[[round(x1, 2), round(y1 + 0.06, 2)],\n                    [round(x2, 2), round(y2 - 0.06, 2)]],\n                layer='F.SilkS', width=configuration['silk_line_width']))\n\n    x1 = x1\n    y1 = HalfAllPadsHeight + (PadHeight / 2) + 0.3\n    x2 = HalfBodyWidth + 0.13\n    y2 = HalfBodyHeight + 0.13\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    #\n    # Bottom line to bottom drill hole\n    x1 = x2\n    y1 = y2\n    x2 = GuideHoleX1 + (GuideHoleDrillSize / 2) + 0.1\n    y2 = y2\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    # Arc around bottom drill hole\n    ccx = GuideHoleX1\n    ccy = GuideHoleY2\n    csx = x2\n    csy = y2\n    kicad_mod.append(Arc(\n        center=[round(ccx, 2), round(ccy, 2)], start=[round(csx, 2), round(csy, 2)],\n        angle=222.8, layer='F.SilkS', width=configuration['silk_line_width']))\n    # Left line from bottom drill hole to top drill hole\n    x1 = -HalfBodyWidth - 0.13\n    y1 = GuideHoleY2 - (GuideHoleDrillSize / 2) - 0.3\n    x2 = x1\n    y2 = y1 - 0.5\n    y2 = HalfAllPadsHeight - pitch + (PadHeight / 2) + 0.3\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    y1 = ((HalfAllPadsHeight - pitch) - (PadHeight / 2) - 0.4)\n    y2 = ((HalfAllPadsHeight - (3 *pitch)) + (PadHeight / 2) + 0.4)\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    # Add small lines between pads\n    if (pins > 3):\n        for halfpins in range(int((pins / 2)) - 2):\n            y1 = y1 - (2 * pitch)\n            y2 = y2 - (2 * pitch)\n            kicad_mod.append(PolygoneLine(\n                polygone=[[round(x1, 2), round(y1 + 0.06, 2)],\n                    [round(x2, 2), round(y2 - 0.06, 2)]],\n                layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n    # Arc around top drill hole\n    y2 = GuideHoleY1 + (GuideHoleDrillSize / 2) + 0.3\n    ccx = GuideHoleX1\n    ccy = GuideHoleY1\n    csx = x1 - 0.63\n    csy = y2 -0.35\n    #\n    # xxx, yyy is the new pin 1 marker\n    #\n    xxx1 = csx\n    yyy1 = csy\n    xxx2 = xxx1\n    yyy2 = 0 - (HalfAllPadsHeight + (PadHeight / 2) + 0.3)\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(xxx1, 2), round(yyy1, 2)], [round(xxx2, 2), round(yyy2, 2)]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    xxx1 = xxx2\n    yyy1 = yyy2\n    xxx2 = 0 - (HalfAllPadsWidth + (PadWidth / 2))\n    yyy2 = yyy1\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(xxx1, 2), round(yyy1, 2)], [round(xxx2, 2), round(yyy2, 2)]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    #\n    kicad_mod.append(Arc(\n        center=[round(ccx, 2), round(ccy, 2)], start=[round(csx, 2), round(csy, 2)],\n        angle=191.0, layer='F.SilkS', width=configuration['silk_line_width']))\n    # Top line to top drill hole\n    x1 = HalfBodyWidth + 0.13\n    y1 = 0 - HalfBodyHeight - 0.13\n    x2 = GuideHoleX1 + (GuideHoleDrillSize / 2) + 0.13\n    y2 = y1\n    kicad_mod.append(PolygoneLine(\n        polygone=[[round(x1, 2), round(y1, 2)], [round(x2, 2), round(y2, 2)]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #\n    # Add the pin 1 marker\n    #\n    # Start in upper right corner\n#        x1 = 0 - (HalfAllPadsWidth + (PadWidth / 2) + 0.25 + 0.25)\n#        y1 = 0 - HalfAllPadsHeight - 1\n#        x2 = x1\n#        y2 = round(y1 + 3, 0)\n#        kicad_mod.append(PolygoneLine(polygone=[[round(x1, 2), round(y1, 2)],        [round(x2, 2),        round(y2, 2)]],        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #\n    # Add the keep out area\n    #\n    x1 = 0 - (KeepOutAreaWidth / 2)\n    y1 = 0 - (KeepOutAreaHeight / 2)\n    x2 = x1 + KeepOutAreaWidth\n    y2 = y1 + KeepOutAreaHeight\n    kicad_mod.append(RectLine(start=[round(x1, 2), round(y1, 2)],\n        end=[round(x2, 2), round(y2, 2)], layer='Dwgs.User', width=0.1))\n    kicad_mod.append(Text(type='user', text='KEEPOUT',\n        at=[0,0], rotation=90,\n        layer='Cmts.User'))\n    x1 = 0 - (KeepOutAreaWidth / 2)\n    y1 = 0 - (KeepOutAreaHeight / 2)\n    x2 = 0 - (KeepOutAreaWidth / 2)\n    y2 = 0 - (KeepOutAreaHeight / 2)\n    GridDelta = 2 * pitch\n    dx1 = 0\n    dy1 = GridDelta\n    yy1 = y1;\n    while (x1 < (KeepOutAreaWidth / 2)):\n        y1 = y1 + GridDelta\n        yy1 = yy1 + dy1\n        if (y1 > ((KeepOutAreaHeight / 2))):\n            yy1 = (KeepOutAreaHeight / 2)\n            dy1 = 0\n            dx1 = y1 - (KeepOutAreaHeight / 2)\n            x1 = (0 - (KeepOutAreaWidth / 2)) + dx1\n        x2 = x2 + GridDelta\n        if (x2 >= ((KeepOutAreaWidth / 2))):\n            x2 = (KeepOutAreaWidth / 2)\n            y2 = y1 - KeepOutAreaWidth\n        if (x1 < (KeepOutAreaWidth / 2)):\n            kicad_mod.append(PolygoneLine(\n                polygone=[[round(x1, 2), round(yy1, 2)],\n                    [round(x2, 2), round(y2, 2)]],\n                layer='Dwgs.User',width=0.1))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2},\n        fp_name=footprint_name, text_y_inside_position='left')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for pins in pins_range:\n        generate_one_footprint(pins, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_picoflex_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Picoflex\"\nseries_long = 'Picoflex Ribbon-Cable Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'http://www.molex.com/pdm_docs/sd/903250004_sd.pdf'\n\n#pins_per_row per row\npins_range = (4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26)\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"90325-00{n:02}\"\n\npitch = 1.27\npitch_row = 2.54\ndrill = 0.8\n\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\n\n\npad_size = [drill + 0.5*2, drill + 0.25*2]\npad_shape = Pad.SHAPE_OVAL\n\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_code.format(n=pins)\n\n    CrtYd_off = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n    body_edge = {}\n    bounding_box = {}\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins//2, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pins, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    GuideHoleDrillSize = 1.5\n\n    GuideHoleX1 = -1.48\n    GuideHoleY1 = -1.8\n\n    GuideHoleY2 = (pins - 1) * pitch - GuideHoleY1\n\n    StartFX = GuideHoleX1\n    StartFY = 0 - 2.755\n\n    # generate the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    tpc = int(pins / 2)\n    for row_idx in range(2):\n        kicad_mod.append(PadArray(\n            start=[2*row_idx*pitch, row_idx*pitch], pincount=tpc, initial=row_idx+1,\n            increment=2, x_spacing=0,  y_spacing=2*pitch, type=Pad.TYPE_THT,\n            shape=pad_shape, size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    # Generate the drill holes\n    stx = (pins - 1) * pitch + 1.8\n    kicad_mod.append(Pad(at=[GuideHoleX1, GuideHoleY1],type=Pad.TYPE_NPTH,\n        shape=Pad.SHAPE_CIRCLE, size=GuideHoleDrillSize,\n        drill=GuideHoleDrillSize, layers=Pad.LAYERS_NPTH))\n    kicad_mod.append(Pad(at=[GuideHoleX1, GuideHoleY2],type=Pad.TYPE_NPTH,\n        shape=Pad.SHAPE_CIRCLE, size=GuideHoleDrillSize,\n        drill=GuideHoleDrillSize, layers=Pad.LAYERS_NPTH))\n\n\n    #\n    # Top lines\n    #\n    x1 = StartFX\n    y1 = StartFY\n    x2 = x1 + 5\n    y2 = y1\n    kicad_mod.append(PolygoneLine(\n        polygone=[[x1, y1], [x2, y2]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(\n        polygone=[[x1, y1 - 0.13], [x2 + 0.13, y2 - 0.13]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    body_edge['top'] = y1\n    bounding_box['top'] = y1\n\n    #\n    # Right lines\n    #\n    x1 = x2\n    y1 = y2\n    x2 = x2\n    y2 = ((pins - 1) * pitch) + 2.755\n    kicad_mod.append(PolygoneLine(\n        polygone=[[x1, y1], [x2, y2]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(\n        polygone=[[x1 + 0.13, y1 - 0.13], [x2 + 0.13, y2 + 0.13]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    body_edge['right'] = x1\n    bounding_box['right'] = x1\n\n    #\n    # Bottom lines\n    #\n    x1 = x2\n    y1 = y2\n    x2 = StartFX\n    y2 = y2\n    kicad_mod.append(PolygoneLine(\n        polygone=[[x1, y1], [x2, y2]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(\n        polygone=[[x1 + 0.13, y1 + 0.13], [x2, y2 + 0.13]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    body_edge['bottom'] = y1\n    bounding_box['bottom'] = y1\n\n    #\n    # Upper arcs\n    #\n    ccx = GuideHoleX1\n    ccy = GuideHoleY1\n    csx = GuideHoleX1\n    csy = -0.85\n    kicad_mod.append(Arc(center=[ccx, ccy], start=[csx, csy], angle=180,\n        layer='F.Fab', width=configuration['fab_line_width']))\n    ccx = GuideHoleX1\n    ccy = GuideHoleY1\n    csx = -1.61\n    csy = -0.72\n    kicad_mod.append(Arc(center=[ccx, ccy], start=[csx, csy], angle=180,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    #\n    # Left lines\n    #\n    x1 = GuideHoleX1\n    y1 = GuideHoleY1 + (GuideHoleY1 - StartFY)\n    x2 = GuideHoleX1\n    y2 = GuideHoleY2 - (GuideHoleY1 - StartFY)\n    x3 = 2\n    y3 = -0.5\n    kicad_mod.append(PolygoneLine(polygone=[[x1,y1], [x2, -0.5]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[[x2, -0.5], [x2 + 0.5, 0]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[[x2 + 0.5, 0], [x2, 0.5]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=[[x2, 0.5], [x2, y2]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    kicad_mod.append(PolygoneLine(\n        polygone=[[x1 - 0.13, y1 + 0.13], [x2 - 0.13, y2 - 0.13]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    body_edge['left'] = x1\n\n    #\n    # Bottom arcs\n    #\n    ccx = GuideHoleX1\n    ccy = GuideHoleY2\n    csx = GuideHoleX1\n    csy = ((pins - 1) * pitch) + 2.755\n    radius = abs(csy - ccy)\n    kicad_mod.append(Arc(center=[ccx, ccy], start=[csx, csy], angle=180,\n        layer='F.Fab', width=configuration['fab_line_width']))\n    bounding_box['left'] = ccx - radius\n\n    ccx = GuideHoleX1\n    ccy = GuideHoleY2\n    csx = -1.47\n    csy = ((pins - 1) * pitch) + 2.755 + 0.13\n    kicad_mod.append(Arc(center=[ccx, ccy], start=[csx, csy], angle=170,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    # pin 1\n    x = body_edge['left'] - 0.3\n    m = 0.3\n\n    pin = [\n    {'x': x,'y': 0},\n    {'x': x-2*m,'y': -m},\n    {'x': x-2*m,'y': +m},\n    {'x': x,'y': 0},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['silk_line_width'], layer='F.SilkS'))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2},\n        fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins in pins_range:\n        generate_one_footprint(pins, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_sabre_tht_side.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Sabre\"\nseries_long = 'Sabre Power Connector'\nmanufacturer = 'Molex'\norientation = 'H'\nnumber_of_rows = 1\n\n\n#pins_per_row per row\npins_per_row_range = [2, 3, 4, 5, 6]\n\n#Molex part number\n#n = number of circuits per row\n\npitch = 7.49\ndrill = 1.78\n\noffset_second_pad = 3.18\n\npad_to_pad_clearance = 3\nmax_annular_ring = 1\nmin_annular_ring = 0.15\n\n#locating pins\nret_dy = 13.13\nret_dx = 4.75\nret_drill = 3.00\nret_size = 4.00\n\n\n\npad_size = [pitch - pad_to_pad_clearance, offset_second_pad + 0.25]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\nversion_params = {\n    'with_thermals_lock':{\n        'mpn': '43160-11{n:02d}',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/431605304_sd.pdf',\n        'description': ', With thermal vias in pads',\n        'fp_name_suffix': '_ThermalVias',\n        'thermals': True,\n        'lock': True\n    },\n    'only_pads_lock':{\n        'mpn': '43160-11{n:02d}',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/431605304_sd.pdf',\n        'description': '',\n        'fp_name_suffix': '',\n        'thermals': False,\n        'lock': True\n    },\n    'with_thermals':{\n        'mpn': '46007-11{n:02d}',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/460071105_sd.pdf',\n        'description': ', With thermal vias in pads',\n        'fp_name_suffix': '_ThermalVias',\n        'thermals': True,\n        'lock': False\n    },\n    'only_pads':{\n        'mpn': '46007-11{n:02d}',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/460071105_sd.pdf',\n        'description': '',\n        'fp_name_suffix': '',\n        'thermals': False,\n        'lock': False\n    }\n}\n\n\n\ndef generate_one_footprint(pins, params, configuration):\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    off = configuration['silk_fab_offset']\n\n    mpn = params['mpn'].format(n=pins*number_of_rows)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n    footprint_name += params['fp_name_suffix']\n\n    kicad_mod = Footprint(footprint_name)\n    desc_format_str = \"Molex {:s}, {:s}{:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(desc_format_str.format(series_long, mpn, params['description'], pins, params['datasheet']))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n\n    # Dimensions\n    P = (pins - 1) * pitch\n    B = P + 2*6.79 # connector length\n    W = 14.76 # connector width\n\n    body_edge={}\n    body_edge['left'] = (P-B)/2\n    body_edge['right'] = body_edge['left'] + B\n    body_edge['top'] =  0.925\n    body_edge['bottom'] = body_edge['top'] + 14.76\n\n    bounding_box = body_edge.copy()\n    bounding_box['top'] = -offset_second_pad - pad_size[1]/2\n\n    ##################################  Pins ##################################\n    kicad_mod.append(PadArray(pincount=pins, start=[0,0],\n        x_spacing=pitch, size=pad_size, drill=drill,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, layers=Pad.LAYERS_THT))\n    kicad_mod.append(PadArray(pincount=pins, start=[0, -offset_second_pad],\n        x_spacing=pitch, size=pad_size, drill=drill,\n        shape=Pad.SHAPE_RECT, type=Pad.TYPE_THT, layers=Pad.LAYERS_THT))\n\n    d_small = 0.3\n    s_small = d_small + 2*min_annular_ring\n    thermal_to_pad_edge = s_small/2 + 0.15\n\n    if params['thermals']:\n        for xi in range(pins):\n            n = xi + 1\n            pad_center_y = -offset_second_pad/2\n            pad_center_x = xi*pitch\n            pad_h = offset_second_pad + pad_size[1]\n            dx = (pad_size[0] - 2*thermal_to_pad_edge)/2\n            dy = (pad_h - 2*thermal_to_pad_edge)/4\n\n            #draw rectangle on F.Fab layer\n\n            # kicad_mod.append(RectLine(\n            #     start=[pad_center_x - pad_l/2, pad_center_y - pad_size[1]/2],\n            #     end=[pad_center_x + pad_l/2, pad_center_y + pad_size[1]/2],\n            #     layer='F.Fab', width=configuration['fab_line_width']))\n\n            kicad_mod.append(PadArray(center=[pad_center_x, pad_center_y],\n                pincount=3, y_spacing=dy*2,\n                drill=d_small, size=s_small, initial=n, increment=0,\n                shape=Pad.SHAPE_CIRCLE, type=Pad.TYPE_THT, layers=Pad.LAYERS_THT))\n            kicad_mod.append(PadArray(center=[pad_center_x - dx, pad_center_y],\n                pincount=5, y_spacing=dy,\n                drill=d_small, size=s_small, initial=n, increment=0,\n                type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_THT))\n            kicad_mod.append(PadArray(center=[pad_center_x + dx, pad_center_y],\n                pincount=5, y_spacing=dy,\n                drill=d_small, size=s_small, initial=n, increment=0,\n                type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_THT))\n\n    if params['lock']:\n        kicad_mod.append(Pad(at=[-ret_dx, ret_dy], type=Pad.TYPE_THT,\n            shape=Pad.SHAPE_CIRCLE, size=ret_size, drill=ret_drill, layers=Pad.LAYERS_THT))\n        kicad_mod.append(Pad(at=[P+ret_dx, ret_dy], type=Pad.TYPE_THT,\n            shape=Pad.SHAPE_CIRCLE, size=ret_size, drill=ret_drill, layers=Pad.LAYERS_THT))\n\n    kicad_mod.append(RectLine(start=[-pad_size[0]/2, -offset_second_pad-pad_size[1]/2],\n        end=[pad_size[0]/2,pad_size[1]/2],offset=pad_silk_off,\n        width=configuration['silk_line_width'], layer='B.SilkS'))\n\n    ############################ Outline ##############################\n    #kicad_mod.append(RectLine(start=[xl1, yt1], end=[xr1, yb1], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(RectLine(\n        start=[body_edge['left'], body_edge['top']],\n        end=[body_edge['right'], body_edge['bottom']],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    if params['lock']:\n        silk1 = [\n            {'x': -pad_size[0]/2 - pad_silk_off, 'y': body_edge['top']-off},\n            {'x': body_edge['left']-off, 'y': body_edge['top']-off},\n            {'x': body_edge['left']-off, 'y': ret_dy-ret_size/2},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=silk1, layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=silk1, layer='F.SilkS', width=configuration['silk_line_width'], x_mirror=P/2))\n        silk2 = [\n            {'x': body_edge['left']-off, 'y': ret_dy+ret_size/2},\n            {'x': body_edge['left']-off, 'y': body_edge['bottom']+off},\n            {'x': P/2, 'y': body_edge['bottom']+off},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=silk2,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=silk2,\n            layer='F.SilkS', width=configuration['silk_line_width'], x_mirror=P/2))\n    else:\n        kicad_mod.append(RectLine(\n            start=[body_edge['left'], body_edge['top']],\n            end=[body_edge['right'], body_edge['bottom']],\n            offset = off,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    for i in range(pins - 1):\n        kicad_mod.append(Line(\n            start=[i*pitch+pad_size[0]/2+pad_silk_off, body_edge['top']-off],\n            end=[(i+1)*pitch-pad_size[0]/2-pad_silk_off, body_edge['top']-off],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    for i in range(pins):\n        w_pin = 1\n        kicad_mod.append(RectLine(start=[i*pitch-w_pin/2, body_edge['top']],\n        end=[i*pitch+w_pin/2, -offset_second_pad-drill/2],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    ############################ Pin 1 ################################\n    # Pin 1 designator\n    pin1_sl = 2.4\n    pin1 = [\n        {'x': -pin1_sl/2, 'y': body_edge['top']},\n        {'x': 0, 'y': body_edge['top'] + pin1_sl/sqrt(2)},\n        {'x': pin1_sl/2, 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin1,\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    pin1 = [\n        {'x': -pad_size[0]/2 - pad_silk_off, 'y': body_edge['top']-off},\n        {'x': -pad_size[0]/2 - pad_silk_off, 'y': -offset_second_pad-pad_size[1]/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin1, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    # pin1 = [\n    #     {'x': 0, 'y': 8},\n    #     {'x': 0.5, 'y': 9},\n    #     {'x': -0.5, 'y': 9},\n    #     {'x': 0, 'y': 8},\n    # ]\n    # kicad_mod.append(PolygoneLine(polygone=pin1, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n    for version in version_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, version_params[version], configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_sabre_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"Sabre\"\nseries_long = 'Sabre Power Connector'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 1\n\n\n#pins_per_row per row\npins_per_row_range = [2, 3, 4, 5, 6]\n\n#Molex part number\n#n = number of circuits per row\n\npitch = 7.49\ndrill = 1.78\n\noffset_second_pad = 3.18\n\npad_to_pad_clearance = 3\nmax_annular_ring = 1\nmin_annular_ring = 0.15\n\n#locating pins\nret_dy = -offset_second_pad - 0.25\nret_dx = 4.75\nret_drill = 3.00\nret_size = 4.00\n\n\n\npad_size = [pitch - pad_to_pad_clearance, offset_second_pad + 0.25]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\nversion_params = {\n    'with_thermals_lock':{\n        'mpn': '43160-21{n:02d}',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/431602102_sd.pdf',\n        'description': ', With thermal vias in pads',\n        'fp_name_suffix': '_ThermalVias',\n        'thermals': True,\n        'lock': True\n    },\n    'only_pads_lock':{\n        'mpn': '43160-21{n:02d}',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/431602102_sd.pdf',\n        'description': '',\n        'fp_name_suffix': '',\n        'thermals': False,\n        'lock': True\n    },\n    'with_thermals':{\n        'mpn': '43160-01{n:02d}',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/431600105_sd.pdf',\n        'description': ', With thermal vias in pads',\n        'fp_name_suffix': '_ThermalVias',\n        'thermals': True,\n        'lock': False\n    },\n    'only_pads':{\n        'mpn': '43160-01{n:02d}',\n        'datasheet': 'http://www.molex.com/pdm_docs/sd/431600105_sd.pdf',\n        'description': '',\n        'fp_name_suffix': '',\n        'thermals': False,\n        'lock': False\n    }\n}\n\n\n\ndef generate_one_footprint(pins, params, configuration):\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    off = configuration['silk_fab_offset']\n\n    mpn = params['mpn'].format(n=pins*number_of_rows)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n    footprint_name += params['fp_name_suffix']\n\n    kicad_mod = Footprint(footprint_name)\n    desc_format_str = \"Molex {:s}, {:s}{:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(desc_format_str.format(series_long, mpn, params['description'], pins, params['datasheet']))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n\n\n    # Dimensions\n    P = (pins - 1) * pitch\n    B = P + 2*6.79 # connector length\n    W = 11.53 # connector width\n\n    TW = 1.85\n    TL = 3.05\n\n    body_edge={}\n    body_edge['left'] = (P-B)/2\n    body_edge['right'] = body_edge['left'] + B\n    body_edge['top'] = -4.47 - offset_second_pad\n    body_edge['bottom'] =  body_edge['top'] + W\n\n    bounding_box = body_edge.copy()\n    bounding_box['top'] = body_edge['top'] - TW\n\n    ##################################  Pins ##################################\n    kicad_mod.append(PadArray(pincount=pins, start=[0,0],\n        x_spacing=pitch, size=pad_size, drill=drill,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, layers=Pad.LAYERS_THT))\n    kicad_mod.append(PadArray(pincount=pins, start=[0, -offset_second_pad],\n        x_spacing=pitch, size=pad_size, drill=drill,\n        shape=Pad.SHAPE_RECT, type=Pad.TYPE_THT, layers=Pad.LAYERS_THT))\n\n    d_small = 0.3\n    s_small = d_small + 2*min_annular_ring\n    thermal_to_pad_edge = s_small/2 + 0.15\n\n    if params['thermals']:\n        for xi in range(pins):\n            n = xi + 1\n            pad_center_y = -offset_second_pad/2\n            pad_center_x = xi*pitch\n            pad_h = offset_second_pad + pad_size[1]\n            dx = (pad_size[0] - 2*thermal_to_pad_edge)/2\n            dy = (pad_h - 2*thermal_to_pad_edge)/4\n\n            #draw rectangle on F.Fab layer\n\n            # kicad_mod.append(RectLine(\n            #     start=[pad_center_x - pad_l/2, pad_center_y - pad_size[1]/2],\n            #     end=[pad_center_x + pad_l/2, pad_center_y + pad_size[1]/2],\n            #     layer='F.Fab', width=configuration['fab_line_width']))\n\n            kicad_mod.append(PadArray(center=[pad_center_x, pad_center_y],\n                pincount=3, y_spacing=dy*2,\n                drill=d_small, size=s_small, initial=n, increment=0,\n                shape=Pad.SHAPE_CIRCLE, type=Pad.TYPE_THT, layers=Pad.LAYERS_THT))\n            kicad_mod.append(PadArray(center=[pad_center_x - dx, pad_center_y],\n                pincount=5, y_spacing=dy,\n                drill=d_small, size=s_small, initial=n, increment=0,\n                type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_THT))\n            kicad_mod.append(PadArray(center=[pad_center_x + dx, pad_center_y],\n                pincount=5, y_spacing=dy,\n                drill=d_small, size=s_small, initial=n, increment=0,\n                type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, layers=Pad.LAYERS_THT))\n\n    if params['lock']:\n        kicad_mod.append(Pad(at=[-ret_dx, ret_dy], type=Pad.TYPE_THT,\n            shape=Pad.SHAPE_CIRCLE, size=ret_size, drill=ret_drill, layers=Pad.LAYERS_THT))\n        kicad_mod.append(Pad(at=[P+ret_dx, ret_dy], type=Pad.TYPE_THT,\n            shape=Pad.SHAPE_CIRCLE, size=ret_size, drill=ret_drill, layers=Pad.LAYERS_THT))\n\n    kicad_mod.append(RectLine(start=[-pad_size[0]/2, -offset_second_pad-pad_size[1]/2],\n        end=[pad_size[0]/2,pad_size[1]/2],offset=pad_silk_off,\n        width=configuration['silk_line_width'], layer='B.SilkS'))\n\n    ############################ Outline ##############################\n    #kicad_mod.append(RectLine(start=[xl1, yt1], end=[xr1, yb1], layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(RectLine(\n        start=[body_edge['left'], body_edge['top']],\n        end=[body_edge['right'], body_edge['bottom']],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    tab = [\n        {'x': P/2 - TL/2, 'y': body_edge['top']},\n        {'x': P/2 - TL/2, 'y': body_edge['top'] - TW},\n        {'x': P/2 + TL/2, 'y': body_edge['top'] - TW},\n        {'x': P/2 + TL/2, 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=tab,\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n\n    kicad_mod.append(RectLine(\n        start=[body_edge['left'], body_edge['top']],\n        end=[body_edge['right'], body_edge['bottom']],\n        offset = off,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    tab = [\n        {'x': P/2 - TL/2 - off, 'y': body_edge['top'] - off},\n        {'x': P/2 - TL/2 - off, 'y': body_edge['top'] - TW - off},\n        {'x': P/2 + TL/2 + off, 'y': body_edge['top'] - TW - off},\n        {'x': P/2 + TL/2 + off, 'y': body_edge['top'] - off}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=tab,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n    ############################ Pin 1 ################################\n    # Pin 1 designator\n    pin1_sl = 2.4\n    pin1 = [\n        {'x': -pin1_sl/2, 'y': body_edge['top']},\n        {'x': 0, 'y': body_edge['top'] + pin1_sl/sqrt(2)},\n        {'x': pin1_sl/2, 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin1,\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    pin1_sl = 0.8\n    yp1 = body_edge['top'] - off - 0.3\n    pin1 = [\n    {'x': 0,'y': yp1},\n    {'x': pin1_sl/2,'y': yp1-pin1_sl/sqrt(2)},\n    {'x': -pin1_sl/2,'y': yp1-pin1_sl/sqrt(2)},\n    {'x': 0,'y': yp1},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin1, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n    for version in version_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, version_params[version], configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_slimstack-501920.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"SlimStack\"\nseries_long = 'SlimStack Fine-Pitch SMT Board-to-Board Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'http://www.molex.com/pdm_docs/sd/5019204001_sd.pdf'\n\n#pins_per_row per row\npins_range = [30,40,50]\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"501920-{n:02}01\"\n\npitch = 0.5\n\ndef generate_one_footprint(pincount, configuration):\n    mpn = part_code.format(n=pincount)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount//2, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pincount, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    kicad_mod.setAttribute('smd')\n\n    # calculate working values\n    pad_x_spacing = 0.5\n    pad_y_spacing = 2.4 + 1.1\n    pad_width = 0.3\n    pad_height = 1.1\n    pad_x_span = (pad_x_spacing * ((pincount / 2) - 1))\n\n    h_body_width = 3.1 / 2.0\n    h_body_length = (pad_x_span / 2.0) + 1.4 + 0.37\n\n    fab_width = configuration['fab_line_width']\n\n    outline_x = h_body_length - (pad_x_span / 2.0) - pad_width/2 - (configuration['silk_pad_clearance'] + configuration['silk_line_width']/2)\n    marker_y = 0.8\n    silk_width = configuration['silk_line_width']\n    nudge = configuration['silk_fab_offset']\n\n    courtyard_width = configuration['courtyard_line_width']\n    courtyard_precision = configuration['courtyard_grid']\n    courtyard_clearance = configuration['courtyard_offset']['connector']\n    courtyard_x = roundToBase(h_body_length + courtyard_clearance, courtyard_precision)\n    courtyard_y = roundToBase((pad_y_spacing + pad_height) / 2.0 + courtyard_clearance, courtyard_precision)\n\n    # create pads\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=pad_x_spacing, y_spacing=0,\\\n        center=[0,-pad_y_spacing/2.0], initial=1, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],\\\n        layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=pad_x_spacing, y_spacing=0,\\\n        center=[0,pad_y_spacing/2.0], initial=2, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],\\\n        layers=Pad.LAYERS_SMT))\n\n    # create fab outline and pin 1 marker\n    kicad_mod.append(RectLine(start=[-h_body_length, -h_body_width], end=[h_body_length, h_body_width], layer='F.Fab', width=fab_width))\n    body_edge={\n        'left':-h_body_length,\n        'top':-h_body_width\n    }\n    body_edge['right'] = -body_edge['left']\n    body_edge['bottom'] = -body_edge['top']\n    kicad_mod.append(Line(start=[-h_body_length+outline_x, -h_body_width-nudge], end=[-h_body_length+outline_x, -h_body_width-marker_y], layer='F.Fab', width=fab_width))\n\n    # create silkscreen outline and pin 1 marker\n    left_outline = [[-h_body_length+outline_x, h_body_width+nudge], [-h_body_length-nudge, h_body_width+nudge], [-h_body_length-nudge, -h_body_width-nudge],\\\n                    [-h_body_length+outline_x, -h_body_width-nudge], [-h_body_length+outline_x, -h_body_width-marker_y]]\n    right_outline = [[h_body_length-outline_x, h_body_width+nudge], [h_body_length+nudge, h_body_width+nudge], [h_body_length+nudge, -h_body_width-nudge],\\\n                     [h_body_length-outline_x, -h_body_width-nudge]]\n    kicad_mod.append(PolygoneLine(polygone=left_outline, layer='F.SilkS', width=silk_width))\n    kicad_mod.append(PolygoneLine(polygone=right_outline, layer='F.SilkS', width=silk_width))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-courtyard_x, -courtyard_y], end=[courtyard_x, courtyard_y], layer='F.CrtYd', width=courtyard_width))\n\n    ######################### Text Fields ###############################\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':-courtyard_y, 'bottom':+courtyard_y},\n        fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for pins in pins_range:\n        generate_one_footprint(pins, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_slimstack-502426.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\n\"\"\"\n\nThis family of parts is spread over 2 datasheets, depending on the 3rd number in the PN suffix:\n\n502340-xx10 (8-80 pin):\nhttp://www.molex.com/pdm_docs/sd/5024260810_sd.pdf\n\n502340-xx30 (14-80 pin):\nhttp://www.molex.com/pdm_docs/sd/5024261430_sd.pdf\n\n\"\"\"\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"SlimStack\"\nseries_long = 'SlimStack Fine-Pitch SMT Board-to-Board Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\n\n#pins_per_row per row\nvalid_pns = [\n    \"0810\",\"1410\",\"2010\",\"2210\",\"2410\",\"2610\",\"3010\",\"3210\",\"3410\",\"4010\",\"4410\",\"5010\",\"6010\",\"6410\",\"8010\",\n    #\"1430\",\"2030\",\"2230\",\"2430\",\"2630\",\"3030\",\"3230\",\"4030\",\"5030\",\"6030\",\"7030\",\"8030\"\n]\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"502426-{pn:s}\"\n\npitch = 0.4\n\ndef generate_one_footprint(partnumber, configuration):\n    pincount = int(partnumber[:2])\n    if partnumber[2:3] == \"1\":\n        datasheet = \"http://www.molex.com/pdm_docs/sd/5024260810_sd.pdf\"\n    elif partnumber[2:3] == \"3\":\n        datasheet = \"http://www.molex.com/pdm_docs/sd/5024261430_sd.pdf\"\n    mpn = part_code.format(pn=partnumber)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount//2, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pincount, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    kicad_mod.setAttribute('smd')\n\n    # calculate working values\n    pad_x_spacing = pitch\n    pad_y_spacing = 1.95 + 0.475\n    pad_width = 0.22\n    pad_height = 0.475\n    pad_x_span = pad_x_spacing * ((pincount / 2) - 1)\n\n    nail_x = pad_x_span / 2.0 + 0.95\n    nail_y = 1.085\n    nail_width = 0.32\n    nail_height = 0.65\n\n    half_body_width = 2.6 / 2.0\n    half_body_length = (pad_x_span / 2.0) + 1.75\n\n    fab_width = configuration['fab_line_width']\n\n    outline_x = half_body_length - (pad_x_span / 2.0) - pad_width/2 - (configuration['silk_pad_clearance'] + configuration['silk_line_width']/2)\n    marker_y = 0.2\n    silk_width = configuration['silk_line_width']\n    nudge = configuration['silk_fab_offset']\n\n    courtyard_width = configuration['courtyard_line_width']\n    courtyard_precision = configuration['courtyard_grid']\n    courtyard_clearance = configuration['courtyard_offset']['connector']\n    courtyard_x = roundToBase(half_body_length + courtyard_clearance, courtyard_precision)\n    courtyard_y = roundToBase((pad_y_spacing + pad_height) / 2.0 + courtyard_clearance, courtyard_precision)\n\n    # create pads\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=-pad_x_spacing, y_spacing=0,center=[0,-pad_y_spacing/2.0],\\\n        initial=1, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=-pad_x_spacing, y_spacing=0,center=[0,pad_y_spacing/2.0],\\\n        initial=2, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],layers=Pad.LAYERS_SMT))\n\n    # create \"fitting nail\" (npth mounting) holes\n    #kicad_mod.append(Pad(at=[-nail_x, 0], type=Pad.TYPE_NPTH, shape=Pad.SHAPE_RECT, size=[0.35, 0.44], drill=[0.35, 0.44], layers=['*.Cu', '*.Mask']))\n    #kicad_mod.append(Pad(at=[nail_x, 0], type=Pad.TYPE_NPTH, shape=Pad.SHAPE_RECT, size=[0.35, 0.44], drill=[0.35, 0.44], layers=['*.Cu', '*.Mask']))\n    kicad_mod.append(RectLine(start=[-nail_x - nail_width / 2.0, -nail_y - nail_height / 2.0], end=[-nail_x + nail_width / 2.0, -nail_y + nail_height / 2.0], layer='Edge.Cuts', width=fab_width))\n    kicad_mod.append(RectLine(start=[-nail_x - nail_width / 2.0, nail_y - nail_height / 2.0], end=[-nail_x + nail_width / 2.0, nail_y + nail_height / 2.0], layer='Edge.Cuts', width=fab_width))\n    kicad_mod.append(RectLine(start=[nail_x - nail_width / 2.0, -nail_y - nail_height / 2.0], end=[nail_x + nail_width / 2.0, -nail_y + nail_height / 2.0], layer='Edge.Cuts', width=fab_width))\n    kicad_mod.append(RectLine(start=[nail_x - nail_width / 2.0, nail_y - nail_height / 2.0], end=[nail_x + nail_width / 2.0, nail_y + nail_height / 2.0], layer='Edge.Cuts', width=fab_width))\n\n    # create fab outline and pin 1 marker\n    kicad_mod.append(RectLine(start=[-half_body_length, -half_body_width], end=[half_body_length, half_body_width], layer='F.Fab', width=fab_width))\n    body_edge={\n        'left':-half_body_length,\n        'top':-half_body_width\n    }\n    body_edge['right'] = -body_edge['left']\n    body_edge['bottom'] = -body_edge['top']\n    kicad_mod.append(Line(start=[half_body_length-outline_x, -half_body_width], end=[half_body_length-outline_x, -half_body_width-marker_y], layer='F.Fab', width=fab_width))\n\n    # create silkscreen outline and pin 1 marker\n    left_outline = [[-half_body_length+outline_x, half_body_width+nudge], [-half_body_length-nudge, half_body_width+nudge], [-half_body_length-nudge, -half_body_width-nudge],\\\n                    [-half_body_length+outline_x, -half_body_width-nudge]]\n    right_outline = [[half_body_length-outline_x, half_body_width+nudge], [half_body_length+nudge, half_body_width+nudge], [half_body_length+nudge, -half_body_width-nudge],\\\n                     [half_body_length-outline_x, -half_body_width-nudge], [half_body_length-outline_x, -half_body_width-marker_y]]\n    kicad_mod.append(PolygoneLine(polygone=left_outline, layer='F.SilkS', width=silk_width))\n    kicad_mod.append(PolygoneLine(polygone=right_outline, layer='F.SilkS', width=silk_width))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-courtyard_x, -courtyard_y], end=[courtyard_x, courtyard_y], layer='F.CrtYd', width=courtyard_width))\n\n    ######################### Text Fields ###############################\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':-courtyard_y, 'bottom':+courtyard_y},\n        fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for partnumber in valid_pns:\n        generate_one_footprint(partnumber, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_slimstack-502430.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\n\"\"\"\n\nThis family of parts is spread over 3 datasheets, depending on the 3rd number in the PN suffix:\n\n502340-xx10 (14-80 pin):\nhttp://www.molex.com/pdm_docs/sd/5024301410_sd.pdf\n\n502340-0820 (8 pin)\nhttp://www.molex.com/pdm_docs/sd/5024300820_sd.pdf\n\n502340-xx30 (14-90 pin):\nhttp://www.molex.com/pdm_docs/sd/5024307030_sd.pdf\n\n\"\"\"\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"SlimStack\"\nseries_long = 'SlimStack Fine-Pitch SMT Board-to-Board Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\n\n#pins_per_row per row\nvalid_pns = [\n    \"1410\",\"2010\",\"2210\",\"2410\",\"2610\",\"3010\",\"3210\",\"3410\",\"4010\",\"4410\",\"5010\",\"6010\",\"6410\",\"8010\",\n    \"0820\",\n    #\"1430\",\"2030\",\"2230\",\"2430\",\"2630\",\"3230\",\"4030\",\"5030\",\"6030\",\"7030\",\"8030\",\"9030\"\n]\n\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"502430-{pn:s}\"\n\npitch = 0.4\n\ndef generate_one_footprint(partnumber, configuration):\n    pincount = int(partnumber[:2])\n    if str(partnumber)[2:3] == \"1\":\n        datasheet = \"http://www.molex.com/pdm_docs/sd/5024301410_sd.pdf\"\n    elif str(partnumber)[2:3] == \"2\":\n        datasheet = \"http://www.molex.com/pdm_docs/sd/5024300820_sd.pdf\"\n    elif str(partnumber)[2:3] == \"3\":\n        datasheet = \"http://www.molex.com/pdm_docs/sd/5024307030_sd.pdf\"\n    mpn = part_code.format(pn=partnumber)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount//2, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pincount, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    kicad_mod.setAttribute('smd')\n\n    # calculate working values\n    pad_x_spacing = pitch\n    pad_y_spacing = 1.05 + 0.66\n    pad_width = 0.22\n    pad_height = 0.66\n    pad_x_span = pad_x_spacing * ((pincount / 2) - 1)\n\n    nail_x = pad_x_span / 2.0 + 0.95\n\n    half_body_width = 1.54 / 2.0\n    half_body_length = (pad_x_span / 2.0) + 1.33\n\n    fab_width = configuration['fab_line_width']\n\n    outline_x = half_body_length - (pad_x_span / 2.0) - pad_width/2 - (configuration['silk_pad_clearance'] + configuration['silk_line_width']/2)\n    marker_y = 0.35\n    silk_width = configuration['silk_line_width']\n    nudge = configuration['silk_fab_offset']\n\n    courtyard_width = configuration['courtyard_line_width']\n    courtyard_precision = configuration['courtyard_grid']\n    courtyard_clearance = configuration['courtyard_offset']['connector']\n    courtyard_x = roundToBase(half_body_length + courtyard_clearance, courtyard_precision)\n    courtyard_y = roundToBase((pad_y_spacing + pad_height) / 2.0 + courtyard_clearance, courtyard_precision)\n\n    # create pads\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=pad_x_spacing, y_spacing=0,center=[0,-pad_y_spacing/2.0],\\\n        initial=1, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=pad_x_spacing, y_spacing=0,center=[0,pad_y_spacing/2.0],\\\n        initial=2, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],layers=Pad.LAYERS_SMT))\n\n    # create \"fitting nail\" (npth mounting) holes\n    #kicad_mod.append(Pad(at=[-nail_x, 0], type=Pad.TYPE_NPTH, shape=Pad.SHAPE_RECT, size=[0.35, 0.44], drill=[0.35, 0.44], layers=['*.Cu', '*.Mask']))\n    #kicad_mod.append(Pad(at=[nail_x, 0], type=Pad.TYPE_NPTH, shape=Pad.SHAPE_RECT, size=[0.35, 0.44], drill=[0.35, 0.44], layers=['*.Cu', '*.Mask']))\n    kicad_mod.append(RectLine(start=[-nail_x - 0.35 / 2.0, -0.22], end=[-nail_x + 0.35 / 2.0, 0.22], layer='Edge.Cuts', width=fab_width))\n    kicad_mod.append(RectLine(start=[nail_x - 0.35 / 2.0, -0.22], end=[nail_x + 0.35 / 2.0, 0.22], layer='Edge.Cuts', width=fab_width))\n\n    # create fab outline and pin 1 marker\n    kicad_mod.append(RectLine(start=[-half_body_length, -half_body_width], end=[half_body_length, half_body_width], layer='F.Fab', width=fab_width))\n    body_edge={\n        'left':-half_body_length,\n        'top':-half_body_width\n    }\n    body_edge['right'] = -body_edge['left']\n    body_edge['bottom'] = -body_edge['top']\n    kicad_mod.append(Line(start=[-half_body_length+outline_x, -half_body_width], end=[-half_body_length+outline_x, -half_body_width-marker_y], layer='F.Fab', width=fab_width))\n\n    # create silkscreen outline and pin 1 marker\n    left_outline = [[-half_body_length+outline_x, half_body_width+nudge], [-half_body_length-nudge, half_body_width+nudge], [-half_body_length-nudge, -half_body_width-nudge],\\\n                    [-half_body_length+outline_x, -half_body_width-nudge], [-half_body_length+outline_x, -half_body_width-marker_y]]\n    right_outline = [[half_body_length-outline_x, half_body_width+nudge], [half_body_length+nudge, half_body_width+nudge], [half_body_length+nudge, -half_body_width-nudge],\\\n                     [half_body_length-outline_x, -half_body_width-nudge]]\n    kicad_mod.append(PolygoneLine(polygone=left_outline, layer='F.SilkS', width=silk_width))\n    kicad_mod.append(PolygoneLine(polygone=right_outline, layer='F.SilkS', width=silk_width))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-courtyard_x, -courtyard_y], end=[courtyard_x, courtyard_y], layer='F.CrtYd', width=courtyard_width))\n\n    ######################### Text Fields ###############################\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':-courtyard_y, 'bottom':+courtyard_y},\n        fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for partnumber in valid_pns:\n        generate_one_footprint(partnumber, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_slimstack-52991.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"SlimStack\"\nseries_long = 'SlimStack Fine-Pitch SMT Board-to-Board Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'http://www.molex.com/pdm_docs/sd/529910308_sd.pdf'\n\n#pins_per_row per row\npins_range = [20,30,40,50,60,70,80]\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"52991-0{n:02}8\"\n\npitch = 0.5\n\ndef generate_one_footprint(pincount, configuration):\n    mpn = part_code.format(n=pincount)\n\n    CrtYd_off = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n    body_edge = {}\n    bounding_box = {}\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount//2, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pincount, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    kicad_mod.setAttribute('smd')\n\n    # calculate working values\n    pad_x_spacing = pitch\n    pad_y_spacing = 2.2 + 1.8\n    pad_width = 0.3\n    pad_height = 1.8\n    pad_x_span = (pad_x_spacing * ((pincount / 2) - 1))\n\n    h_body_width = 4.3 / 2.0\n    h_body_length = (pad_x_span / 2.0) + 2.15\n\n    tab_width = 1.3\n    tab_height = 0.5\n\n    fab_width = configuration['fab_line_width']\n\n    outline_x = h_body_length - (pad_x_span / 2.0) - pad_width/2 - (configuration['silk_pad_clearance'] + configuration['silk_line_width']/2)\n    marker_y = 0.8\n    silk_width = configuration['silk_line_width']\n    nudge = configuration['silk_fab_offset']\n\n    courtyard_width = configuration['courtyard_line_width']\n    courtyard_precision = configuration['courtyard_grid']\n    courtyard_clearance = configuration['courtyard_offset']['connector']\n    courtyard_x = roundToBase(h_body_length + courtyard_clearance, courtyard_precision)\n    courtyard_y = roundToBase((pad_y_spacing + pad_height) / 2.0 + courtyard_clearance, courtyard_precision)\n\n    # create pads\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=pad_x_spacing, y_spacing=0,\\\n        center=[0,-pad_y_spacing/2.0], initial=1, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],\\\n        layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=pad_x_spacing, y_spacing=0,\\\n        center=[0,pad_y_spacing/2.0], initial=2, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],\\\n        layers=Pad.LAYERS_SMT))\n\n    # create fab outline and pin 1 marker\n    kicad_mod.append(RectLine(start=[-h_body_length, -h_body_width], end=[h_body_length, h_body_width], layer='F.Fab', width=fab_width))\n    body_edge={\n        'left':-h_body_length,\n        'top':-h_body_width\n    }\n    body_edge['right'] = -body_edge['left']\n    body_edge['bottom'] = -body_edge['top']\n    kicad_mod.append(Line(start=[-h_body_length+outline_x, -h_body_width-nudge], end=[-h_body_length+outline_x, -h_body_width-marker_y], layer='F.Fab', width=fab_width))\n\n    # create silkscreen outline and pin 1 marker\n    left_outline = [[-h_body_length+outline_x, h_body_width+nudge], [-h_body_length-nudge, h_body_width+nudge], [-h_body_length-nudge, -h_body_width-nudge],\\\n                    [-h_body_length+outline_x, -h_body_width-nudge], [-h_body_length+outline_x, -h_body_width-marker_y]]\n    right_outline = [[h_body_length-outline_x, h_body_width+nudge], [h_body_length+nudge, h_body_width+nudge], [h_body_length+nudge, -h_body_width-nudge],\\\n                     [h_body_length-outline_x, -h_body_width-nudge]]\n    top_left_tab = [[-h_body_length-nudge, -h_body_width-nudge], [-h_body_length-nudge, -h_body_width-nudge-tab_height],\\\n                    [-h_body_length-nudge+tab_width, -h_body_width-nudge-tab_height], [-h_body_length-nudge+tab_width, -h_body_width-nudge]]\n    bottom_left_tab = [[-h_body_length-nudge, h_body_width+nudge], [-h_body_length-nudge+tab_width/3, h_body_width+nudge+tab_height],\\\n                       [-h_body_length-nudge+tab_width, h_body_width+nudge+tab_height], [-h_body_length-nudge+tab_width, h_body_width+nudge]]\n    top_right_tab = [[h_body_length+nudge, -h_body_width-nudge], [h_body_length+nudge, -h_body_width-nudge-tab_height],\\\n                     [h_body_length+nudge-tab_width, -h_body_width-nudge-tab_height], [h_body_length+nudge-tab_width, -h_body_width-nudge]]\n    bottom_right_tab = [[h_body_length+nudge, h_body_width+nudge], [h_body_length+nudge, h_body_width+nudge+tab_height],\\\n                       [h_body_length+nudge-tab_width, h_body_width+nudge+tab_height], [h_body_length+nudge-tab_width, h_body_width+nudge]]\n    kicad_mod.append(PolygoneLine(polygone=left_outline, layer='F.SilkS', width=silk_width))\n    kicad_mod.append(PolygoneLine(polygone=right_outline, layer='F.SilkS', width=silk_width))\n    kicad_mod.append(PolygoneLine(polygone=top_left_tab, layer='F.SilkS', width=silk_width))\n    kicad_mod.append(PolygoneLine(polygone=bottom_left_tab, layer='F.SilkS', width=silk_width))\n    kicad_mod.append(PolygoneLine(polygone=top_right_tab, layer='F.SilkS', width=silk_width))\n    kicad_mod.append(PolygoneLine(polygone=bottom_right_tab, layer='F.SilkS', width=silk_width))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-courtyard_x, -courtyard_y], end=[courtyard_x, courtyard_y], layer='F.CrtYd', width=courtyard_width))\n\n    ######################### Text Fields ###############################\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':-courtyard_y, 'bottom':+courtyard_y},\n        fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for pins in pins_range:\n        generate_one_footprint(pins, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_slimstack-53748.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport math\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"SlimStack\"\nseries_long = 'SlimStack Fine-Pitch SMT Board-to-Board Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'https://www.molex.com/pdm_docs/sd/537480308_sd.pdf'\n\n#pins_per_row per row\npins_range = [20,30,40,60,70,80]\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"53748-0{n:02}8\"\n\npitch = 0.5\n\ndef generate_one_footprint(pincount, configuration):\n    mpn = part_code.format(n=pincount)\n\n    CrtYd_off = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n    body_edge = {}\n    bounding_box = {}\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount//2, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pincount, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    kicad_mod.setAttribute('smd')\n\n    # calculate working values\n    pad_x_spacing = 2.2 + 1.2\n    pad_y_spacing = pitch\n    pad_width = 1.2\n    pad_height = 0.3\n    pad_y_span = (pad_y_spacing * ((pincount / 2) - 1))\n\n    h_body_width = 3.1 / 2.0\n    h_body_length = (pad_y_span / 2.0) + 2.15\n\n    tab_width = 0.6\n    tab_height = 1.1\n    tab_cut_x = 0.49\n    tab_cut_y = 0.7\n    silk_tab_cut_offset_x = configuration['silk_fab_offset']*math.tan(math.radians(55/2))\n    silk_tab_cut_offset_y = configuration['silk_fab_offset']*math.tan(math.radians(35/2))\n\n    fab_width = configuration['fab_line_width']\n\n    outline_y = pad_y_span / 2.0 + pad_height/2 + (configuration['silk_pad_clearance'] + configuration['silk_line_width']/2)\n    marker_x = 0.7\n    silk_width = configuration['silk_line_width']\n    nudge = configuration['silk_fab_offset']\n\n    courtyard_width = configuration['courtyard_line_width']\n    courtyard_precision = configuration['courtyard_grid']\n    courtyard_clearance = configuration['courtyard_offset']['connector']\n    courtyard_x = roundToBase(max(h_body_width + tab_width, (pad_x_spacing + pad_width)/2) + courtyard_clearance, courtyard_precision)\n    courtyard_y = roundToBase(h_body_length + courtyard_clearance, courtyard_precision)\n\n    # create pads\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=0, y_spacing=pad_y_spacing,\\\n        center=[-pad_x_spacing/2.0, 0], initial=1, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],\\\n        layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=0, y_spacing=pad_y_spacing,\\\n        center=[pad_x_spacing/2.0, 0], initial=2, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],\\\n        layers=Pad.LAYERS_SMT))\n\n    # create fab outline and pin 1 marker\n    fab_outline = [[-h_body_width - tab_width, -h_body_length], \\\n                        [-h_body_width - tab_width, -h_body_length + tab_height], [-h_body_width, -h_body_length + tab_height], \\\n                        [-h_body_width, h_body_length - tab_height], [-h_body_width - tab_width, h_body_length - tab_height], \\\n                        [-h_body_width - tab_width, h_body_length - tab_cut_y], [-h_body_width - tab_width + tab_cut_x, h_body_length], \\\n                        [h_body_width + tab_width, h_body_length], [h_body_width + tab_width, h_body_length - tab_height],\n                        [h_body_width, h_body_length - tab_height], [h_body_width, -h_body_length + tab_height], \\\n                        [h_body_width + tab_width, -h_body_length + tab_height], [h_body_width + tab_width, -h_body_length], \\\n                        [-h_body_width - tab_width, -h_body_length]]\n    kicad_mod.append(PolygoneLine(polygone=fab_outline, layer='F.Fab', width=fab_width))\n\n\n    body_edge={\n        'left':-h_body_width,\n        'top':-h_body_length\n    }\n    body_edge['right'] = -body_edge['left']\n    body_edge['bottom'] = -body_edge['top']\n    kicad_mod.append(Line(start=[-h_body_width+marker_x, -pad_y_span/2], end=[-h_body_width, -pad_y_span/2+marker_x/2], layer='F.Fab', width=fab_width))\n    kicad_mod.append(Line(start=[-h_body_width+marker_x, -pad_y_span/2], end=[-h_body_width, -pad_y_span/2-marker_x/2], layer='F.Fab', width=fab_width))\n\n\n    \n\n    # create silkscreen outline and pin 1 marker\n    top_outline = [[h_body_width+nudge, -outline_y], [h_body_width+nudge, -h_body_length+nudge+tab_height], \\\n                    [h_body_width+nudge+tab_width, -h_body_length+nudge+tab_height], [h_body_width+nudge+tab_width, -h_body_length-nudge], \\\n                    [-h_body_width-nudge-tab_width, -h_body_length-nudge], [-h_body_width-nudge-tab_width, -h_body_length+nudge+tab_height], \\\n                    [-h_body_width-nudge-tab_width, -h_body_length+nudge+tab_height], [-h_body_width-nudge, -h_body_length+nudge+tab_height], \\\n                    [-h_body_width-nudge, -outline_y], [-h_body_width-marker_x, -outline_y]]\n\n    bottom_outline = [[h_body_width+nudge, outline_y], [h_body_width+nudge, h_body_length-nudge-tab_height], \\\n                    [h_body_width+nudge+tab_width, h_body_length-nudge-tab_height], [h_body_width+nudge+tab_width, h_body_length+nudge], \\\n                    [-h_body_width - tab_width + tab_cut_x - silk_tab_cut_offset_x,+h_body_length+nudge], [-h_body_width-nudge-tab_width, h_body_length - tab_cut_y + silk_tab_cut_offset_y],\\\n                    [-h_body_width-nudge-tab_width, h_body_length-nudge-tab_height], [-h_body_width - nudge, h_body_length-nudge-tab_height], \\\n                    [-h_body_width-nudge, outline_y]]\n    \n    kicad_mod.append(PolygoneLine(polygone=top_outline, layer='F.SilkS', width=silk_width))\n    kicad_mod.append(PolygoneLine(polygone=bottom_outline, layer='F.SilkS', width=silk_width))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-courtyard_x, -courtyard_y], end=[courtyard_x, courtyard_y], layer='F.CrtYd', width=courtyard_width))\n\n    ######################### Text Fields ###############################\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':-courtyard_y, 'bottom':+courtyard_y},\n        fp_name=footprint_name, text_y_inside_position='center', allow_rotation=True)\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for pins in pins_range:\n        generate_one_footprint(pins, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_slimstack-54722.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"SlimStack\"\nseries_long = 'SlimStack Fine-Pitch SMT Board-to-Board Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'http://www.molex.com/pdm_docs/sd/547220804_sd.pdf'\n\n#pins_per_row per row\npins_range = [16,20,22,24,30,34,40,50,60,80]\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"54722-0{n:02}4\"\n\npitch = 0.5\n\ndef generate_one_footprint(pincount, configuration):\n    mpn = part_code.format(n=pincount)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount//2, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pincount, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    kicad_mod.setAttribute('smd')\n\n    # calculate working values\n    pad_x_spacing = pitch\n    pad_y_spacing = 4.4 + 1.1\n    pad_width = 0.3\n    pad_height = 1.1\n    pad_x_span = (pad_x_spacing * ((pincount / 2) - 1))\n\n    h_body_width = 5.0 / 2.0\n    h_body_length = (pad_x_span / 2.0) + 1.05 + 0.5\n\n    fab_width = configuration['fab_line_width']\n\n    #outline_x = 1.2\n    outline_x = h_body_length - (pad_x_span / 2.0) - pad_width/2 - (configuration['silk_pad_clearance'] + configuration['silk_line_width']/2)\n    marker_y = 0.8\n    silk_width = configuration['silk_line_width']\n    nudge = configuration['silk_fab_offset']\n\n    courtyard_width = configuration['courtyard_line_width']\n    courtyard_precision = configuration['courtyard_grid']\n    courtyard_clearance = configuration['courtyard_offset']['connector']\n    courtyard_x = roundToBase(h_body_length + courtyard_clearance, courtyard_precision)\n    courtyard_y = roundToBase((pad_y_spacing + pad_height) / 2.0 + courtyard_clearance, courtyard_precision)\n\n    # create pads\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=pad_x_spacing, y_spacing=0,\\\n        center=[0,-pad_y_spacing/2.0], initial=1, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],\\\n        layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=pad_x_spacing, y_spacing=0,\\\n        center=[0,pad_y_spacing/2.0], initial=2, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],\\\n        layers=Pad.LAYERS_SMT))\n\n    # create fab outline and pin 1 marker\n    kicad_mod.append(RectLine(start=[-h_body_length, -h_body_width], end=[h_body_length, h_body_width], layer='F.Fab', width=fab_width))\n    body_edge={\n        'left':-h_body_length,\n        'top':-h_body_width\n    }\n    body_edge['right'] = -body_edge['left']\n    body_edge['bottom'] = -body_edge['top']\n    kicad_mod.append(Line(start=[-h_body_length+outline_x, -h_body_width-nudge], end=[-h_body_length+outline_x, -h_body_width-marker_y], layer='F.Fab', width=fab_width))\n\n    # create silkscreen outline and pin 1 marker\n    left_outline = [[-h_body_length+outline_x, h_body_width+nudge], [-h_body_length-nudge, h_body_width+nudge], [-h_body_length-nudge, -h_body_width-nudge],\\\n                    [-h_body_length+outline_x, -h_body_width-nudge], [-h_body_length+outline_x, -h_body_width-marker_y]]\n    right_outline = [[h_body_length-outline_x, h_body_width+nudge], [h_body_length+nudge, h_body_width+nudge], [h_body_length+nudge, -h_body_width-nudge],\\\n                     [h_body_length-outline_x, -h_body_width-nudge]]\n    kicad_mod.append(PolygoneLine(polygone=left_outline, layer='F.SilkS', width=silk_width))\n    kicad_mod.append(PolygoneLine(polygone=right_outline, layer='F.SilkS', width=silk_width))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-courtyard_x, -courtyard_y], end=[courtyard_x, courtyard_y], layer='F.CrtYd', width=courtyard_width))\n\n    ######################### Text Fields ###############################\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':-courtyard_y, 'bottom':+courtyard_y},\n        fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for pins in pins_range:\n        generate_one_footprint(pins, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_slimstack-55560.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"SlimStack\"\nseries_long = 'SlimStack Fine-Pitch SMT Board-to-Board Connectors'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'http://www.molex.com/pdm_docs/sd/555600207_sd.pdf'\n\n#pins_per_row per row\npins_range = [16,20,22,24,30,34,40,50,60,80]\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"55560-0{n:02}1\"\n\npitch = 0.5\n\ndef generate_one_footprint(pincount, configuration):\n    mpn = part_code.format(n=pincount)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount//2, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pincount, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    kicad_mod.setAttribute('smd')\n\n    # calculate working values\n    pad_x_spacing = pitch\n    pad_y_spacing = 2.9 + 1.0\n    pad_width = 0.3\n    pad_height = 1.0\n    pad_x_span = (pad_x_spacing * ((pincount / 2) - 1))\n\n    h_body_width = 2.83 / 2.0\n    h_body_length = (pad_x_span / 2.0) + 0.45 + 0.525\n\n    fab_width = configuration['fab_line_width']\n\n    #outline_x = 0.6\n    outline_x = h_body_length - (pad_x_span / 2.0) - pad_width/2 - (configuration['silk_pad_clearance'] + configuration['silk_line_width']/2)\n    marker_y = 0.8\n    silk_width = configuration['silk_line_width']\n    nudge = configuration['silk_fab_offset']\n\n    courtyard_width = configuration['courtyard_line_width']\n    courtyard_precision = configuration['courtyard_grid']\n    courtyard_clearance = configuration['courtyard_offset']['connector']\n    courtyard_x = roundToBase(h_body_length + courtyard_clearance, courtyard_precision)\n    courtyard_y = roundToBase((pad_y_spacing + pad_height) / 2.0 + courtyard_clearance, courtyard_precision)\n\n\n\n    # create pads\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=pad_x_spacing, y_spacing=0,\\\n        center=[0,-pad_y_spacing/2.0], initial=1, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],\\\n        layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(pincount=pincount//2, x_spacing=pad_x_spacing, y_spacing=0,\\\n        center=[0,pad_y_spacing/2.0], initial=2, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[pad_width, pad_height],\\\n        layers=Pad.LAYERS_SMT))\n\n    # create fab outline and pin 1 marker\n    kicad_mod.append(RectLine(start=[-h_body_length, -h_body_width], end=[h_body_length, h_body_width], layer='F.Fab', width=fab_width))\n    body_edge={\n        'left':-h_body_length,\n        'top':-h_body_width\n    }\n    body_edge['right'] = -body_edge['left']\n    body_edge['bottom'] = -body_edge['top']\n    kicad_mod.append(Line(start=[-h_body_length+outline_x, -h_body_width-nudge], end=[-h_body_length+outline_x, -h_body_width-marker_y], layer='F.Fab', width=fab_width))\n\n    # create silkscreen outline and pin 1 marker\n    left_outline = [[-h_body_length+outline_x, h_body_width+nudge], [-h_body_length-nudge, h_body_width+nudge], [-h_body_length-nudge, -h_body_width-nudge],\\\n                    [-h_body_length+outline_x, -h_body_width-nudge], [-h_body_length+outline_x, -h_body_width-marker_y]]\n    right_outline = [[h_body_length-outline_x, h_body_width+nudge], [h_body_length+nudge, h_body_width+nudge], [h_body_length+nudge, -h_body_width-nudge],\\\n                     [h_body_length-outline_x, -h_body_width-nudge]]\n    kicad_mod.append(PolygoneLine(polygone=left_outline, layer='F.SilkS', width=silk_width))\n    kicad_mod.append(PolygoneLine(polygone=right_outline, layer='F.SilkS', width=silk_width))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-courtyard_x, -courtyard_y], end=[courtyard_x, courtyard_y], layer='F.CrtYd', width=courtyard_width))\n\n    ######################### Text Fields ###############################\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':-courtyard_y, 'bottom':+courtyard_y},\n        fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for pins in pins_range:\n        generate_one_footprint(pins, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/conn_molex_stackable-linear_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"SL\"\nseries_long = 'Stackable Linear Connector'\nmanufacturer = 'Molex'\norientation = 'V'\nnumber_of_rows = 1\n\n#pins_per_row_per_row per row\npins_per_row_range = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]\n\n#Molex part number\n#n = number of circuits per row\n# Boss ist ohne zusätzliche Befestigungslöcher. Dafür gibt es eine komische zusätzliche Bohrung\nvariant_params = {\n    'boss':{\n        'mount_pins': False,\n        'datasheet': 'https://www.molex.com/pdm_docs/sd/1719710002_sd.pdf',\n        'part_code': \"171971-00{n:02d}\",\n        'alternative_codes': [\n            \"171971-01{n:02d}\",\n            \"171971-02{n:02d}\"\n            ]\n        }\n}\n\npitch = 2.54\ndrill = 1.09\nstart_pos_x = 0 # Where should pin 1 be located.\npad_to_pad_clearance = 0.8\nmax_annular_ring = 0.95 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\nrow = 2.54\n\nsize = row - pad_to_pad_clearance\nif size - drill < 2 * min_annular_ring:\n    size = drill + 2 * min_annular_ring\nif size - drill > 2 * max_annular_ring:\n    size = drill + 2 * max_annular_ring\n\n# print(\"size\", size)\n\ndef generate_one_footprint(pins_per_row, variant, configuration):\n    mpn = variant_params[variant]['part_code'].format(n = pins_per_row)\n    alt_mpn = [code.format(n=pins_per_row) for code in variant_params[variant]['alternative_codes']]\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man = manufacturer,\n        series = series,\n        mpn = mpn, num_rows = number_of_rows, pins_per_row = pins_per_row, mounting_pad = \"\",\n        pitch = pitch, orientation = orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Molex {:s}, {:s} (compatible alternatives: {:s}), {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, ', '.join(alt_mpn), pins_per_row, variant_params[variant]['datasheet']))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation = orientation_str, man = manufacturer,\n        entry = configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n\n    #connector length\n    if pins_per_row == 2:\n        A = 7.38\n    else:\n        A = pins_per_row * pitch + 2.46\n\n    #pin centers\n    P = (pins_per_row - 1) * pitch\n\n    #connector width\n    W = 5.1\n\n    #corner positions\n    x1 = -(A - P) / 2\n    x2 = x1 + A\n\n    y2 = W / 2\n    y1 = y2 - W\n\n    #tab length\n    if pins_per_row == 2:\n        tab_l = 6.86\n    else:\n        tab_l = 7.62\n    #tab width\n    tab_w = 1.50\n\n    body_edge = {\n        'left': x1,\n        'right': x2,\n        'bottom': y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n    bounding_box['bottom'] = y2 + tab_w\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    #generate the pads\n    kicad_mod.append(PadArray(\n        pincount = pins_per_row, initial = 1,\n        start = [0, 0], x_spacing=pitch, type = Pad.TYPE_THT,\n        shape = Pad.SHAPE_CIRCLE, size = size, drill = drill, layers = Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    off = configuration['silk_fab_offset']\n    silk_pad_off = configuration['silk_pad_clearance'] + configuration['silk_line_width'] / 2\n\n    #draw the outline of the shape\n    kicad_mod.append(PolygoneLine(polygone = [\n            { 'x': body_edge['left'], 'y': body_edge['top'] },\n            { 'x': body_edge['left'], 'y': body_edge['top'] + 2.31 },\n            { 'x': body_edge['left'] + 0.13, 'y': body_edge['top'] + 2.31 },\n            { 'x': body_edge['left'] + 0.13, 'y': body_edge['bottom'] - 0.76 },\n            { 'x': body_edge['left'], 'y': body_edge['bottom'] - 0.76 },\n            { 'x': body_edge['left'], 'y': body_edge['bottom'] },\n            { 'x': body_edge['right'], 'y': body_edge['bottom'] },\n            { 'x': body_edge['right'], 'y': body_edge['bottom'] - 0.76 },\n            { 'x': body_edge['right'] - 0.13, 'y': body_edge['bottom'] - 0.76 },\n            { 'x': body_edge['right'] - 0.13, 'y': body_edge['top'] + 2.31 },\n            { 'x': body_edge['right'], 'y': body_edge['top'] + 2.31 },\n            { 'x': body_edge['right'], 'y': body_edge['top'] },\n            { 'x': body_edge['left'], 'y': body_edge['top'] },\n        ],\n        layer = 'F.Fab', width = configuration['fab_line_width']))\n\n    #draw the outline of the tab\n    kicad_mod.append(PolygoneLine(polygone = [\n            { 'x': P / 2 - tab_l / 2,'y': y2} ,\n            { 'x': P / 2 - tab_l / 2,'y': y2 + tab_w },\n            { 'x': P / 2 + tab_l / 2,'y': y2 + tab_w },\n            { 'x': P / 2 + tab_l / 2,'y': y2 },\n        ], layer = 'F.Fab', width = configuration['fab_line_width']))\n\n    #draw the outline of the connector on the silkscreen \n    kicad_mod.append(PolygoneLine(polygone = [\n            { 'x': body_edge['left'] - off, 'y': body_edge['top'] - off },\n            { 'x': body_edge['left'] - off, 'y': body_edge['top'] + 2.31 + off },\n            { 'x': body_edge['left'] + 0.13 - off, 'y': body_edge['top'] + 2.31 + off },\n            { 'x': body_edge['left'] + 0.13 - off, 'y': body_edge['bottom'] - 0.76 - off },\n            { 'x': body_edge['left'] - off, 'y': body_edge['bottom'] - 0.76 - off },\n            { 'x': body_edge['left'] - off, 'y': body_edge['bottom'] + off },\n            { 'x': P / 2 - tab_l / 2 - off, 'y': y2 + off} ,\n            { 'x': P / 2 - tab_l / 2 - off, 'y': y2 + tab_w + off },\n            { 'x': P / 2 + tab_l / 2 + off,'y': y2 + tab_w + off },\n            { 'x': P / 2 + tab_l / 2 + off,'y': y2 + off},\n            { 'x': body_edge['right'] + off, 'y': body_edge['bottom'] + off },\n            { 'x': body_edge['right'] + off, 'y': body_edge['bottom'] - 0.76 - off },\n            { 'x': body_edge['right'] - 0.13 + off, 'y': body_edge['bottom'] - 0.76 - off },\n            { 'x': body_edge['right'] - 0.13 + off, 'y': body_edge['top'] + 2.31 + off },\n            { 'x': body_edge['right'] + off, 'y': body_edge['top'] + 2.31 + off },\n            { 'x': body_edge['right'] + off, 'y': body_edge['top'] - off },\n            { 'x': body_edge['left'] - off, 'y': body_edge['top'] - off },\n        ], layer = 'F.SilkS', width = configuration['silk_line_width']))\n\n    #pin-1 marker\n    p1m_off = 0.3 + off\n    p1m_sl = 2\n    pin = [\n        { 'x': body_edge['left'] - p1m_off, 'y': body_edge['top'] + p1m_sl },\n        { 'x': body_edge['left'] - p1m_off, 'y': body_edge['top'] - p1m_off },\n        { 'x': body_edge['left'] + p1m_sl, 'y': body_edge['top'] - p1m_off },\n    ]\n    kicad_mod.append(PolygoneLine(polygone = pin, layer = 'F.SilkS', width = configuration['silk_line_width']))\n\n    sl = 1\n    pin = [\n        {'y': body_edge['top'], 'x':  sl / 2 },\n        {'y': body_edge['top'] + sl / sqrt(2), 'x': 0 },\n        {'y': body_edge['top'], 'x':  -sl / 2 }\n    ]\n    kicad_mod.append(PolygoneLine(polygone = pin, width = configuration['fab_line_width'], layer = 'F.Fab'))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left'] - configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top'] - configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    if variant_params[variant]['mount_pins']:\n       pass\n    else:\n        kicad_mod.append(RectLine(\n            start = [cx1, cy1], end = [cx2, cy2],\n            layer = 'F.CrtYd', width = configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod = kicad_mod, configuration = configuration, body_edges = body_edge,\n        courtyard = { 'top': cy1, 'bottom': cy2 }, fp_name = footprint_name, text_y_inside_position = 'bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix = model3d_path_prefix, lib_name = lib_name, fp_name = footprint_name)\n    kicad_mod.append(Model(filename = model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name = lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename = '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir = output_dir, fp_name = footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Molex/helpers.py",
    "content": "def roundToBase(value, base):\n    if base == 0:\n        return value\n    return round(value/base) * base\n"
  },
  {
    "path": "scripts/Connector/Connector_PCBEdge/molex_EDGELOCK.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))\n\nfrom KicadModTree import *\n\npadNums = [2, 4, 6, 8]\ndatasheet = \"https://www.molex.com/pdm_docs/sd/2008900106_sd.pdf\"\n\nleftSpaceWidth = 2.2\nrightSpaceWidth = 1.4\nspaceHeight = 7.1\ncenterSpaceHeight = 4.2\ncenterSpaceWidth = 0.85\ncenterCardWidth = 5.4\nedgeToHoleBottom = 5.25\nholeWidth = 2.8\nholeHeight = 3.05\nedgeToPadBottom = 0.9\nedgeToPadTop = spaceHeight\npadWidth = 1.0\npadHeight = edgeToPadTop - edgeToPadBottom\npadToPad = 2.0\npadCenterToSpaceSide = 1.1\ndatasheetCDiffB = 0.3\ndatasheetBtoHousingLeft = 1.9\ndatasheetBtoHousingRight = 1.0\nlargerR = 0.4\nsmallerR = 0.2\nchamferLength = 0.5\nchamferComment = \"Chamfer 30 degree \" + str(chamferLength) + \" mm\"\n\nhousingHeight = 20.8\n\nfor padNum in padNums:\n    footprint_name = \"molex_EDGELOCK_\" + str(padNum) + \"-CKT\"\n    datasheetC = centerCardWidth + centerSpaceWidth * 2 + padCenterToSpaceSide * 4 + (padNum - 2) * padToPad\n\n    datasheetB = datasheetC + datasheetCDiffB\n    housingWidth = datasheetB + datasheetBtoHousingLeft + datasheetBtoHousingRight\n    edgeToHousingTop = edgeToHoleBottom + holeHeight\n\n    f = Footprint(footprint_name)\n    f.setDescription(datasheet)\n    f.setTags(\"Connector PCBEdge molex EDGELOCK\")\n    f.setAttribute(\"smd\")\n    f.append(Model(filename=\"${KISYS3DMOD}/Connector_PCBEdge.3dshapes/\" + footprint_name + \".wrl\",\n                   at=[0.0, 0.0, 0.0],\n                   scale=[1.0, 1.0, 1.0],\n                   rotate=[0.0, 0.0, 0.0]))\n\n    s = [1.0, 1.0]\n    sFabRef = [0.7, 0.7]\n\n    t1 = 0.1\n    t2 = 0.15\n\n    wCrtYd = 0.05\n    wFab = 0.1\n    wSilkS = 0.12\n    wCut = wSilkS\n    crtYd = 0.3\n    silkClearance = 0.2\n    bevelLength = 1.0\n\n    xCenter = 0.0\n    xFabRight = housingWidth / 2\n    xSilkRight = xFabRight + silkClearance\n    xRightCrtYd = xSilkRight + crtYd\n\n    xLeftCrtYd = - xRightCrtYd\n    xFabLeft = -xFabRight\n    xSilkLeft = -xSilkRight\n\n    xOffset = (datasheetBtoHousingLeft - datasheetBtoHousingRight) / 2\n    xFabRight -= xOffset\n    xSilkRight -= xOffset\n    xRightCrtYd -= xOffset\n    xLeftCrtYd -= xOffset\n    xFabLeft -= xOffset\n    xSilkLeft -= xOffset\n\n    yCenter = 0.0\n\n    yFabBottom = housingHeight / 2\n    yFabTop = -yFabBottom\n    yEdge = yFabTop + edgeToHousingTop\n    ySilkBottom = yEdge - spaceHeight\n    yBottomCrtYd = yEdge\n\n    ySilkTop = yFabTop - silkClearance\n    yTopCrtYd = ySilkTop - crtYd\n\n    yValue = yFabBottom + 1.25\n    yRef = yFabTop - 1.25\n\n    yOffset = yEdge - edgeToPadBottom - padHeight / 2\n    yFabBottom -= yOffset\n    yFabTop -= yOffset\n    yEdge -= yOffset\n    ySilkBottom -= yOffset\n    yBottomCrtYd -= yOffset\n    ySilkTop -= yOffset\n    yTopCrtYd -= yOffset\n    yValue -= yOffset\n    yRef -= yOffset\n\n    f.append(Text(type=\"reference\", text=\"REF**\", at=[xCenter, yRef],\n                  layer=\"F.SilkS\", size=s, thickness=t2))\n    f.append(Text(type=\"value\", text=footprint_name, at=[xCenter, yValue],\n                  layer=\"F.Fab\", size=s, thickness=t2))\n    f.append(Text(type=\"user\", text=\"%R\", at=[xCenter, yCenter],\n                  layer=\"F.Fab\", size=sFabRef, thickness=t1))\n\n    f.append(RectLine(start=[xLeftCrtYd, yTopCrtYd],\n                      end=[xRightCrtYd, yBottomCrtYd],\n                      layer=\"F.CrtYd\", width=wCrtYd))\n\n    f.append(PolygoneLine(polygone=[[xFabRight, yFabTop],\n                                    [xFabRight, yFabBottom],\n                                    [xFabLeft, yFabBottom],\n                                    [xFabLeft, yFabTop + bevelLength],\n                                    [xFabLeft + bevelLength, yFabTop],\n                                    [xFabRight, yFabTop]],\n                          layer=\"F.Fab\", width=wFab))\n\n    f.append(PolygoneLine(polygone=[[xSilkLeft, ySilkBottom],\n                                    [xSilkLeft, ySilkTop + bevelLength],\n                                    [xSilkLeft + bevelLength, ySilkTop],\n                                    [xSilkRight, ySilkTop],\n                                    [xSilkRight, ySilkBottom]],\n                          layer=\"F.SilkS\", width=wSilkS))\n\n    padShape = Pad.SHAPE_ROUNDRECT\n    radiusRatio = 0.2\n    padSize = [padWidth, padHeight]\n    yPad = yEdge - edgeToPadBottom - padHeight / 2\n    xPadLeft = xFabLeft + datasheetBtoHousingLeft + padCenterToSpaceSide + datasheetCDiffB / 2\n\n    for i in range(0, padNum):\n        x = xPadLeft + padToPad * i\n        if (i >= padNum/2):\n            x += centerCardWidth + centerSpaceWidth * 2 + padCenterToSpaceSide * 2 - padToPad\n        f.append(Pad(number=i+1, type=Pad.TYPE_SMT, shape=padShape,\n                     at=[x, yPad], size=padSize, layers=Pad.LAYERS_SMT,\n                     radius_ratio=radiusRatio))\n\n    padCardWidth = padToPad * (padNum / 2 - 1) + padCenterToSpaceSide * 2\n    xSpaceLeftRight = xFabLeft + datasheetBtoHousingLeft + datasheetCDiffB / 2\n    xSpaceCneterLeftLeft = xSpaceLeftRight + padCardWidth\n    xSpaceCneterRightLeft = xSpaceCneterLeftLeft + centerSpaceWidth + centerCardWidth\n    xSpaceRightLeft = xSpaceCneterRightLeft + centerSpaceWidth + padCardWidth\n    f.append(PolygoneLine(polygone=[[xSpaceLeftRight - leftSpaceWidth, yEdge],\n                                    [xSpaceLeftRight - leftSpaceWidth, yEdge - spaceHeight + largerR]],\n             layer=\"Edge.Cuts\", width=wCut))\n    f.append(Arc(center=[xSpaceLeftRight - leftSpaceWidth + largerR, yEdge - spaceHeight + largerR],\n                 start=[xSpaceLeftRight - leftSpaceWidth, yEdge - spaceHeight + largerR],\n                 angle=90.0, layer=\"Edge.Cuts\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xSpaceLeftRight - leftSpaceWidth + largerR, yEdge - spaceHeight],\n                                    [xSpaceLeftRight - largerR, yEdge - spaceHeight]],\n             layer=\"Edge.Cuts\", width=wCut))\n    f.append(Arc(center=[xSpaceLeftRight - largerR, yEdge - spaceHeight + largerR],\n                 start=[xSpaceLeftRight - largerR, yEdge - spaceHeight],\n                 angle=90.0, layer=\"Edge.Cuts\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xSpaceLeftRight, yEdge - spaceHeight + largerR],\n                                    [xSpaceLeftRight, yEdge],\n                                    [xSpaceCneterLeftLeft, yEdge],\n                                    [xSpaceCneterLeftLeft, yEdge - centerSpaceHeight + smallerR]],\n             layer=\"Edge.Cuts\", width=wCut))\n    f.append(Arc(center=[xSpaceCneterLeftLeft + smallerR, yEdge - centerSpaceHeight + smallerR],\n                 start=[xSpaceCneterLeftLeft, yEdge - centerSpaceHeight + smallerR],\n                 angle=90.0, layer=\"Edge.Cuts\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xSpaceCneterLeftLeft + smallerR, yEdge - centerSpaceHeight],\n                                    [xSpaceCneterLeftLeft + centerSpaceWidth - smallerR, yEdge - centerSpaceHeight]],\n             layer=\"Edge.Cuts\", width=wCut))\n    f.append(Arc(center=[xSpaceCneterLeftLeft + centerSpaceWidth - smallerR, yEdge - centerSpaceHeight + smallerR],\n                 start=[xSpaceCneterLeftLeft + centerSpaceWidth - smallerR, yEdge - centerSpaceHeight],\n                 angle=90.0, layer=\"Edge.Cuts\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xSpaceCneterLeftLeft + centerSpaceWidth, yEdge - centerSpaceHeight + smallerR],\n                                    [xSpaceCneterLeftLeft + centerSpaceWidth, yEdge],\n                                    [xSpaceCneterRightLeft, yEdge],\n                                    [xSpaceCneterRightLeft, yEdge - centerSpaceHeight + smallerR]],\n             layer=\"Edge.Cuts\", width=wCut))\n    f.append(Arc(center=[xSpaceCneterRightLeft + smallerR, yEdge - centerSpaceHeight + smallerR],\n                 start=[xSpaceCneterRightLeft, yEdge - centerSpaceHeight + smallerR],\n                 angle=90.0, layer=\"Edge.Cuts\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xSpaceCneterRightLeft + smallerR, yEdge - centerSpaceHeight],\n                                    [xSpaceCneterRightLeft + centerSpaceWidth - smallerR, yEdge - centerSpaceHeight]],\n             layer=\"Edge.Cuts\", width=wCut))\n    f.append(Arc(center=[xSpaceCneterRightLeft + centerSpaceWidth - smallerR, yEdge - centerSpaceHeight + smallerR],\n                 start=[xSpaceCneterRightLeft + centerSpaceWidth - smallerR, yEdge - centerSpaceHeight],\n                 angle=90.0, layer=\"Edge.Cuts\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xSpaceCneterRightLeft + centerSpaceWidth, yEdge - centerSpaceHeight + smallerR],\n                                    [xSpaceCneterRightLeft + centerSpaceWidth, yEdge],\n                                    [xSpaceRightLeft, yEdge],\n                                    [xSpaceRightLeft, yEdge - spaceHeight + largerR]],\n             layer=\"Edge.Cuts\", width=wCut))\n    f.append(Arc(center=[xSpaceRightLeft + largerR, yEdge - spaceHeight + largerR],\n                 start=[xSpaceRightLeft, yEdge - spaceHeight + largerR],\n                 angle=90.0, layer=\"Edge.Cuts\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xSpaceRightLeft + largerR, yEdge - spaceHeight],\n                                    [xSpaceRightLeft + rightSpaceWidth - largerR, yEdge - spaceHeight]],\n             layer=\"Edge.Cuts\", width=wCut))\n    f.append(Arc(center=[xSpaceRightLeft + rightSpaceWidth - largerR, yEdge - spaceHeight + largerR],\n                 start=[xSpaceRightLeft + rightSpaceWidth - largerR, yEdge - spaceHeight],\n                 angle=90.0, layer=\"Edge.Cuts\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xSpaceRightLeft + rightSpaceWidth, yEdge - spaceHeight + largerR],\n                                    [xSpaceRightLeft + rightSpaceWidth, yEdge]],\n             layer=\"Edge.Cuts\", width=wCut))\n\n    xHoleLeft = xSpaceCneterLeftLeft + centerSpaceWidth + (centerCardWidth - holeWidth) / 2\n    yHoleBottom = yEdge - edgeToHoleBottom\n    f.append(Arc(center=[xHoleLeft + largerR, yHoleBottom - largerR],\n                 start=[xHoleLeft, yHoleBottom - largerR],\n                 angle=-90.0, layer=\"Edge.Cuts\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xHoleLeft + largerR, yHoleBottom],\n                                    [xHoleLeft + holeWidth - largerR, yHoleBottom]],\n             layer=\"Edge.Cuts\", width=wCut))\n    f.append(Arc(center=[xHoleLeft + holeWidth - largerR, yHoleBottom - largerR],\n                 start=[xHoleLeft + holeWidth - largerR, yHoleBottom],\n                 angle=-90.0, layer=\"Edge.Cuts\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xHoleLeft + holeWidth, yHoleBottom - largerR],\n                                    [xHoleLeft + holeWidth, yHoleBottom - holeHeight + largerR]],\n             layer=\"Edge.Cuts\", width=wCut))\n    f.append(Arc(center=[xHoleLeft + holeWidth - largerR, yHoleBottom - holeHeight + largerR],\n                 start=[xHoleLeft + holeWidth, yHoleBottom - holeHeight + largerR],\n                 angle=-90.0, layer=\"Edge.Cuts\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xHoleLeft + holeWidth - largerR, yHoleBottom - holeHeight],\n                                    [xHoleLeft + largerR, yHoleBottom - holeHeight]],\n             layer=\"Edge.Cuts\", width=wCut))\n    f.append(Arc(center=[xHoleLeft + largerR, yHoleBottom - holeHeight + largerR],\n                 start=[xHoleLeft + largerR, yHoleBottom - holeHeight],\n                 angle=-90.0, layer=\"Edge.Cuts\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xHoleLeft, yHoleBottom - holeHeight + largerR],\n                                    [xHoleLeft, yHoleBottom - largerR]],\n             layer=\"Edge.Cuts\", width=wCut))\n\n    f.append(PolygoneLine(polygone=[[xSpaceLeftRight, yEdge - chamferLength],\n                                    [xSpaceCneterLeftLeft, yEdge - chamferLength]],\n             layer=\"Dwgs.User\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xSpaceCneterLeftLeft + centerSpaceWidth, yEdge - chamferLength],\n                                    [xSpaceCneterRightLeft, yEdge - chamferLength]],\n             layer=\"Dwgs.User\", width=wCut))\n    f.append(PolygoneLine(polygone=[[xSpaceCneterRightLeft + centerSpaceWidth, yEdge - chamferLength],\n                                    [xSpaceRightLeft, yEdge - chamferLength]],\n             layer=\"Dwgs.User\", width=wCut))\n    f.append(Text(type=\"user\", text=chamferComment, at=[xCenter, yEdge + sFabRef[0]],\n                  layer=\"Cmts.User\", size=sFabRef, thickness=t2))\n\n    file_handler = KicadFileHandler(f)\n    file_handler.writeFile(footprint_name + \".kicad_mod\")\n"
  },
  {
    "path": "scripts/Connector/Connector_PhoenixContact/config_phoenix_KLCv1.0.yaml",
    "content": "# This holds the configuration information\n# using this config file will create KLCv2.x compatible footprints.\n\nlib_name_format_str: \"Connectors_Phoenix\"\n#lib_name_format_str: \"Conn_Phoenix_{series:s}-{style:%s}_{pitch:.2f}\"\nmanufacturer: \"PhoenixContact\"\n\n\n#fp_name_format_string: '{man:s}_{series:s}_{mpn:s}_{num_pins:02d}x{pitch:.2f}mm_{orientation:s}{flanged:s}{mount_hole:s}'\nfp_name_format_string: '{man:s}_{mpn:s}_{num_pins:02d}x{pitch:.2f}mm_{orientation:s}{flanged:s}{mount_hole:s}'\n#mpn_format_string: '{subseries:s}_{rating:s}_{num_pins:s}-{style:s}{pitch:s}'\nmpn_format_string: '{subseries:s}-{style:s}'\nmpn_format_string_description: '{subseries:s}_{rating:s}/{num_pins:d}-{style:s}{pitch:s}'\n3d_model_prefix: '${KISYS3DMOD}/'\n#keywords_format_string: 'phoenix_contact connector {mpn:s}{param_name:s}{order_info:s}'\nkeywords_format_string: 'phoenix_contact connector {param_name:s}'\n\norientation_str: ['Vertical', 'Angled']\nflanged_str: ['', '_ThreadedFlange']\nmount_hole_str: ['', '_MountHole']\n\npin_layers: ['*.Cu', '*.Mask'] #, '*.Paste' through hole: no paste!\nmount_hole_layers: ['*.Cu', '*.Mask']\n\nwith_fab_layer :  False\ninner_details_on_fab : False\ncourtyard_for_mountscrews : True\n"
  },
  {
    "path": "scripts/Connector/Connector_PhoenixContact/config_phoenix_KLCv1.1.yaml",
    "content": "# This holds the configuration information\n# using this config file will create KLCv2.x compatible footprints.\n\nlib_name_format_str: \"Connectors_Phoenix\"\n#lib_name_format_str: \"Conn_Phoenix_{series:s}-{style:%s}_{pitch:.2f}\"\nmanufacturer: \"PhoenixContact\"\n\n\n#fp_name_format_string: '{man:s}_{series:s}_{mpn:s}_{num_pins:02d}x{pitch:.2f}mm_{orientation:s}{flanged:s}{mount_hole:s}'\nfp_name_format_string: '{man:s}_{mpn:s}_{num_pins:02d}x{pitch:.2f}mm_{orientation:s}{flanged:s}{mount_hole:s}'\n#mpn_format_string: '{subseries:s}_{rating:s}_{num_pins:s}-{style:s}{pitch:s}'\nmpn_format_string: '{subseries:s}-{style:s}'\nmpn_format_string_description: '{subseries:s}_{rating:s}/{num_pins:d}-{style:s}{pitch:s}'\n3d_model_prefix: '${KISYS3DMOD}/'\n#keywords_format_string: 'phoenix_contact connector {mpn:s}{param_name:s}{order_info:s}'\nkeywords_format_string: 'phoenix_contact connector {param_name:s}'\n\norientation_str: ['Vertical', 'Angled']\nflanged_str: ['', '_ThreadedFlange']\nmount_hole_str: ['', '_MountHole']\n\npin_layers: ['*.Cu', '*.Mask'] #, '*.Paste' through hole: no paste!\nmount_hole_layers: ['*.Cu', '*.Mask']\n\nwith_fab_layer :  True\ninner_details_on_fab : False\ncourtyard_for_mountscrews : True\n"
  },
  {
    "path": "scripts/Connector/Connector_PhoenixContact/config_phoenix_KLCv2.0.yaml",
    "content": "# This holds the configuration information\n# using this config file will create KLCv2.x compatible footprints.\n\nlib_name_format_str: \"Connectors_Phoenix\"\n#lib_name_format_str: \"Conn_Phoenix_{series:s}-{style:%s}_{pitch:.2f}\"\nmanufacturer: \"PhoenixContact\"\n\n\n#fp_name_format_string: '{man:s}_{series:s}_{mpn:s}_{num_pins:02d}x{pitch:.2f}mm_{orientation:s}{flanged:s}{mount_hole:s}'\nfp_name_format_string: '{man:s}_{mpn:s}_{num_pins:02d}x{pitch:.2f}mm_{orientation:s}{flanged:s}{mount_hole:s}'\n#mpn_format_string: '{subseries:s}_{rating:s}_{num_pins:s}-{style:s}{pitch:s}'\nmpn_format_string: '{subseries:s}-{style:s}'\nmpn_format_string_description: '{subseries:s}_{rating:s}/{num_pins:d}-{style:s}{pitch:s}'\n3d_model_prefix: '${KISYS3DMOD}/'\n#keywords_format_string: 'phoenix_contact connector {mpn:s}{param_name:s}{order_info:s}'\nkeywords_format_string: 'phoenix_contact connector {param_name:s}'\n\norientation_str: ['Vertical', 'Angled']\nflanged_str: ['', '_ThreadedFlange']\nmount_hole_str: ['', '_MountHole']\n\npin_layers: ['*.Cu', '*.Mask'] #, '*.Paste' through hole: no paste!\nmount_hole_layers: ['*.Cu', '*.Mask']\n\nwith_fab_layer :  True\ninner_details_on_fab : False\ncourtyard_for_mountscrews : True\n"
  },
  {
    "path": "scripts/Connector/Connector_PhoenixContact/config_phoenix_KLCv3.0.yaml",
    "content": "# This holds the configuration information\n# using this config file will create KLCv2.x compatible footprints.\n\n#lib_name_format_str: \"Conn_Phoenix_{series:s}-{style:%s}_{pitch:.2f}\"\nlib_name_format_str: \"Connector_Phoenix_{series:s}{suffix:s}\"\nmanufacturer: \"PhoenixContact\"\n\n\n#fp_name_format_string: '{man:s}_{series:s}_{mpn:s}_{num_pins:02d}x{pitch:.2f}mm_{orientation:s}{flanged:s}{mount_hole:s}'\nfp_name_format_string: '{man:s}_{mpn:s}_{num_rows:d}x{num_pins:02d}_P{pitch:.2f}mm_{orientation:s}{flanged:s}{mount_hole:s}'\n\nmpn_format_string: '{subseries:s}_{rating:s}_{num_pins:d}-{style:s}{pitch:s}'\nmpn_format_string_description: '{subseries:s}_{rating:s}/{num_pins:d}-{style:s}{pitch:s}'\n#mpn_format_string: '{subseries:s}-{style:s}'\n3d_model_prefix: '${KISYS3DMOD}/'\n#keywords_format_string: 'phoenix_contact connector {mpn:s}{param_name:s}{order_info:s}'\nkeywords_format_string: 'phoenix_contact connector {param_name:s}'\n\norientation_str: ['Vertical', 'Horizontal']\nflanged_str: ['', '_ThreadedFlange']\nmount_hole_str: ['', '_MountHole']\n\npin_layers: ['*.Cu', '*.Mask'] #, '*.Paste' through hole: no paste!\nmount_hole_layers: ['*.Cu', '*.Mask']\n\nwith_fab_layer :  True\ninner_details_on_fab : False\ncourtyard_for_mountscrews : True\n"
  },
  {
    "path": "scripts/Connector/Connector_PhoenixContact/config_phoenix_TERA.yaml",
    "content": "# This holds the configuration information\n# using this config file will create KLCv2.x compatible footprints.\n\nlib_name_format_str: \"Tera_Connectors_Phoenix\"\n#lib_name_format_str: \"Conn_Phoenix_{series:s}-{style:%s}_{pitch:.2f}\"\nmanufacturer: \"PhoenixContact\"\n\n\n#fp_name_format_string: '{man:s}_{series:s}_{mpn:s}_{num_pins:02d}x{pitch:.2f}mm_{orientation:s}{flanged:s}{mount_hole:s}'\nfp_name_format_string: '{man:s}_{mpn:s}_{num_pins:02d}x{pitch:.2f}mm_{orientation:s}{flanged:s}{mount_hole:s}'\n#mpn_format_string: '{subseries:s}_{rating:s}_{num_pins:s}-{style:s}{pitch:s}'\nmpn_format_string: '{subseries:s}-{style:s}'\nmpn_format_string_description: '{subseries:s}_{rating:s}/{num_pins:d}-{style:s}{pitch:s}'\n3d_model_prefix: '${TERA3DMOD}/'\n#keywords_format_string: 'phoenix_contact connector {mpn:s}{param_name:s}{order_info:s}'\nkeywords_format_string: 'phoenix_contact connector {param_name:s}'\n\norientation_str: ['Vertical', 'Angled']\nflanged_str: ['', '_ThreadedFlange']\nmount_hole_str: ['', '_MountHole']\n\npin_layers: ['*.Cu', '*.Mask'] #, '*.Paste' through hole: no paste!\nmount_hole_layers: ['*.Cu', '*.Mask']\n\nwith_fab_layer :  True\ninner_details_on_fab : False\ncourtyard_for_mountscrews : True\n"
  },
  {
    "path": "scripts/Connector/Connector_PhoenixContact/helpers.py",
    "content": "def round_to(value, base):\n    return round(value/base) * base\n\ndef v_add(p1,p2):\n    return [p1[0]+p2[0],p1[1]+p2[1]]\n\ndef round_crty_point(point, grid_size):\n    return [round_to(point[0], grid_size),round_to(point[1], grid_size)]\n\ndef offset_dir(coordinate, offset, center=0):\n    if coordinate > center:\n        return coordinate + offset\n    elif coordinate< center:\n        return coordinate - offset\n    else:\n        return coordinate\n\ndef v_offset(point, offset, center = (0,0)):\n    if type(center) is dict:\n        center_x = float(center.get('x', 0.))\n        center_y = float(center.get('y', 0.))\n    else:\n        center_x=center[0]\n        center_y=center[1]\n\n    if type(point) is dict:\n        result={}\n        result['x']=offset_dir(float(point.get('x', 0.)), offset, center_x)\n        result['y']=offset_dir(float(point.get('y', 0.)), offset, center_y)\n        return result\n\n    return [\n        point[0] + (offset if point[0] >=center_x else -offset),\n        point[1] + (offset if point[1] >=center_y else -offset)\n    ]\n\ndef offset_polyline(polyline_points, offset, center=(0,0)):\n    resulting_points = []\n    for point in polyline_points:\n        resulting_points.append(v_offset(point,offset,center))\n\n    return resulting_points\n\ndef create_pin1_marker_triangle(bottom_y, center_x = 0, dimensions = [0.6,0.6], with_top_line = True):\n    marker_width = dimensions[0]\n    marker_height = dimensions[1]\n\n    marker_top=bottom_y-marker_height\n    marker_poly=[\n        {'x':center_x+marker_width/2, 'y':marker_top},\n        {'x':center_x, 'y':bottom_y},\n        {'x':center_x-marker_width/2, 'y':marker_top}\n    ]\n    if with_top_line:\n        marker_poly.append({'x':center_x+marker_width/2, 'y':marker_top})\n    return marker_poly\n\ndef create_pin1_marker_corner(top_y, left_x, sidelength = [1,1]):\n    marker_poly=[\n        {'x':left_x, 'y':top_y + sidelength[1]},\n        {'x':left_x, 'y':top_y},\n        {'x':left_x + sidelength[0], 'y':top_y}\n    ]\n\n    return marker_poly\n"
  },
  {
    "path": "scripts/Connector/Connector_PhoenixContact/mc.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nfrom helpers import *\nimport re\nimport fnmatch\nimport argparse\nimport yaml\n\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load KicadModTree path\n#add KicadModTree to searchpath using export PYTHONPATH=\"${PYTHONPATH}<absolute path>/kicad-footprint-generator/\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nfrom mc_params import seriesParams, dimensions, generate_description, all_params\n\nseries = ['MC', '1,5']\n\ndef generate_one_footprint(motel, params, configuration):\n\n    # Through-hole type shrouded header, Top entry type\n    subseries, connector_style = params.series_name.split('-')\n    pitch_mpn = '-{:g}'.format(params.pin_pitch)\n    suffix = '_HighVoltage' if params.pin_pitch >= 5.08 else ''\n    lib_name = configuration['lib_name_format_str'].format(series=series[0],\n        style=series[1], pitch=params.pin_pitch, suffix=suffix)\n    mpn = configuration['mpn_format_string'].format(subseries=subseries, style = connector_style,\n        rating=series[1], num_pins=params.num_pins, pitch=pitch_mpn)\n    footprint_name = configuration['fp_name_format_string'].format(man = configuration['manufacturer'],\n        series = series[0], mpn = mpn, num_rows = 1,\n        num_pins = params.num_pins, mounting_pad = \"\", pitch = params.pin_pitch,\n        orientation = configuration['orientation_str'][1] if params.angled else configuration['orientation_str'][0],\n        flanged = configuration['flanged_str'][1] if params.flanged else configuration['flanged_str'][0],\n        mount_hole = configuration['mount_hole_str'][1] if params.mount_hole else configuration['mount_hole_str'][0])\n\n\n    calc_dim = dimensions(params)\n\n    body_top_left=[calc_dim.left_to_pin,params.back_to_pin]\n    body_bottom_right=v_add(body_top_left,[calc_dim.length,calc_dim.width])\n    silk_top_left=v_offset(body_top_left, configuration['silk_fab_offset'])\n    silk_bottom_right=v_offset(body_bottom_right, configuration['silk_fab_offset'])\n    center_x = (params.num_pins-1)/2.0*params.pin_pitch\n    kicad_mod = Footprint(footprint_name)\n\n    body_edge={\n        'left': body_top_left[0],\n        'top': body_top_left[1],\n        'right': body_bottom_right[0],\n        'bottom': body_bottom_right[1],\n    }\n\n    mpn = configuration['mpn_format_string_description'].format(subseries=subseries, style = connector_style,\n        rating=series[1], num_pins=params.num_pins, pitch=pitch_mpn)\n    kicad_mod.setDescription(generate_description(params, mpn))\n    kicad_mod.setTags(configuration['keywords_format_string'].format(mpn=mpn, param_name=model,\n        order_info = ', '.join(params.order_info)))\n\n    #add the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[0, 0],\n        x_spacing=params.pin_pitch, pincount=params.num_pins,\n        size=[params.pin_Sx, params.pin_Sy], drill=seriesParams.drill,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=configuration['pin_layers'],\n        **optional_pad_params))\n\n    if params.mount_hole:\n        kicad_mod.append(Pad(number='\"\"', type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n                            at=calc_dim.mount_hole_left, size=[seriesParams.mount_drill, seriesParams.mount_drill], \\\n                            drill=seriesParams.mount_drill, layers=configuration['mount_hole_layers']))\n        kicad_mod.append(Pad(number='\"\"', type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n                            at=calc_dim.mount_hole_right, size=[seriesParams.mount_drill, seriesParams.mount_drill], \\\n                            drill=seriesParams.mount_drill, layers=configuration['mount_hole_layers']))\n    #add an outline around the pins\n\n    # create silscreen\n\n\n    if params.angled:\n        #kicad_mod.append(RectLine(start=silk_top_left, end=silk_bottom_right, layer='F.SilkS'))\n        silkGab = params.pin_Sx/2.0+seriesParams.silk_pad_clearance\n        kicad_mod.append(Line(start=silk_top_left, end=[silk_top_left[0], silk_bottom_right[1]], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[silk_top_left[0], silk_bottom_right[1]], end=silk_bottom_right, layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=silk_bottom_right, end=[silk_bottom_right[0], silk_top_left[1]], layer='F.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Line(start=silk_top_left, end=[-silkGab, silk_top_left[1]], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[silk_bottom_right[0], silk_top_left[1]], end=[(params.num_pins-1)*params.pin_pitch+silkGab, silk_top_left[1]],\\\n                        layer='F.SilkS', width=configuration['silk_line_width']))\n\n        for p in range(params.num_pins-1):\n            kicad_mod.append(Line(start=[p*params.pin_pitch+silkGab, silk_top_left[1]], \\\n                            end=[(p+1)*params.pin_pitch-silkGab, silk_top_left[1]], layer='F.SilkS', width=configuration['silk_line_width']))\n\n        if configuration['with_fab_layer']:\n            kicad_mod.append(RectLine(start=body_top_left, end=body_bottom_right, layer='F.Fab', width=configuration['fab_line_width']))\n\n        left = silk_top_left[0] + (seriesParams.flange_lenght if params.flanged else 0)\n        right = silk_bottom_right[0] - (seriesParams.flange_lenght if params.flanged else 0)\n        scoreline_y = seriesParams.scoreline_from_back+params.back_to_pin\n        kicad_mod.append(Line(start=[left, scoreline_y], end=[right, scoreline_y], layer='F.SilkS', width=configuration['silk_line_width']))\n        if configuration['inner_details_on_fab']:\n            kicad_mod.append(Line(start=[left +(0 if params.flanged else configuration['silk_fab_offset']), scoreline_y],\n                end=[right-(0 if params.flanged else configuration['silk_fab_offset']), scoreline_y], layer='F.Fab', width=configuration['fab_line_width']))\n        if params.flanged:\n            kicad_mod.append(Line(start=[left, silk_top_left[1]], end=[left, silk_bottom_right[1]], layer='F.SilkS', width=configuration['silk_line_width']))\n            kicad_mod.append(Line(start=[right, silk_top_left[1]], end=[right, silk_bottom_right[1]], layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['inner_details_on_fab']:\n                kicad_mod.append(Line(start=[left, body_top_left[1]], end=[left, body_bottom_right[1]], layer='F.Fab', width=configuration['fab_line_width']))\n                kicad_mod.append(Line(start=[right, body_top_left[1]], end=[right, body_bottom_right[1]], layer='F.Fab', width=configuration['fab_line_width']))\n    else:\n        if not params.flanged:\n            kicad_mod.append(RectLine(start=silk_top_left, end=silk_bottom_right, layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['with_fab_layer']:\n                kicad_mod.append(RectLine(start=body_top_left, end=body_bottom_right, layer='F.Fab', width=configuration['fab_line_width']))\n        else:\n            flange_cutout = calc_dim.width-calc_dim.flange_width\n            outline_poly=[\n                    {'x':silk_top_left[0], 'y':silk_bottom_right[1]},\n                    {'x':silk_bottom_right[0], 'y':silk_bottom_right[1]},\n                    {'x':silk_bottom_right[0], 'y':silk_top_left[1]+flange_cutout},\n                    {'x':silk_bottom_right[0]-seriesParams.flange_lenght, 'y':silk_top_left[1]+flange_cutout},\n                    {'x':silk_bottom_right[0]-seriesParams.flange_lenght, 'y':silk_top_left[1]},\n                    {'x':silk_top_left[0]+seriesParams.flange_lenght, 'y':silk_top_left[1]},\n                    {'x':silk_top_left[0]+seriesParams.flange_lenght, 'y':silk_top_left[1]+flange_cutout},\n                    {'x':silk_top_left[0], 'y':silk_top_left[1]+flange_cutout},\n                    {'x':silk_top_left[0], 'y':silk_bottom_right[1]}\n                ]\n            kicad_mod.append(PolygoneLine(polygone=outline_poly, layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['with_fab_layer']:\n                outline_poly=offset_polyline(outline_poly,-configuration['silk_fab_offset'],(center_x,0))\n                kicad_mod.append(PolygoneLine(polygone=outline_poly, layer=\"F.Fab\", width=configuration['fab_line_width']))\n\n        if params.flanged:\n            kicad_mod.append(Circle(center=calc_dim.mount_hole_left, radius=1.9, layer='F.SilkS', width=configuration['silk_line_width']))\n            kicad_mod.append(Circle(center=calc_dim.mount_hole_right, radius=1.9, layer='F.SilkS', width=configuration['silk_line_width']))\n            if not params.mount_hole:\n                kicad_mod.append(Circle(center=calc_dim.mount_hole_left, radius=1, layer='F.SilkS', width=configuration['silk_line_width']))\n                kicad_mod.append(Circle(center=calc_dim.mount_hole_right, radius=1, layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['inner_details_on_fab']:\n                kicad_mod.append(Circle(center=calc_dim.mount_hole_left, radius=1.9, layer='F.Fab', width=configuration['fab_line_width']))\n                kicad_mod.append(Circle(center=calc_dim.mount_hole_right, radius=1.9, layer='F.Fab', width=configuration['fab_line_width']))\n                kicad_mod.append(Circle(center=calc_dim.mount_hole_left, radius=1, layer='F.Fab', width=configuration['fab_line_width']))\n                kicad_mod.append(Circle(center=calc_dim.mount_hole_right, radius=1, layer='F.Fab', width=configuration['fab_line_width']))\n\n        for i in range(params.num_pins):\n            plug_outline_translation = Translation(i*params.pin_pitch, 0)\n            plug_outline_poly=[\n                {'x':-seriesParams.plug_arc_len/2.0, 'y':calc_dim.plug_front},\n                {'x':-seriesParams.plug_cut_len/2.0, 'y':calc_dim.plug_front},\n                {'x':-seriesParams.plug_cut_len/2.0, 'y':calc_dim.plug_front-seriesParams.plug_cut_width},\n                {'x':-seriesParams.plug_seperator_distance/2.0, 'y':calc_dim.plug_front-seriesParams.plug_cut_width},\n                {'x':-seriesParams.plug_seperator_distance/2.0, 'y':calc_dim.plug_back+seriesParams.plug_trapezoid_width},\n                {'x':-seriesParams.plug_trapezoid_short/2.0, 'y':calc_dim.plug_back+seriesParams.plug_trapezoid_width},\n                {'x':-seriesParams.plug_trapezoid_long/2.0, 'y':calc_dim.plug_back},\n                {'x':seriesParams.plug_trapezoid_long/2.0, 'y':calc_dim.plug_back},\n                {'x':seriesParams.plug_trapezoid_short/2.0, 'y':calc_dim.plug_back+seriesParams.plug_trapezoid_width},\n                {'x':seriesParams.plug_seperator_distance/2.0, 'y':calc_dim.plug_back+seriesParams.plug_trapezoid_width},\n                {'x':seriesParams.plug_seperator_distance/2.0, 'y':calc_dim.plug_front-seriesParams.plug_cut_width},\n                {'x':seriesParams.plug_cut_len/2.0, 'y':calc_dim.plug_front-seriesParams.plug_cut_width},\n                {'x':seriesParams.plug_cut_len/2.0, 'y':calc_dim.plug_front},\n                {'x':seriesParams.plug_arc_len/2.0, 'y':calc_dim.plug_front}\n            ]\n            plug_outline_translation.append(PolygoneLine(polygone=plug_outline_poly, layer='F.SilkS', width=configuration['silk_line_width']))\n            plug_outline_translation.append(Arc(start=[-seriesParams.plug_arc_len/2.0,calc_dim.plug_front], center=[0,calc_dim.plug_front+1.7], angle=47.6, layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['inner_details_on_fab']:\n                plug_outline_translation.append(PolygoneLine(polygone=plug_outline_poly,  layer=\"F.Fab\", width=configuration['fab_line_width']))\n                plug_outline_translation.append(Arc(start=[-seriesParams.plug_arc_len/2.0,calc_dim.plug_front], center=[0,calc_dim.plug_front+1.7], angle=47.6,  layer=\"F.Fab\", width=configuration['fab_line_width']))\n            kicad_mod.append(plug_outline_translation)\n    if params.mount_hole:\n        kicad_mod.append(Circle(center=calc_dim.mount_hole_left, radius=seriesParams.mount_screw_head_r+configuration['silk_fab_offset'], layer='B.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Circle(center=calc_dim.mount_hole_right, radius=seriesParams.mount_screw_head_r+configuration['silk_fab_offset'], layer='B.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Circle(center=calc_dim.mount_hole_right, radius=seriesParams.mount_screw_head_r, layer='B.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(Circle(center=calc_dim.mount_hole_left, radius=seriesParams.mount_screw_head_r, layer='B.Fab', width=configuration['fab_line_width']))\n\n    ################################################## Courtyard ##################################################\n    if params.angled:\n        crtyd_top_left=v_offset([silk_top_left[0],-params.pin_Sy/2], configuration['courtyard_offset']['connector'])\n    else:\n        crtyd_top_left=v_offset(body_top_left, configuration['courtyard_offset']['connector'])\n    crtyd_bottom_right=v_offset(body_bottom_right, configuration['courtyard_offset']['connector'])\n    kicad_mod.append(RectLine(start=round_crty_point(crtyd_top_left, configuration['courtyard_grid']), end=round_crty_point(crtyd_bottom_right, configuration['courtyard_grid']), layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    if params.mount_hole and configuration['courtyard_for_mountscrews']:\n        kicad_mod.append(Circle(center=calc_dim.mount_hole_right, radius=seriesParams.mount_screw_head_r+configuration['courtyard_offset']['connector'], layer='B.CrtYd', width=configuration['courtyard_line_width']))\n        kicad_mod.append(Circle(center=calc_dim.mount_hole_left, radius=seriesParams.mount_screw_head_r+configuration['courtyard_offset']['connector'], layer='B.CrtYd', width=configuration['courtyard_line_width']))\n\n    ################################################# Text Fields #################################################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':crtyd_top_left[1], 'bottom':crtyd_bottom_right[1]}, fp_name=footprint_name, text_y_inside_position='top')\n\n\n    ################################################# Pin 1 Marker #################################################\n    if not params.angled:\n        pin1_marker_poly = create_pin1_marker_corner(crtyd_top_left[1],\n            body_top_left[0] - configuration['courtyard_offset']['connector'] +\n            (seriesParams.flange_lenght if params.flanged else 0), [2,1.25])\n        kicad_mod.append(PolygoneLine(polygone=pin1_marker_poly, layer='F.SilkS', width=configuration['silk_line_width']))\n        if configuration['with_fab_layer']:\n            kicad_mod.append(PolygoneLine(polygone=pin1_marker_poly, layer='F.Fab', width=configuration['fab_line_width']))\n    else:\n        kicad_mod.append(PolygoneLine(polygone=create_pin1_marker_triangle(-params.pin_Sy/2-0.2),\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        if configuration['with_fab_layer']:\n            kicad_mod.append(PolygoneLine(\n                polygone=create_pin1_marker_triangle(bottom_y = 0,\n                    dimensions = [params.pin_Sx - 0.2, -body_top_left[1]], with_top_line = False),\n                layer='F.Fab', width=configuration['fab_line_width']))\n\n    #################################################### 3d file ###################################################\n    p3dname = '{prefix:s}{lib_name:s}.3dshapes/{fp_name}.wrl'.format(prefix = configuration.get('3d_model_prefix', '${KISYS3DMOD}/'), lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=p3dname,\n                           at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n\n    file_handler = KicadFileHandler(kicad_mod)\n    out_dir = '{:s}.pretty/'.format(lib_name)\n    if not os.path.exists(out_dir):\n        os.makedirs(out_dir)\n    file_handler.writeFile('{:s}.pretty/{:s}.kicad_mod'.format(lib_name, footprint_name))\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='config_phoenix_KLCv3.0.yaml')\n    parser.add_argument('--model_filter', type=str, nargs='?', help='define a filter for what should be generated.', default=\"*\")\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    model_filter_regobj=re.compile(fnmatch.translate(args.model_filter))\n    for model, params in all_params.items():\n        if model_filter_regobj.match(model):\n            generate_one_footprint(model, params, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_PhoenixContact/mc_params.py",
    "content": "from collections import namedtuple\nfrom collections import OrderedDict\n\nclass seriesParams():\n    drill = 1.2\n    annular_ring = 0.3 # overwritten by minimum pad to pad clearance.\n\n    mount_drill = 2.4\n    mount_screw_head_r = 2.1\n    flange_lenght = 4.8\n    scoreline_from_back = 6.0\n\n    plug_cut_len = 3.0\n    plug_cut_width = 4.3\n    plug_arc_len = 1.5\n    plug_trapezoid_short = 2.5\n    plug_trapezoid_long = 3.0\n    plug_trapezoid_width = 1\n    plug_seperator_distance = 1.5\n\n    silk_pad_clearance = 0.15\n    mount_screw_info = \"ISO 1481-ST 2.2x4.5 C or ISO 7049-ST 2.2x4.5 C (http://www.fasteners.eu/standards/ISO/7049/)\"\n\n    # Connector voltage ratings:\n    # Rated voltage (III/3) 160 V\n    # Rated voltage (III/2) 160 V\n    # Rated voltage (II/2) 250 V\n    # Rated surge voltage (III/3) 2.5 kV\n    # Rated surge voltage (III/2) 2.5 kV\n    # Rated surge voltage (II/2) 2.5 kV\n    # VDE 0110-1/4.97 2.5kV -> 1.5mm clearance\n    min_pad_to_pad_clearance = 1.5\n\n    # Connector voltage ratings:\n    # Rated voltage (III/3) 250 V\n    # Rated voltage (III/2) 320 V\n    # Rated voltage (II/2) 400 V\n    # Rated surge voltage (III/3) 4 kV\n    # Rated surge voltage (III/2) 4 kV\n    # Rated surge voltage (II/2) 4 kV\n    # VDE 0110-1/4.97 4kV -> 3mm clearance\n    HV_min_pad_to_pad_clearance = 3.0\n\nParams = namedtuple(\"Params\",[\n    'series_name',\n    'angled',\n    'flanged',\n    'num_pins',\n    'pin_pitch',\n    'mount_hole',\n    'order_info',\n    'mount_hole_to_pin',\n    'side_to_pin',\n    'back_to_pin',\n    'pin_Sx',\n    'pin_Sy'\n])\n\ndef generate_params(num_pins, series_name, pin_pitch, angled, flanged, order_info, mount_hole=False, mount_hole_to_pin=None,\n            side_to_pin=None, back_to_pin=None, min_pad_to_pad_clearance=seriesParams.min_pad_to_pad_clearance):\n    nominal_pin_Sx = seriesParams.drill + 2 * seriesParams.annular_ring\n    nominal_pin_Sy = seriesParams.drill + 2 * 1.2\n    return Params(\n        series_name=series_name,\n        angled=angled,\n        flanged=flanged,\n        num_pins=num_pins,\n        pin_pitch=pin_pitch,\n        mount_hole=mount_hole,\n        order_info=order_info,\n        mount_hole_to_pin=pin_pitch if mount_hole_to_pin is None else mount_hole_to_pin,\n        side_to_pin=(3*pin_pitch if flanged else pin_pitch+2)/2.0 if side_to_pin is None else side_to_pin,\n        back_to_pin= (8-9.2 if angled else 3-7.25) if back_to_pin is None else back_to_pin,\n        pin_Sx=(nominal_pin_Sx if pin_pitch-nominal_pin_Sx >= min_pad_to_pad_clearance else pin_pitch - min_pad_to_pad_clearance),\n        pin_Sy = nominal_pin_Sy\n    )\n\n\nall_params = {\n    ##################################################################################################################\n    # Pin Pitch 3.50mm\n    ##################################################################################################################\n    'MC_01x02_G_3.5mm' : generate_params( 2, \"MC-G\", 3.5, True, False, OrderedDict([('1844210', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x03_G_3.5mm' : generate_params( 3, \"MC-G\", 3.5, True, False, OrderedDict([('1844223', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x04_G_3.5mm' : generate_params( 4, \"MC-G\", 3.5, True, False, OrderedDict([('1844236', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x05_G_3.5mm' : generate_params( 5, \"MC-G\", 3.5, True, False, OrderedDict([('1844249', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x06_G_3.5mm' : generate_params( 6, \"MC-G\", 3.5, True, False, OrderedDict([('1844252', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x07_G_3.5mm' : generate_params( 7, \"MC-G\", 3.5, True, False, OrderedDict([('1844265', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x08_G_3.5mm' : generate_params( 8, \"MC-G\", 3.5, True, False, OrderedDict([('1844278', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x09_G_3.5mm' : generate_params( 9, \"MC-G\", 3.5, True, False, OrderedDict([('1844281', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x10_G_3.5mm' : generate_params(10, \"MC-G\", 3.5, True, False, OrderedDict([('1844294', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x11_G_3.5mm' : generate_params(11, \"MC-G\", 3.5, True, False, OrderedDict([('1844304', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x12_G_3.5mm' : generate_params(12, \"MC-G\", 3.5, True, False, OrderedDict([('1844317', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x13_G_3.5mm' : generate_params(13, \"MC-G\", 3.5, True, False, OrderedDict([('1844320', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x14_G_3.5mm' : generate_params(14, \"MC-G\", 3.5, True, False, OrderedDict([('1844333', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x15_G_3.5mm' : generate_params(15, \"MC-G\", 3.5, True, False, OrderedDict([('1844346', '8A 160V')]), side_to_pin=2.45),\n    'MC_01x16_G_3.5mm' : generate_params(16, \"MC-G\", 3.5, True, False, OrderedDict([('1844359', '8A 160V')]), side_to_pin=2.45),\n    ###################################################################################################################\n    'MC_01x02_GF_3.5mm' : generate_params( 2, \"MC-GF\", 3.5, True, True, OrderedDict([('1843790', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x03_GF_3.5mm' : generate_params( 3, \"MC-GF\", 3.5, True, True, OrderedDict([('1843800', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x04_GF_3.5mm' : generate_params( 4, \"MC-GF\", 3.5, True, True, OrderedDict([('1843813', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x05_GF_3.5mm' : generate_params( 5, \"MC-GF\", 3.5, True, True, OrderedDict([('1843826', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x06_GF_3.5mm' : generate_params( 6, \"MC-GF\", 3.5, True, True, OrderedDict([('1843839', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x07_GF_3.5mm' : generate_params( 7, \"MC-GF\", 3.5, True, True, OrderedDict([('1843842', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x08_GF_3.5mm' : generate_params( 8, \"MC-GF\", 3.5, True, True, OrderedDict([('1843855', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x09_GF_3.5mm' : generate_params( 9, \"MC-GF\", 3.5, True, True, OrderedDict([('1843868', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x10_GF_3.5mm' : generate_params(10, \"MC-GF\", 3.5, True, True, OrderedDict([('1843871', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x11_GF_3.5mm' : generate_params(11, \"MC-GF\", 3.5, True, True, OrderedDict([('1843884', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x12_GF_3.5mm' : generate_params(12, \"MC-GF\", 3.5, True, True, OrderedDict([('1843897', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x13_GF_3.5mm' : generate_params(13, \"MC-GF\", 3.5, True, True, OrderedDict([('1843907', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x14_GF_3.5mm' : generate_params(14, \"MC-GF\", 3.5, True, True, OrderedDict([('1843910', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x15_GF_3.5mm' : generate_params(15, \"MC-GF\", 3.5, True, True, OrderedDict([('1843923', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MC_01x16_GF_3.5mm' : generate_params(16, \"MC-GF\", 3.5, True, True, OrderedDict([('1843936', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    ###################################################################################################################\n    'MC_01x02_GF_3.5mm_MH' : generate_params( 2, \"MC-GF\", 3.5, True, True, OrderedDict([('1843790', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x03_GF_3.5mm_MH' : generate_params( 3, \"MC-GF\", 3.5, True, True, OrderedDict([('1843800', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x04_GF_3.5mm_MH' : generate_params( 4, \"MC-GF\", 3.5, True, True, OrderedDict([('1843813', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x05_GF_3.5mm_MH' : generate_params( 5, \"MC-GF\", 3.5, True, True, OrderedDict([('1843826', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x06_GF_3.5mm_MH' : generate_params( 6, \"MC-GF\", 3.5, True, True, OrderedDict([('1843839', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x07_GF_3.5mm_MH' : generate_params( 7, \"MC-GF\", 3.5, True, True, OrderedDict([('1843842', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x08_GF_3.5mm_MH' : generate_params( 8, \"MC-GF\", 3.5, True, True, OrderedDict([('1843855', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x09_GF_3.5mm_MH' : generate_params( 9, \"MC-GF\", 3.5, True, True, OrderedDict([('1843868', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x10_GF_3.5mm_MH' : generate_params(10, \"MC-GF\", 3.5, True, True, OrderedDict([('1843871', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x11_GF_3.5mm_MH' : generate_params(11, \"MC-GF\", 3.5, True, True, OrderedDict([('1843884', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x12_GF_3.5mm_MH' : generate_params(12, \"MC-GF\", 3.5, True, True, OrderedDict([('1843897', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x13_GF_3.5mm_MH' : generate_params(13, \"MC-GF\", 3.5, True, True, OrderedDict([('1843907', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x14_GF_3.5mm_MH' : generate_params(14, \"MC-GF\", 3.5, True, True, OrderedDict([('1843910', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x15_GF_3.5mm_MH' : generate_params(15, \"MC-GF\", 3.5, True, True, OrderedDict([('1843923', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MC_01x16_GF_3.5mm_MH' : generate_params(16, \"MC-GF\", 3.5, True, True, OrderedDict([('1843936', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    ###################################################################################################################\n    'MCV_01x02_G_3.5mm' : generate_params( 2, \"MCV-G\", 3.5, False, False, OrderedDict([('1843606', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x03_G_3.5mm' : generate_params( 3, \"MCV-G\", 3.5, False, False, OrderedDict([('1843619', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x04_G_3.5mm' : generate_params( 4, \"MCV-G\", 3.5, False, False, OrderedDict([('1843622', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x05_G_3.5mm' : generate_params( 5, \"MCV-G\", 3.5, False, False, OrderedDict([('1843635', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x06_G_3.5mm' : generate_params( 6, \"MCV-G\", 3.5, False, False, OrderedDict([('1843648', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x07_G_3.5mm' : generate_params( 7, \"MCV-G\", 3.5, False, False, OrderedDict([('1843651', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x08_G_3.5mm' : generate_params( 8, \"MCV-G\", 3.5, False, False, OrderedDict([('1843664', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x09_G_3.5mm' : generate_params( 9, \"MCV-G\", 3.5, False, False, OrderedDict([('1843677', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x10_G_3.5mm' : generate_params(10, \"MCV-G\", 3.5, False, False, OrderedDict([('1843680', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x11_G_3.5mm' : generate_params(11, \"MCV-G\", 3.5, False, False, OrderedDict([('1843693', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x12_G_3.5mm' : generate_params(12, \"MCV-G\", 3.5, False, False, OrderedDict([('1843703', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x13_G_3.5mm' : generate_params(13, \"MCV-G\", 3.5, False, False, OrderedDict([('1843716', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x14_G_3.5mm' : generate_params(14, \"MCV-G\", 3.5, False, False, OrderedDict([('1843729', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x15_G_3.5mm' : generate_params(15, \"MCV-G\", 3.5, False, False, OrderedDict([('1843732', '8A 160V')]), side_to_pin=2.45),\n    'MCV_01x16_G_3.5mm' : generate_params(16, \"MCV-G\", 3.5, False, False, OrderedDict([('1843745', '8A 160V')]), side_to_pin=2.45),\n    ###################################################################################################################\n    'MCV_01x02_GF_3.5mm' : generate_params( 2, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843224', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x03_GF_3.5mm' : generate_params( 3, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843237', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x04_GF_3.5mm' : generate_params( 4, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843240', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x05_GF_3.5mm' : generate_params( 5, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843253', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x06_GF_3.5mm' : generate_params( 6, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843266', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x07_GF_3.5mm' : generate_params( 7, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843279', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x08_GF_3.5mm' : generate_params( 8, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843282', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x09_GF_3.5mm' : generate_params( 9, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843295', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x10_GF_3.5mm' : generate_params(10, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843305', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x11_GF_3.5mm' : generate_params(11, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843318', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x12_GF_3.5mm' : generate_params(12, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843321', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x13_GF_3.5mm' : generate_params(13, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843334', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x14_GF_3.5mm' : generate_params(14, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843347', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x15_GF_3.5mm' : generate_params(15, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843350', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    'MCV_01x16_GF_3.5mm' : generate_params(16, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843363', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3),\n    ###################################################################################################################\n    'MCV_01x02_GF_3.5mm_MH' : generate_params( 2, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843224', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x03_GF_3.5mm_MH' : generate_params( 3, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843237', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x04_GF_3.5mm_MH' : generate_params( 4, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843240', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x05_GF_3.5mm_MH' : generate_params( 5, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843253', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x06_GF_3.5mm_MH' : generate_params( 6, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843266', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x07_GF_3.5mm_MH' : generate_params( 7, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843279', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x08_GF_3.5mm_MH' : generate_params( 8, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843282', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x09_GF_3.5mm_MH' : generate_params( 9, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843295', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x10_GF_3.5mm_MH' : generate_params(10, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843305', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x11_GF_3.5mm_MH' : generate_params(11, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843318', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x12_GF_3.5mm_MH' : generate_params(12, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843321', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x13_GF_3.5mm_MH' : generate_params(13, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843334', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x14_GF_3.5mm_MH' : generate_params(14, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843347', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x15_GF_3.5mm_MH' : generate_params(15, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843350', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    'MCV_01x16_GF_3.5mm_MH' : generate_params(16, \"MCV-GF\", 3.5, False, True, OrderedDict([('1843363', '8A 160V')]), side_to_pin=6.9, mount_hole_to_pin=4.3, mount_hole=True),\n    ##################################################################################################################\n    # Pin Pitch 3.81mm\n    ##################################################################################################################\n    'MC_01x02_G_3.81mm' : generate_params( 2, \"MC-G\", 3.81, True, False, OrderedDict([('1803277', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x03_G_3.81mm' : generate_params( 3, \"MC-G\", 3.81, True, False, OrderedDict([('1803280', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x04_G_3.81mm' : generate_params( 4, \"MC-G\", 3.81, True, False, OrderedDict([('1803293', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x05_G_3.81mm' : generate_params( 5, \"MC-G\", 3.81, True, False, OrderedDict([('1803303', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x06_G_3.81mm' : generate_params( 6, \"MC-G\", 3.81, True, False, OrderedDict([('1803316', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x07_G_3.81mm' : generate_params( 7, \"MC-G\", 3.81, True, False, OrderedDict([('1803329', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x08_G_3.81mm' : generate_params( 8, \"MC-G\", 3.81, True, False, OrderedDict([('1803332', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x09_G_3.81mm' : generate_params( 9, \"MC-G\", 3.81, True, False, OrderedDict([('1803345', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x10_G_3.81mm' : generate_params(10, \"MC-G\", 3.81, True, False, OrderedDict([('1803358', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x11_G_3.81mm' : generate_params(11, \"MC-G\", 3.81, True, False, OrderedDict([('1803361', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x12_G_3.81mm' : generate_params(12, \"MC-G\", 3.81, True, False, OrderedDict([('1803374', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x13_G_3.81mm' : generate_params(13, \"MC-G\", 3.81, True, False, OrderedDict([('1803387', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x14_G_3.81mm' : generate_params(14, \"MC-G\", 3.81, True, False, OrderedDict([('1803390', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x15_G_3.81mm' : generate_params(15, \"MC-G\", 3.81, True, False, OrderedDict([('1803400', '8A 160V')]), side_to_pin=2.6),\n    'MC_01x16_G_3.81mm' : generate_params(16, \"MC-G\", 3.81, True, False, OrderedDict([('1803413', '8A 160V')]), side_to_pin=2.6),\n    ###################################################################################################################\n    'MC_01x02_GF_3.81mm' : generate_params( 2, \"MC-GF\", 3.81, True, True, OrderedDict([('1827868', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x03_GF_3.81mm' : generate_params( 3, \"MC-GF\", 3.81, True, True, OrderedDict([('1827871', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x04_GF_3.81mm' : generate_params( 4, \"MC-GF\", 3.81, True, True, OrderedDict([('1827884', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x05_GF_3.81mm' : generate_params( 5, \"MC-GF\", 3.81, True, True, OrderedDict([('1827897', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x06_GF_3.81mm' : generate_params( 6, \"MC-GF\", 3.81, True, True, OrderedDict([('1827907', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x07_GF_3.81mm' : generate_params( 7, \"MC-GF\", 3.81, True, True, OrderedDict([('1827910', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x08_GF_3.81mm' : generate_params( 8, \"MC-GF\", 3.81, True, True, OrderedDict([('1827923', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x09_GF_3.81mm' : generate_params( 9, \"MC-GF\", 3.81, True, True, OrderedDict([('1827936', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x10_GF_3.81mm' : generate_params(10, \"MC-GF\", 3.81, True, True, OrderedDict([('1827949', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x11_GF_3.81mm' : generate_params(11, \"MC-GF\", 3.81, True, True, OrderedDict([('1827952', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x12_GF_3.81mm' : generate_params(12, \"MC-GF\", 3.81, True, True, OrderedDict([('1827965', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x13_GF_3.81mm' : generate_params(13, \"MC-GF\", 3.81, True, True, OrderedDict([('1827978', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x14_GF_3.81mm' : generate_params(14, \"MC-GF\", 3.81, True, True, OrderedDict([('1827981', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x15_GF_3.81mm' : generate_params(15, \"MC-GF\", 3.81, True, True, OrderedDict([('1827994', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MC_01x16_GF_3.81mm' : generate_params(16, \"MC-GF\", 3.81, True, True, OrderedDict([('1828003', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    ###################################################################################################################\n    'MC_01x02_GF_3.81mm_MH' : generate_params( 2, \"MC-GF\", 3.81, True, True, OrderedDict([('1827868', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x03_GF_3.81mm_MH' : generate_params( 3, \"MC-GF\", 3.81, True, True, OrderedDict([('1827871', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x04_GF_3.81mm_MH' : generate_params( 4, \"MC-GF\", 3.81, True, True, OrderedDict([('1827884', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x05_GF_3.81mm_MH' : generate_params( 5, \"MC-GF\", 3.81, True, True, OrderedDict([('1827897', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x06_GF_3.81mm_MH' : generate_params( 6, \"MC-GF\", 3.81, True, True, OrderedDict([('1827907', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x07_GF_3.81mm_MH' : generate_params( 7, \"MC-GF\", 3.81, True, True, OrderedDict([('1827910', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x08_GF_3.81mm_MH' : generate_params( 8, \"MC-GF\", 3.81, True, True, OrderedDict([('1827923', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x09_GF_3.81mm_MH' : generate_params( 9, \"MC-GF\", 3.81, True, True, OrderedDict([('1827936', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x10_GF_3.81mm_MH' : generate_params(10, \"MC-GF\", 3.81, True, True, OrderedDict([('1827949', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x11_GF_3.81mm_MH' : generate_params(11, \"MC-GF\", 3.81, True, True, OrderedDict([('1827952', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x12_GF_3.81mm_MH' : generate_params(12, \"MC-GF\", 3.81, True, True, OrderedDict([('1827965', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x13_GF_3.81mm_MH' : generate_params(13, \"MC-GF\", 3.81, True, True, OrderedDict([('1827978', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x14_GF_3.81mm_MH' : generate_params(14, \"MC-GF\", 3.81, True, True, OrderedDict([('1827981', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x15_GF_3.81mm_MH' : generate_params(15, \"MC-GF\", 3.81, True, True, OrderedDict([('1827994', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MC_01x16_GF_3.81mm_MH' : generate_params(16, \"MC-GF\", 3.81, True, True, OrderedDict([('1828003', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    ###################################################################################################################\n    'MCV_01x02_G_3.81mm' : generate_params( 2, \"MCV-G\", 3.81, False, False, OrderedDict([('1803426', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x03_G_3.81mm' : generate_params( 3, \"MCV-G\", 3.81, False, False, OrderedDict([('1803439', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x04_G_3.81mm' : generate_params( 4, \"MCV-G\", 3.81, False, False, OrderedDict([('1803442', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x05_G_3.81mm' : generate_params( 5, \"MCV-G\", 3.81, False, False, OrderedDict([('1803455', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x06_G_3.81mm' : generate_params( 6, \"MCV-G\", 3.81, False, False, OrderedDict([('1803468', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x07_G_3.81mm' : generate_params( 7, \"MCV-G\", 3.81, False, False, OrderedDict([('1803471', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x08_G_3.81mm' : generate_params( 8, \"MCV-G\", 3.81, False, False, OrderedDict([('1803484', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x09_G_3.81mm' : generate_params( 9, \"MCV-G\", 3.81, False, False, OrderedDict([('1803497', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x10_G_3.81mm' : generate_params(10, \"MCV-G\", 3.81, False, False, OrderedDict([('1803507', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x11_G_3.81mm' : generate_params(11, \"MCV-G\", 3.81, False, False, OrderedDict([('1803510', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x12_G_3.81mm' : generate_params(12, \"MCV-G\", 3.81, False, False, OrderedDict([('1803523', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x13_G_3.81mm' : generate_params(13, \"MCV-G\", 3.81, False, False, OrderedDict([('1803536', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x14_G_3.81mm' : generate_params(14, \"MCV-G\", 3.81, False, False, OrderedDict([('1803549', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x15_G_3.81mm' : generate_params(15, \"MCV-G\", 3.81, False, False, OrderedDict([('1803552', '8A 160V')]), side_to_pin=2.6),\n    'MCV_01x16_G_3.81mm' : generate_params(16, \"MCV-G\", 3.81, False, False, OrderedDict([('1803565', '8A 160V')]), side_to_pin=2.6),\n    ###################################################################################################################\n    'MCV_01x02_GF_3.81mm' : generate_params( 2, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830596', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x03_GF_3.81mm' : generate_params( 3, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830606', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x04_GF_3.81mm' : generate_params( 4, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830619', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x05_GF_3.81mm' : generate_params( 5, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830622', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x06_GF_3.81mm' : generate_params( 6, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830635', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x07_GF_3.81mm' : generate_params( 7, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830648', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x08_GF_3.81mm' : generate_params( 8, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830651', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x09_GF_3.81mm' : generate_params( 9, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830664', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x10_GF_3.81mm' : generate_params(10, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830677', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x11_GF_3.81mm' : generate_params(11, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830680', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x12_GF_3.81mm' : generate_params(12, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830693', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x13_GF_3.81mm' : generate_params(13, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830703', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x14_GF_3.81mm' : generate_params(14, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830716', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x15_GF_3.81mm' : generate_params(15, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830729', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    'MCV_01x16_GF_3.81mm' : generate_params(16, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830732', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5),\n    ###################################################################################################################\n    'MCV_01x02_GF_3.81mm_MH' : generate_params( 2, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830596', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x03_GF_3.81mm_MH' : generate_params( 3, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830606', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x04_GF_3.81mm_MH' : generate_params( 4, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830619', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x05_GF_3.81mm_MH' : generate_params( 5, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830622', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x06_GF_3.81mm_MH' : generate_params( 6, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830635', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x07_GF_3.81mm_MH' : generate_params( 7, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830648', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x08_GF_3.81mm_MH' : generate_params( 8, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830651', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x09_GF_3.81mm_MH' : generate_params( 9, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830664', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x10_GF_3.81mm_MH' : generate_params(10, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830677', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x11_GF_3.81mm_MH' : generate_params(11, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830680', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x12_GF_3.81mm_MH' : generate_params(12, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830693', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x13_GF_3.81mm_MH' : generate_params(13, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830703', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x14_GF_3.81mm_MH' : generate_params(14, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830716', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x15_GF_3.81mm_MH' : generate_params(15, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830729', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    'MCV_01x16_GF_3.81mm_MH' : generate_params(16, \"MCV-GF\", 3.81, False, True, OrderedDict([('1830732', '8A 160V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True),\n    ##################################################################################################################\n    # Pin Pitch 5.08mm\n    ##################################################################################################################\n    'MC_01x02_G_5.08mm' : generate_params( 2, \"MC-G\", 5.08, True, False, OrderedDict([('1836189', '8A 320V')]), side_to_pin=2.54, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x03_G_5.08mm' : generate_params( 3, \"MC-G\", 5.08, True, False, OrderedDict([('1836192', '8A 320V')]), side_to_pin=2.54, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x04_G_5.08mm' : generate_params( 4, \"MC-G\", 5.08, True, False, OrderedDict([('1836202', '8A 320V')]), side_to_pin=2.54, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x05_G_5.08mm' : generate_params( 5, \"MC-G\", 5.08, True, False, OrderedDict([('1836215', '8A 320V')]), side_to_pin=2.54, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x06_G_5.08mm' : generate_params( 6, \"MC-G\", 5.08, True, False, OrderedDict([('1836228', '8A 320V')]), side_to_pin=2.54, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x07_G_5.08mm' : generate_params( 7, \"MC-G\", 5.08, True, False, OrderedDict([('1836231', '8A 320V')]), side_to_pin=2.54, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x08_G_5.08mm' : generate_params( 8, \"MC-G\", 5.08, True, False, OrderedDict([('1836244', '8A 320V')]), side_to_pin=2.54, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x09_G_5.08mm' : generate_params( 9, \"MC-G\", 5.08, True, False, OrderedDict([('1836257', '8A 320V')]), side_to_pin=2.54, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x10_G_5.08mm' : generate_params(10, \"MC-G\", 5.08, True, False, OrderedDict([('1836260', '8A 320V')]), side_to_pin=2.54, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x11_G_5.08mm' : generate_params(11, \"MC-G\", 5.08, True, False, OrderedDict([('1836273', '8A 320V')]), side_to_pin=2.54, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x12_G_5.08mm' : generate_params(12, \"MC-G\", 5.08, True, False, OrderedDict([('1836286', '8A 320V')]), side_to_pin=2.54, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    ###################################################################################################################\n    'MC_01x02_GF_5.08mm' : generate_params( 2, \"MC-GF\", 5.08, True, True, OrderedDict([('1847466', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x03_GF_5.08mm' : generate_params( 3, \"MC-GF\", 5.08, True, True, OrderedDict([('1847479', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x04_GF_5.08mm' : generate_params( 4, \"MC-GF\", 5.08, True, True, OrderedDict([('1847482', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x05_GF_5.08mm' : generate_params( 5, \"MC-GF\", 5.08, True, True, OrderedDict([('1847495', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x06_GF_5.08mm' : generate_params( 6, \"MC-GF\", 5.08, True, True, OrderedDict([('1847505', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x07_GF_5.08mm' : generate_params( 7, \"MC-GF\", 5.08, True, True, OrderedDict([('1847518', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x08_GF_5.08mm' : generate_params( 8, \"MC-GF\", 5.08, True, True, OrderedDict([('1847521', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x09_GF_5.08mm' : generate_params( 9, \"MC-GF\", 5.08, True, True, OrderedDict([('1847534', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x10_GF_5.08mm' : generate_params(10, \"MC-GF\", 5.08, True, True, OrderedDict([('1847547', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x11_GF_5.08mm' : generate_params(11, \"MC-GF\", 5.08, True, True, OrderedDict([('1847550', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x12_GF_5.08mm' : generate_params(12, \"MC-GF\", 5.08, True, True, OrderedDict([('1847563', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    ###################################################################################################################\n    'MC_01x02_GF_5.08mm_MH' : generate_params( 2, \"MC-GF\", 5.08, True, True, OrderedDict([('1847466', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x03_GF_5.08mm_MH' : generate_params( 3, \"MC-GF\", 5.08, True, True, OrderedDict([('1847479', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x04_GF_5.08mm_MH' : generate_params( 4, \"MC-GF\", 5.08, True, True, OrderedDict([('1847482', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x05_GF_5.08mm_MH' : generate_params( 5, \"MC-GF\", 5.08, True, True, OrderedDict([('1847495', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x06_GF_5.08mm_MH' : generate_params( 6, \"MC-GF\", 5.08, True, True, OrderedDict([('1847505', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x07_GF_5.08mm_MH' : generate_params( 7, \"MC-GF\", 5.08, True, True, OrderedDict([('1847518', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x08_GF_5.08mm_MH' : generate_params( 8, \"MC-GF\", 5.08, True, True, OrderedDict([('1847521', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x09_GF_5.08mm_MH' : generate_params( 9, \"MC-GF\", 5.08, True, True, OrderedDict([('1847534', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x10_GF_5.08mm_MH' : generate_params(10, \"MC-GF\", 5.08, True, True, OrderedDict([('1847547', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x11_GF_5.08mm_MH' : generate_params(11, \"MC-GF\", 5.08, True, True, OrderedDict([('1847550', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MC_01x12_GF_5.08mm_MH' : generate_params(12, \"MC-GF\", 5.08, True, True, OrderedDict([('1847563', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    ###################################################################################################################\n    'MCV_01x02_G_5.08mm' : generate_params( 2, \"MCV-G\", 5.08, False, False, OrderedDict([('1836299', '8A 320V')]), side_to_pin=2.54, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x03_G_5.08mm' : generate_params( 3, \"MCV-G\", 5.08, False, False, OrderedDict([('1836309', '8A 320V')]), side_to_pin=2.54, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x04_G_5.08mm' : generate_params( 4, \"MCV-G\", 5.08, False, False, OrderedDict([('1836312', '8A 320V')]), side_to_pin=2.54, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x05_G_5.08mm' : generate_params( 5, \"MCV-G\", 5.08, False, False, OrderedDict([('1836325', '8A 320V')]), side_to_pin=2.54, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x06_G_5.08mm' : generate_params( 6, \"MCV-G\", 5.08, False, False, OrderedDict([('1836338', '8A 320V')]), side_to_pin=2.54, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x07_G_5.08mm' : generate_params( 7, \"MCV-G\", 5.08, False, False, OrderedDict([('1836341', '8A 320V')]), side_to_pin=2.54, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x08_G_5.08mm' : generate_params( 8, \"MCV-G\", 5.08, False, False, OrderedDict([('1836354', '8A 320V')]), side_to_pin=2.54, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x09_G_5.08mm' : generate_params( 9, \"MCV-G\", 5.08, False, False, OrderedDict([('1836367', '8A 320V')]), side_to_pin=2.54, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x10_G_5.08mm' : generate_params(10, \"MCV-G\", 5.08, False, False, OrderedDict([('1836370', '8A 320V')]), side_to_pin=2.54, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x11_G_5.08mm' : generate_params(11, \"MCV-G\", 5.08, False, False, OrderedDict([('1836383', '8A 320V')]), side_to_pin=2.54, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x12_G_5.08mm' : generate_params(12, \"MCV-G\", 5.08, False, False, OrderedDict([('1836396', '8A 320V')]), side_to_pin=2.54, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    ###################################################################################################################\n    'MCV_01x02_GF_5.08mm' : generate_params( 2, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847615', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x03_GF_5.08mm' : generate_params( 3, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847628', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x04_GF_5.08mm' : generate_params( 4, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847631', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x05_GF_5.08mm' : generate_params( 5, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847644', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x06_GF_5.08mm' : generate_params( 6, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847657', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x07_GF_5.08mm' : generate_params( 7, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847660', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x08_GF_5.08mm' : generate_params( 8, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847673', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x09_GF_5.08mm' : generate_params( 9, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847686', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x10_GF_5.08mm' : generate_params(10, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847699', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x11_GF_5.08mm' : generate_params(11, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847709', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x12_GF_5.08mm' : generate_params(12, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847712', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    ###################################################################################################################\n    'MCV_01x02_GF_5.08mm_MH' : generate_params( 2, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847615', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x03_GF_5.08mm_MH' : generate_params( 3, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847628', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x04_GF_5.08mm_MH' : generate_params( 4, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847631', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x05_GF_5.08mm_MH' : generate_params( 5, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847644', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x06_GF_5.08mm_MH' : generate_params( 6, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847657', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x07_GF_5.08mm_MH' : generate_params( 7, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847660', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x08_GF_5.08mm_MH' : generate_params( 8, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847673', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x09_GF_5.08mm_MH' : generate_params( 9, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847686', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x10_GF_5.08mm_MH' : generate_params(10, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847699', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x11_GF_5.08mm_MH' : generate_params(11, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847709', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance),\n    'MCV_01x12_GF_5.08mm_MH' : generate_params(12, \"MCV-GF\", 5.08, False, True, OrderedDict([('1847712', '8A 320V')]), side_to_pin=7.1, mount_hole_to_pin=4.5, mount_hole=True, back_to_pin=2.9-7.25, min_pad_to_pad_clearance=seriesParams.HV_min_pad_to_pad_clearance)\n}\n\n\n#lock_cutout=\nCalcDim=namedtuple(\"CalcDim\",[\n    \"length\", \"width\", \"left_to_pin\",\n    \"mount_hole_left\", \"mount_hole_right\", \"flange_width\",\n    \"plug_front\", \"plug_back\"\n])\ndef dimensions(params):\n    mount_hole_y = 0.9 if params.angled else 0.0\n    width = 9.2 if params.angled else 7.25\n    return CalcDim(\n        length = (params.num_pins-1)*params.pin_pitch + 2*params.side_to_pin\n        ,width = width\n        ,left_to_pin = -params.side_to_pin\n        ,mount_hole_left = [-params.mount_hole_to_pin,mount_hole_y]\n        ,mount_hole_right = [(params.num_pins-1)*params.pin_pitch+params.mount_hole_to_pin,mount_hole_y]\n        ,flange_width = 9.2 if params.angled else 6.0\n        ,plug_front = width + params.back_to_pin -0.75\n        ,plug_back = params.back_to_pin+0.6+0.25\n    )\n\ndef generate_description(params, mpn):\n    d = \"Generic Phoenix Contact connector footprint for: \" + mpn + \"; number of pins: \" + (\"%02d\" %params.num_pins) + \"; pin pitch: \" + (('%.2f' % params.pin_pitch))\\\n        +\"mm\" + ('; Angled' if params.angled else '; Vertical')\\\n        + ('; threaded flange' + ('; footprint includes mount hole for mounting screw: ' + seriesParams.mount_screw_info if params.mount_hole else '') if params.flanged else '')\n    for order_num, info in params.order_info.items():\n        d += \" || order number: \" + order_num + \" \" + info\n    return d\n"
  },
  {
    "path": "scripts/Connector/Connector_PhoenixContact/mstb.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nfrom helpers import *\nimport re\nimport fnmatch\nimport argparse\nimport yaml\n\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load KicadModTree path\n#add KicadModTree to searchpath using export PYTHONPATH=\"${PYTHONPATH}<absolute path>/kicad-footprint-generator/\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\n\nfrom mstb_params import seriesParams, dimensions, generate_description, all_params\n\nseries = ['MSTB', '2,5']\n\ndef generate_one_footprint(model, params, configuration):\n\n    subseries, connector_style = params.series_name.split('-')\n    pitch_mpn = ''\n    if params.pin_pitch == 5.08:\n        pitch_mpn = '-5,08'\n    elif params.pin_pitch == 7.62:\n        pitch_mpn = '-7,62'\n    lib_series = 'GMSTB' if params.pin_pitch >= 7.5 else 'MSTB'\n    lib_name = configuration['lib_name_format_str'].format(series=lib_series,\n        style=series[1], pitch=params.pin_pitch, suffix='')\n    mpn = configuration['mpn_format_string'].format(subseries=subseries, style = connector_style,\n        rating=series[1], num_pins=params.num_pins, pitch=pitch_mpn)\n    footprint_name = configuration['fp_name_format_string'].format(man = configuration['manufacturer'], series = series[0], mpn = mpn, num_rows = 1,\n        num_pins = params.num_pins, mounting_pad = \"\", pitch = params.pin_pitch,\n        orientation = configuration['orientation_str'][1] if params.angled else configuration['orientation_str'][0],\n        flanged = configuration['flanged_str'][1] if params.flanged else configuration['flanged_str'][0],\n        mount_hole = configuration['mount_hole_str'][1] if params.mount_hole else configuration['mount_hole_str'][0])\n\n    length, width, upper_to_pin, left_to_pin, mount_hole_left, mount_hole_right, inner_len = dimensions(params)\n\n    body_top_left=[left_to_pin,upper_to_pin]\n    body_bottom_right=v_add(body_top_left,[length,width])\n\n    body_edge={\n        'left': body_top_left[0],\n        'top': body_top_left[1],\n        'right': body_bottom_right[0],\n        'bottom': body_bottom_right[1],\n    }\n\n    silk_top_left=v_offset(body_top_left, configuration['silk_fab_offset'])\n    silk_bottom_right=v_offset(body_bottom_right, configuration['silk_fab_offset'])\n\n    center_x = (params.num_pins-1)/2.0*params.pin_pitch\n    kicad_mod = Footprint(footprint_name)\n\n    mpn = configuration['mpn_format_string_description'].format(subseries=subseries, style = connector_style,\n        rating=series[1], num_pins=params.num_pins, pitch=pitch_mpn)\n    kicad_mod.setDescription(generate_description(params, mpn))\n    kicad_mod.setTags(configuration['keywords_format_string'].format(mpn=mpn, param_name=model,\n        order_info = ', '.join(params.order_info)))\n\n\n    ################################################# Pads #################################################\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[0, 0],\n        x_spacing=params.pin_pitch, pincount=params.num_pins,\n        size=[params.pin_Sx, params.pin_Sy], drill=seriesParams.drill,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=configuration['pin_layers'],\n        **optional_pad_params))\n\n    if params.mount_hole:\n        kicad_mod.append(Pad(number='\"\"', type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n                            at=mount_hole_left, size=[seriesParams.mount_drill, seriesParams.mount_drill], \\\n                            drill=seriesParams.mount_drill, layers=configuration['mount_hole_layers']))\n        kicad_mod.append(Pad(number='\"\"', type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n                            at=mount_hole_right, size=[seriesParams.mount_drill, seriesParams.mount_drill], \\\n                            drill=seriesParams.mount_drill, layers=configuration['mount_hole_layers']))\n    #add an outline around the pins\n\n    ################################################# Silk and Fab #################################################\n    kicad_mod.append(RectLine(start=silk_top_left, end=silk_bottom_right, layer='F.SilkS', width=configuration['silk_line_width']))\n    if configuration['with_fab_layer']:\n        kicad_mod.append(RectLine(start=body_top_left, end=body_bottom_right, layer='F.Fab', width=configuration['fab_line_width']))\n    if params.angled:\n        lock_poly=[\n            {'x':-1, 'y':0},\n            {'x':1, 'y':0},\n            {'x':1.5/2, 'y':-1.5},\n            {'x':-1.5/2, 'y':-1.5},\n            {'x':-1, 'y':0}\n        ]\n        lock_poly_fab=[\n            {'x':-1, 'y':-configuration['silk_fab_offset']},\n            {'x':1, 'y':-configuration['silk_fab_offset']},\n            {'x':1.5/2, 'y':-1.5},\n            {'x':-1.5/2, 'y':-1.5},\n            {'x':-1, 'y':-configuration['silk_fab_offset']}\n        ]\n        kicad_mod.append(RectLine(start=[silk_top_left[0],silk_bottom_right[1]-1.5], end=[silk_bottom_right[0], silk_bottom_right[1]-1.5-1.8], layer='F.SilkS', width=configuration['silk_line_width']))\n        if configuration['inner_details_on_fab']:\n            kicad_mod.append(RectLine(start=[body_top_left[0],silk_bottom_right[1]-1.5], end=[body_bottom_right[0], silk_bottom_right[1]-1.5-1.8],\n                layer='F.Fab', width=configuration['fab_line_width']))\n        if params.flanged:\n            lock_translation = Translation(mount_hole_left[0], silk_bottom_right[1])\n            lock_translation.append(PolygoneLine(polygone=lock_poly, layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['inner_details_on_fab']:\n                lock_translation.append(PolygoneLine(polygone=lock_poly_fab, layer='F.Fab', width=configuration['fab_line_width']))\n            kicad_mod.append(lock_translation)\n            lock_translation = Translation(mount_hole_right[0], silk_bottom_right[1])\n            lock_translation.append(PolygoneLine(polygone=lock_poly, layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['inner_details_on_fab']:\n                lock_translation.append(PolygoneLine(polygone=lock_poly_fab, layer='F.Fab', width=configuration['fab_line_width']))\n            kicad_mod.append(lock_translation)\n\n        for i in range(params.num_pins):\n            lock_translation = Translation(i*params.pin_pitch, silk_bottom_right[1])\n            lock_translation.append(PolygoneLine(polygone=lock_poly, layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['inner_details_on_fab']:\n                lock_translation.append(PolygoneLine(polygone=lock_poly_fab, layer='F.Fab', width=configuration['fab_line_width']))\n            kicad_mod.append(lock_translation)\n    else:\n        inner_width = 5.3 #measured\n\n        pi1 = [body_top_left[0]+(length-inner_len)/2.0, body_top_left[1]+1.7] # 1.7mm measured\n        top_thickness = pi1[1]-silk_top_left[1]\n        pi2 = [body_bottom_right[0]-(length-inner_len)/2.0, pi1[1]+inner_width]\n        #kicad_mod.append(RectLine(start=pi1, end=pi2, layer='F.SilkS'))\n\n        first_center = params.pin_pitch/2.0\n        line_len = params.pin_pitch-2\n        outher_line_len = (-left_to_pin-1 + mount_hole_left[0]) if params.flanged else (-left_to_pin-1)\n        kicad_mod.append(Line(start=[silk_top_left[0], pi1[1]-1], end=[silk_top_left[0]+outher_line_len, pi1[1]-1], layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Line(start=[silk_bottom_right[0], pi1[1]-1], end=[silk_bottom_right[0]-outher_line_len, pi1[1]-1], layer='F.SilkS', width=configuration['silk_line_width']))\n        if configuration['inner_details_on_fab']:\n            kicad_mod.append(Line(start=[body_top_left[0], pi1[1]-1], end=[body_top_left[0]+outher_line_len, pi1[1]-1], layer='F.Fab', width=configuration['fab_line_width']))\n            kicad_mod.append(Line(start=[body_bottom_right[0], pi1[1]-1], end=[body_bottom_right[0]-outher_line_len, pi1[1]-1], layer='F.Fab', width=configuration['fab_line_width']))\n\n        for i in range(params.num_pins -1):\n            chamfer_edge = Translation(i*params.pin_pitch, pi1[1]-1)\n            chamfer_edge.append(Line(start=[first_center-line_len/2.0, 0], end=[first_center+line_len/2.0, 0], layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['inner_details_on_fab']:\n                chamfer_edge.append(Line(start=[first_center-line_len/2.0, 0], end=[first_center+line_len/2.0, 0], layer='F.Fab', width=configuration['fab_line_width']))\n            kicad_mod.append(chamfer_edge)\n\n        flanged_line_left = (mount_hole_left[0]+1)\n        lock_rect_silk={'start':[-1,0], 'end':[1,-top_thickness], 'layer':'F.SilkS', 'width':configuration['silk_line_width']}\n        lock_rect_fab={'start':[-1,0], 'end':[1,-top_thickness+configuration['silk_fab_offset']], 'layer':'F.Fab', 'width':configuration['fab_line_width']}\n        if params.flanged:\n            lock_translation = Translation(mount_hole_left[0], pi1[1])\n            lock_translation.append(RectLine(**lock_rect_silk))\n            if configuration['inner_details_on_fab']:\n                lock_translation.append(RectLine(**lock_rect_fab))\n            kicad_mod.append(lock_translation)\n            lock_translation = Translation(mount_hole_right[0], pi1[1])\n            lock_translation.append(RectLine(**lock_rect_silk))\n            if configuration['inner_details_on_fab']:\n                lock_translation.append(RectLine(**lock_rect_fab))\n            kicad_mod.append(lock_translation)\n\n            chamfer_edge = Translation(0, pi1[1]-1)\n            chamfer_edge.append(Line(start=[flanged_line_left, 0], end=[-1, 0], layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['inner_details_on_fab']:\n                chamfer_edge.append(Line(start=[flanged_line_left, 0], end=[-1, 0], layer='F.Fab', width=configuration['fab_line_width']))\n            kicad_mod.append(chamfer_edge)\n            chamfer_edge = Translation((params.num_pins-1)*params.pin_pitch+params.mount_hole_to_pin, pi1[1]-1)\n            chamfer_edge.append(Line(start=[flanged_line_left, 0], end=[-1, 0], layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['inner_details_on_fab']:\n                chamfer_edge.append(Line(start=[flanged_line_left, 0], end=[-1, 0], layer='F.Fab', width=configuration['fab_line_width']))\n            kicad_mod.append(chamfer_edge)\n\n\n        for i in range(params.num_pins):\n            lock_translation = Translation(i*params.pin_pitch, pi1[1])\n            lock_translation.append(RectLine(**lock_rect_silk))\n            if configuration['inner_details_on_fab']:\n                lock_translation.append(RectLine(**lock_rect_fab))\n            kicad_mod.append(lock_translation)\n\n        if params.flanged:\n            kicad_mod.append(Circle(center=mount_hole_left, radius=1.9, layer='F.SilkS', width=configuration['silk_line_width']))\n            kicad_mod.append(Circle(center=mount_hole_right, radius=1.9, layer='F.SilkS', width=configuration['silk_line_width']))\n            if not params.mount_hole:\n                kicad_mod.append(Circle(center=mount_hole_left, radius=1, layer='F.SilkS', width=configuration['silk_line_width']))\n                kicad_mod.append(Circle(center=mount_hole_right, radius=1, layer='F.SilkS', width=configuration['silk_line_width']))\n\n            if configuration['inner_details_on_fab']:\n                kicad_mod.append(Circle(center=mount_hole_left, radius=1.9, layer='F.Fab', width=configuration['fab_line_width']))\n                kicad_mod.append(Circle(center=mount_hole_right, radius=1.9, layer='F.Fab', width=configuration['fab_line_width']))\n                kicad_mod.append(Circle(center=mount_hole_left, radius=1, layer='F.Fab', width=configuration['fab_line_width']))\n                kicad_mod.append(Circle(center=mount_hole_right, radius=1, layer='F.Fab', width=configuration['fab_line_width']))\n\n        angle = -100.5\n        arc_width = 4.0\n        for i in range(params.num_pins):\n            plug_arc = Translation(i*params.pin_pitch,0)\n            plug_arc.append(Arc(start=[-arc_width/2.0,pi2[1]], center=[0,0.55], angle=angle, layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['inner_details_on_fab']:\n                plug_arc.append(Arc(start=[-arc_width/2.0,pi2[1]], center=[0,0.55], angle=angle, layer='F.Fab', width=configuration['fab_line_width']))\n            kicad_mod.append(plug_arc)\n\n        for i in range(params.num_pins-1):\n            lower_line = Translation(i*params.pin_pitch,pi2[1])\n            lower_line.append(Line(start=[arc_width/2.0, 0], end=[params.pin_pitch-arc_width/2.0, 0], layer='F.SilkS', width=configuration['silk_line_width']))\n            if configuration['inner_details_on_fab']:\n                lower_line.append(Line(start=[arc_width/2.0, 0], end=[params.pin_pitch-arc_width/2.0, 0], layer='F.Fab', width=configuration['fab_line_width']))\n            kicad_mod.append(lower_line)\n\n        arc_to_side = pi1[0]+arc_width/2.0\n        poly=[\n            {'x':pi1[0]-arc_to_side, 'y':pi2[1]},\n            {'x':pi1[0], 'y':pi2[1]},\n            {'x':pi1[0], 'y':pi1[1]},\n            {'x':pi2[0], 'y':pi1[1]},\n            {'x':pi2[0], 'y':pi2[1]},\n            {'x':pi2[0]+arc_to_side, 'y':pi2[1]}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly))\n        if configuration['inner_details_on_fab']:\n            kicad_mod.append(PolygoneLine(polygone=poly, layer='F.Fab', width=configuration['fab_line_width']))\n\n\n    if params.mount_hole:\n        kicad_mod.append(Circle(center=mount_hole_left, radius=seriesParams.mount_screw_head_r+configuration['silk_fab_offset'], layer='B.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(Circle(center=mount_hole_right, radius=seriesParams.mount_screw_head_r+configuration['silk_fab_offset'], layer='B.SilkS', width=configuration['silk_line_width']))\n\n        kicad_mod.append(Circle(center=mount_hole_right, radius=seriesParams.mount_screw_head_r, layer='B.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(Circle(center=mount_hole_left, radius=seriesParams.mount_screw_head_r, layer='B.Fab', width=configuration['fab_line_width']))\n\n    ################################################## Courtyard ##################################################\n    #if params.angled:\n        #p1=[p1[0],-seriesParams.pin_Sy/2]\n    crtyd_top_left=v_offset(body_top_left, configuration['courtyard_offset']['connector'])\n    crtyd_bottom_right=v_offset(body_bottom_right, configuration['courtyard_offset']['connector'])\n    kicad_mod.append(RectLine(start=round_crty_point(crtyd_top_left, configuration['courtyard_grid']), end=round_crty_point(crtyd_bottom_right, configuration['courtyard_grid']), layer='F.CrtYd'))\n\n    if params.mount_hole and configuration['courtyard_for_mountscrews']:\n        kicad_mod.append(Circle(center=mount_hole_right, radius=seriesParams.mount_screw_head_r+configuration['courtyard_offset']['connector'], layer='B.CrtYd', width=configuration['courtyard_line_width']))\n        kicad_mod.append(Circle(center=mount_hole_left, radius=seriesParams.mount_screw_head_r+configuration['courtyard_offset']['connector'], layer='B.CrtYd', width=configuration['courtyard_line_width']))\n\n    ################################################# Text Fields #################################################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':crtyd_top_left[1], 'bottom':crtyd_bottom_right[1]}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ################################################# Pin 1 Marker #################################################\n    if not params.angled:\n        kicad_mod.append(PolygoneLine(polygone=create_pin1_marker_triangle(silk_top_left[1]-0.2),\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        if configuration['with_fab_layer']:\n            kicad_mod.append(PolygoneLine(\n                polygone=create_pin1_marker_triangle(bottom_y = -params.pin_Sy/2- 0.75,\n                    dimensions = [1, 1], with_top_line = True),\n                layer='F.Fab', width=configuration['fab_line_width']))\n    else:\n        y_bottom_silk_marker = (silk_top_left[1] if silk_top_left[1] < -params.pin_Sy/2 else -params.pin_Sy/2) - 0.2\n        kicad_mod.append(PolygoneLine(polygone=create_pin1_marker_triangle(y_bottom_silk_marker),\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        if configuration['with_fab_layer']:\n            kicad_mod.append(PolygoneLine(\n                polygone=create_pin1_marker_triangle(bottom_y = -0.5,\n                    dimensions = [1.9, -body_top_left[1]-0.5], with_top_line = False),\n                layer='F.Fab', width=configuration['fab_line_width']))\n\n    #################################################### 3d file ###################################################\n    p3dname = '{prefix:s}{lib_name:s}.3dshapes/{fp_name}.wrl'.format(prefix = configuration.get('3d_model_prefix', '${KISYS3DMOD}/'), lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=p3dname,\n                           at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n\n    file_handler = KicadFileHandler(kicad_mod)\n    out_dir = '{:s}.pretty/'.format(lib_name)\n    if not os.path.exists(out_dir):\n        os.makedirs(out_dir)\n    file_handler.writeFile('{:s}.pretty/{:s}.kicad_mod'.format(lib_name, footprint_name))\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='config_phoenix_KLCv3.0.yaml')\n    parser.add_argument('--model_filter', type=str, nargs='?', help='define a filter for what should be generated.', default=\"*\")\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    model_filter_regobj=re.compile(fnmatch.translate(args.model_filter))\n    for model, params in all_params.items():\n        if model_filter_regobj.match(model):\n            generate_one_footprint(model, params, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_PhoenixContact/mstb_params.py",
    "content": "from collections import namedtuple\nfrom collections import OrderedDict\n\nclass seriesParams():\n    drill = 1.4\n    annular_ring = 0.35 # overwritten by minimum pad to pad clearance.\n    mount_drill = 2.4\n    mount_screw_head_r = 2.1\n    mount_screw_info = \"ISO 1481-ST 2.2x6.5 C or ISO 7049-ST 2.2x6.5 C (http://www.fasteners.eu/standards/ISO/7049/)\"\n\n    # Connector voltage ratings:\n    # Rated voltage (III/3) 250 V\n    # Rated voltage (III/2) 320 V\n    # Rated voltage (II/2) 400 V\n    # Rated surge voltage (III/3) 4 kV\n    # Rated surge voltage (III/2) 4 kV\n    # Rated surge voltage (II/2) 4 kV\n    # VDE 0110-1/4.97 4kV -> 3mm clearance\n    MSTB_min_pad_to_pad_clearance = 3.0\n\n    #Rated surge voltage (III/3) 6 kV\n    #Rated surge voltage (III/2) 6 kV\n    #Rated surge voltage (II/2) 6 kV\n    #Rated voltage (III/3) 400 V\n    #Rated voltage (III/2) 630 V\n    #Rated voltage (II/2) 630 V\n    # VDE 0110-1/4.97 6kV -> 5.5mm\n    GMSTB_min_pad_to_pad_clearance = 5.5\n\nParams = namedtuple(\"Params\",[\n    'series_name',\n    'angled',\n    'flanged',\n    'num_pins',\n    'pin_pitch',\n    'mount_hole',\n    'order_info',\n    'mount_hole_to_pin',\n    'side_to_pin',\n    'pin_Sx',\n    'pin_Sy'\n])\n\ndef generate_params(num_pins, series_name, pin_pitch, angled, flanged, order_info, mount_hole=False, mount_hole_to_pin=None,\n        side_to_pin=None, min_pad_to_pad_clearance=seriesParams.MSTB_min_pad_to_pad_clearance):\n    nominal_pin_Sx = seriesParams.drill + 2 * seriesParams.annular_ring\n    nominal_pin_Sy = seriesParams.drill + 2 * 1.1\n    return Params(\n        series_name=series_name,\n        angled=angled,\n        flanged=flanged,\n        num_pins=num_pins,\n        pin_pitch=pin_pitch,\n        mount_hole=mount_hole,\n        order_info=order_info,\n        mount_hole_to_pin=pin_pitch if mount_hole_to_pin is None else mount_hole_to_pin,\n        side_to_pin=(3*pin_pitch if flanged else pin_pitch+2)/2.0 if side_to_pin is None else side_to_pin,\n        pin_Sx= nominal_pin_Sx if (pin_pitch - nominal_pin_Sx) >= min_pad_to_pad_clearance else (pin_pitch - min_pad_to_pad_clearance),\n        pin_Sy = nominal_pin_Sy\n    )\n\n\nall_params = {\n    ##################################################################################################################\n    # Pin Pitch 5.00mm\n    ##################################################################################################################\n    'MSTBA_01x02_G_5.00mm' : generate_params( 2, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757475', '12A'), ('1923759', '16A (HC)')])),\n    'MSTBA_01x03_G_5.00mm' : generate_params( 3, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757488', '12A'), ('1923762', '16A (HC)')])),\n    'MSTBA_01x04_G_5.00mm' : generate_params( 4, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757491', '12A'), ('1923775', '16A (HC)')])),\n    'MSTBA_01x05_G_5.00mm' : generate_params( 5, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757501', '12A'), ('1923788', '16A (HC)')])),\n    'MSTBA_01x06_G_5.00mm' : generate_params( 6, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757514', '12A'), ('1923791', '16A (HC)')])),\n    'MSTBA_01x07_G_5.00mm' : generate_params( 7, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757493', '12A'), ('1923801', '16A (HC)')])),\n    'MSTBA_01x08_G_5.00mm' : generate_params( 8, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757527', '12A'), ('1923814', '16A (HC)')])),\n    'MSTBA_01x09_G_5.00mm' : generate_params( 9, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757530', '12A'), ('1923827', '16A (HC)')])),\n    'MSTBA_01x10_G_5.00mm' : generate_params(10, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757543', '12A'), ('1923830', '16A (HC)')])),\n    'MSTBA_01x11_G_5.00mm' : generate_params(11, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757556', '12A'), ('1923843', '16A (HC)')])),\n    'MSTBA_01x12_G_5.00mm' : generate_params(12, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757569', '12A'), ('1923856', '16A (HC)')])),\n    'MSTBA_01x13_G_5.00mm' : generate_params(13, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757572', '12A')])),\n    'MSTBA_01x14_G_5.00mm' : generate_params(14, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757585', '12A')])),\n    'MSTBA_01x15_G_5.00mm' : generate_params(15, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757598', '12A')])),\n    'MSTBA_01x16_G_5.00mm' : generate_params(16, \"MSTBA-G\", 5.0, True, False, OrderedDict([('1757608', '12A')])),\n    ###################################################################################################################\n    'MSTB_01x02_GF_5.00mm' : generate_params( 2, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776692', '12A'), ('1923979', '16A (HC)')])),\n    'MSTB_01x03_GF_5.00mm' : generate_params( 3, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776702', '12A'), ('1923982', '16A (HC)')])),\n    'MSTB_01x04_GF_5.00mm' : generate_params( 4, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776715', '12A'), ('1923995', '16A (HC)')])),\n    'MSTB_01x05_GF_5.00mm' : generate_params( 5, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776728', '12A'), ('1924004', '16A (HC)')])),\n    'MSTB_01x06_GF_5.00mm' : generate_params( 6, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776731', '12A'), ('1924017', '16A (HC)')])),\n    'MSTB_01x07_GF_5.00mm' : generate_params( 7, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776744', '12A'), ('1924020', '16A (HC)')])),\n    'MSTB_01x08_GF_5.00mm' : generate_params( 8, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776757', '12A'), ('1924033', '16A (HC)')])),\n    'MSTB_01x09_GF_5.00mm' : generate_params( 9, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776760', '12A'), ('1924046', '16A (HC)')])),\n    'MSTB_01x10_GF_5.00mm' : generate_params(10, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776773', '12A'), ('1924059', '16A (HC)')])),\n    'MSTB_01x11_GF_5.00mm' : generate_params(11, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776786', '12A'), ('1924062', '16A (HC)')])),\n    'MSTB_01x12_GF_5.00mm' : generate_params(12, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776799', '12A'), ('1924075', '16A (HC)')])),\n    'MSTB_01x13_GF_5.00mm' : generate_params(13, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776809', '12A')])),\n    'MSTB_01x14_GF_5.00mm' : generate_params(14, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776812', '12A')])),\n    'MSTB_01x15_GF_5.00mm' : generate_params(15, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776825', '12A')])),\n    'MSTB_01x16_GF_5.00mm' : generate_params(16, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776838', '12A')])),\n    ###################################################################################################################\n    'MSTB_01x02_GF_5.00mm_MH' : generate_params( 2, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776692', '12A'), ('1923979', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x03_GF_5.00mm_MH' : generate_params( 3, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776702', '12A'), ('1923982', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x04_GF_5.00mm_MH' : generate_params( 4, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776715', '12A'), ('1923995', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x05_GF_5.00mm_MH' : generate_params( 5, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776728', '12A'), ('1924004', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x06_GF_5.00mm_MH' : generate_params( 6, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776731', '12A'), ('1924017', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x07_GF_5.00mm_MH' : generate_params( 7, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776744', '12A'), ('1924020', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x08_GF_5.00mm_MH' : generate_params( 8, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776757', '12A'), ('1924033', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x09_GF_5.00mm_MH' : generate_params( 9, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776760', '12A'), ('1924046', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x10_GF_5.00mm_MH' : generate_params(10, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776773', '12A'), ('1924059', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x11_GF_5.00mm_MH' : generate_params(11, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776786', '12A'), ('1924062', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x12_GF_5.00mm_MH' : generate_params(12, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776799', '12A'), ('1924075', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x13_GF_5.00mm_MH' : generate_params(13, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776809', '12A')]), mount_hole=True),\n    'MSTB_01x14_GF_5.00mm_MH' : generate_params(14, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776812', '12A')]), mount_hole=True),\n    'MSTB_01x15_GF_5.00mm_MH' : generate_params(15, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776825', '12A')]), mount_hole=True),\n    'MSTB_01x16_GF_5.00mm_MH' : generate_params(16, \"MSTB-GF\", 5.0, True, True, OrderedDict([('1776838', '12A')]), mount_hole=True),\n    ###################################################################################################################\n    'MSTBVA_01x02_G_5.00mm' : generate_params( 2, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755516', '12A'), ('1924198', '16A (HC)')])),\n    'MSTBVA_01x03_G_5.00mm' : generate_params( 3, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755529', '12A'), ('1924208', '16A (HC)')])),\n    'MSTBVA_01x04_G_5.00mm' : generate_params( 4, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755532', '12A'), ('1924211', '16A (HC)')])),\n    'MSTBVA_01x05_G_5.00mm' : generate_params( 5, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755545', '12A'), ('1924224', '16A (HC)')])),\n    'MSTBVA_01x06_G_5.00mm' : generate_params( 6, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755558', '12A'), ('1924237', '16A (HC)')])),\n    'MSTBVA_01x07_G_5.00mm' : generate_params( 7, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755561', '12A'), ('1924240', '16A (HC)')])),\n    'MSTBVA_01x08_G_5.00mm' : generate_params( 8, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755574', '12A'), ('1924253', '16A (HC)')])),\n    'MSTBVA_01x09_G_5.00mm' : generate_params( 9, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755587', '12A'), ('1924266', '16A (HC)')])),\n    'MSTBVA_01x10_G_5.00mm' : generate_params(10, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755503', '12A'), ('1924279', '16A (HC)')])),\n    'MSTBVA_01x11_G_5.00mm' : generate_params(11, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755590', '12A'), ('1924282', '16A (HC)')])),\n    'MSTBVA_01x12_G_5.00mm' : generate_params(12, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755600', '12A'), ('1924295', '16A (HC)')])),\n    'MSTBVA_01x13_G_5.00mm' : generate_params(13, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755613', '12A')])),\n    'MSTBVA_01x14_G_5.00mm' : generate_params(14, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755626', '12A')])),\n    'MSTBVA_01x15_G_5.00mm' : generate_params(15, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755639', '12A')])),\n    'MSTBVA_01x16_G_5.00mm' : generate_params(16, \"MSTBVA-G\", 5.0, False, False, OrderedDict([('1755642', '12A')])),\n    ###################################################################################################################\n    'MSTBV_01x02_GF_5.00mm' : generate_params( 2, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776883', '12A'), ('1924415', '16A (HC)')])),\n    'MSTBV_01x03_GF_5.00mm' : generate_params( 3, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776896', '12A'), ('1924428', '16A (HC)')])),\n    'MSTBV_01x04_GF_5.00mm' : generate_params( 4, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776906', '12A'), ('1924431', '16A (HC)')])),\n    'MSTBV_01x05_GF_5.00mm' : generate_params( 5, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776919', '12A'), ('1924444', '16A (HC)')])),\n    'MSTBV_01x06_GF_5.00mm' : generate_params( 6, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776922', '12A'), ('1924457', '16A (HC)')])),\n    'MSTBV_01x07_GF_5.00mm' : generate_params( 7, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776935', '12A'), ('1924460', '16A (HC)')])),\n    'MSTBV_01x08_GF_5.00mm' : generate_params( 8, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776948', '12A'), ('1924473', '16A (HC)')])),\n    'MSTBV_01x09_GF_5.00mm' : generate_params( 9, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776951', '12A'), ('1924486', '16A (HC)')])),\n    'MSTBV_01x10_GF_5.00mm' : generate_params(10, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776964', '12A'), ('1924499', '16A (HC)')])),\n    'MSTBV_01x11_GF_5.00mm' : generate_params(11, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776977', '12A'), ('1924509', '16A (HC)')])),\n    'MSTBV_01x12_GF_5.00mm' : generate_params(12, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776980', '12A'), ('1924512', '16A (HC)')])),\n    'MSTBV_01x13_GF_5.00mm' : generate_params(13, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776993', '12A')])),\n    'MSTBV_01x14_GF_5.00mm' : generate_params(14, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776002', '12A')])),\n    'MSTBV_01x15_GF_5.00mm' : generate_params(15, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776015', '12A')])),\n    'MSTBV_01x16_GF_5.00mm' : generate_params(16, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776028', '12A')])),\n    ###################################################################################################################\n    'MSTBV_01x02_GF_5.00mm_MH' : generate_params( 2, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776883', '12A'), ('1924415', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x03_GF_5.00mm_MH' : generate_params( 3, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776896', '12A'), ('1924428', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x04_GF_5.00mm_MH' : generate_params( 4, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776906', '12A'), ('1924431', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x05_GF_5.00mm_MH' : generate_params( 5, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776919', '12A'), ('1924444', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x06_GF_5.00mm_MH' : generate_params( 6, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776922', '12A'), ('1924457', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x07_GF_5.00mm_MH' : generate_params( 7, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776935', '12A'), ('1924460', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x08_GF_5.00mm_MH' : generate_params( 8, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776948', '12A'), ('1924473', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x09_GF_5.00mm_MH' : generate_params( 9, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776951', '12A'), ('1924486', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x10_GF_5.00mm_MH' : generate_params(10, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776964', '12A'), ('1924499', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x11_GF_5.00mm_MH' : generate_params(11, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776977', '12A'), ('1924509', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x12_GF_5.00mm_MH' : generate_params(12, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776980', '12A'), ('1924512', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x13_GF_5.00mm_MH' : generate_params(13, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776993', '12A')]), mount_hole=True),\n    'MSTBV_01x14_GF_5.00mm_MH' : generate_params(14, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776002', '12A')]), mount_hole=True),\n    'MSTBV_01x15_GF_5.00mm_MH' : generate_params(15, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776015', '12A')]), mount_hole=True),\n    'MSTBV_01x16_GF_5.00mm_MH' : generate_params(16, \"MSTBV-GF\", 5.0, False, True, OrderedDict([('1776028', '12A')]), mount_hole=True),\n    ##################################################################################################################\n    # Pin Pitch 5.08mm\n    ##################################################################################################################\n    'MSTBA_01x02_G_5.08mm' : generate_params( 2, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757242', '12A'), ('1923869', '16A (HC)')])),\n    'MSTBA_01x03_G_5.08mm' : generate_params( 3, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757255', '12A'), ('1923872', '16A (HC)')])),\n    'MSTBA_01x04_G_5.08mm' : generate_params( 4, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757268', '12A'), ('1923885', '16A (HC)')])),\n    'MSTBA_01x05_G_5.08mm' : generate_params( 5, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757271', '12A'), ('1923898', '16A (HC)')])),\n    'MSTBA_01x06_G_5.08mm' : generate_params( 6, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757284', '12A'), ('1923908', '16A (HC)')])),\n    'MSTBA_01x07_G_5.08mm' : generate_params( 7, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757297', '12A'), ('1923911', '16A (HC)')])),\n    'MSTBA_01x08_G_5.08mm' : generate_params( 8, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757307', '12A'), ('1923924', '16A (HC)')])),\n    'MSTBA_01x09_G_5.08mm' : generate_params( 9, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757310', '12A'), ('1923937', '16A (HC)')])),\n    'MSTBA_01x10_G_5.08mm' : generate_params(10, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757323', '12A'), ('1923940', '16A (HC)')])),\n    'MSTBA_01x11_G_5.08mm' : generate_params(11, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757336', '12A'), ('1923953', '16A (HC)')])),\n    'MSTBA_01x12_G_5.08mm' : generate_params(12, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757349', '12A'), ('1923966', '16A (HC)')])),\n    'MSTBA_01x13_G_5.08mm' : generate_params(13, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757352', '12A')])),\n    'MSTBA_01x14_G_5.08mm' : generate_params(14, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757365', '12A')])),\n    'MSTBA_01x15_G_5.08mm' : generate_params(15, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757378', '12A')])),\n    'MSTBA_01x16_G_5.08mm' : generate_params(16, \"MSTBA-G\", 5.08, True, False, OrderedDict([('1757381', '12A')])),\n    ###################################################################################################################\n    'MSTB_01x02_GF_5.08mm' : generate_params( 2, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776508', '12A'), ('1924088', '16A (HC)')])),\n    'MSTB_01x03_GF_5.08mm' : generate_params( 3, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776511', '12A'), ('1924091', '16A (HC)')])),\n    'MSTB_01x04_GF_5.08mm' : generate_params( 4, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776524', '12A'), ('1924101', '16A (HC)')])),\n    'MSTB_01x05_GF_5.08mm' : generate_params( 5, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776537', '12A'), ('1924114', '16A (HC)')])),\n    'MSTB_01x06_GF_5.08mm' : generate_params( 6, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776540', '12A'), ('1924127', '16A (HC)')])),\n    'MSTB_01x07_GF_5.08mm' : generate_params( 7, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776553', '12A'), ('1924130', '16A (HC)')])),\n    'MSTB_01x08_GF_5.08mm' : generate_params( 8, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776566', '12A'), ('1924143', '16A (HC)')])),\n    'MSTB_01x09_GF_5.08mm' : generate_params( 9, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776579', '12A'), ('1924156', '16A (HC)')])),\n    'MSTB_01x10_GF_5.08mm' : generate_params(10, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776582', '12A'), ('1924169', '16A (HC)')])),\n    'MSTB_01x11_GF_5.08mm' : generate_params(11, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776595', '12A'), ('1924172', '16A (HC)')])),\n    'MSTB_01x12_GF_5.08mm' : generate_params(12, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776605', '12A'), ('1924185', '16A (HC)')])),\n    'MSTB_01x13_GF_5.08mm' : generate_params(13, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776618', '12A')])),\n    'MSTB_01x14_GF_5.08mm' : generate_params(14, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776621', '12A')])),\n    'MSTB_01x15_GF_5.08mm' : generate_params(15, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776634', '12A')])),\n    'MSTB_01x16_GF_5.08mm' : generate_params(16, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776647', '12A')])),\n    ###################################################################################################################\n    'MSTB_01x02_GF_5.08mm_MH' : generate_params( 2, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776508', '12A'), ('1924088', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x03_GF_5.08mm_MH' : generate_params( 3, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776511', '12A'), ('1924091', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x04_GF_5.08mm_MH' : generate_params( 4, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776524', '12A'), ('1924101', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x05_GF_5.08mm_MH' : generate_params( 5, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776537', '12A'), ('1924114', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x06_GF_5.08mm_MH' : generate_params( 6, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776540', '12A'), ('1924127', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x07_GF_5.08mm_MH' : generate_params( 7, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776553', '12A'), ('1924130', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x08_GF_5.08mm_MH' : generate_params( 8, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776566', '12A'), ('1924143', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x09_GF_5.08mm_MH' : generate_params( 9, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776579', '12A'), ('1924156', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x10_GF_5.08mm_MH' : generate_params(10, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776582', '12A'), ('1924169', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x11_GF_5.08mm_MH' : generate_params(11, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776595', '12A'), ('1924172', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x12_GF_5.08mm_MH' : generate_params(12, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776605', '12A'), ('1924185', '16A (HC)')]), mount_hole=True),\n    'MSTB_01x13_GF_5.08mm_MH' : generate_params(13, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776618', '12A')]), mount_hole=True),\n    'MSTB_01x14_GF_5.08mm_MH' : generate_params(14, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776621', '12A')]), mount_hole=True),\n    'MSTB_01x15_GF_5.08mm_MH' : generate_params(15, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776634', '12A')]), mount_hole=True),\n    'MSTB_01x16_GF_5.08mm_MH' : generate_params(16, \"MSTB-GF\", 5.08, True, True, OrderedDict([('1776647', '12A')]), mount_hole=True),\n    ###################################################################################################################\n    'MSTBVA_01x02_G_5.08mm' : generate_params( 2, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755736', '12A'), ('1924305', '16A (HC)')])),\n    'MSTBVA_01x03_G_5.08mm' : generate_params( 3, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755749', '12A'), ('1924318', '16A (HC)')])),\n    'MSTBVA_01x04_G_5.08mm' : generate_params( 4, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755752', '12A'), ('1924321', '16A (HC)')])),\n    'MSTBVA_01x05_G_5.08mm' : generate_params( 5, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755765', '12A'), ('1924334', '16A (HC)')])),\n    'MSTBVA_01x06_G_5.08mm' : generate_params( 6, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755778', '12A'), ('1924347', '16A (HC)')])),\n    'MSTBVA_01x07_G_5.08mm' : generate_params( 7, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755781', '12A'), ('1924350', '16A (HC)')])),\n    'MSTBVA_01x08_G_5.08mm' : generate_params( 8, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755794', '12A'), ('1924363', '16A (HC)')])),\n    'MSTBVA_01x09_G_5.08mm' : generate_params( 9, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755804', '12A'), ('1924376', '16A (HC)')])),\n    'MSTBVA_01x10_G_5.08mm' : generate_params(10, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755817', '12A'), ('1924389', '16A (HC)')])),\n    'MSTBVA_01x11_G_5.08mm' : generate_params(11, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755820', '12A'), ('1924392', '16A (HC)')])),\n    'MSTBVA_01x12_G_5.08mm' : generate_params(12, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755833', '12A'), ('1924402', '16A (HC)')])),\n    'MSTBVA_01x13_G_5.08mm' : generate_params(13, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755846', '12A')])),\n    'MSTBVA_01x14_G_5.08mm' : generate_params(14, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755859', '12A')])),\n    'MSTBVA_01x15_G_5.08mm' : generate_params(15, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755862', '12A')])),\n    'MSTBVA_01x16_G_5.08mm' : generate_params(16, \"MSTBVA-G\", 5.08, False, False, OrderedDict([('1755875', '12A')])),\n    ###################################################################################################################\n    'MSTBV_01x02_GF_5.08mm' : generate_params( 2, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777073', '12A'), ('1924525', '16A (HC)')])),\n    'MSTBV_01x03_GF_5.08mm' : generate_params( 3, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777086', '12A'), ('1924538', '16A (HC)')])),\n    'MSTBV_01x04_GF_5.08mm' : generate_params( 4, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777099', '12A'), ('1924541', '16A (HC)')])),\n    'MSTBV_01x05_GF_5.08mm' : generate_params( 5, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777109', '12A'), ('1924554', '16A (HC)')])),\n    'MSTBV_01x06_GF_5.08mm' : generate_params( 6, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777112', '12A'), ('1924567', '16A (HC)')])),\n    'MSTBV_01x07_GF_5.08mm' : generate_params( 7, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777125', '12A'), ('1924570', '16A (HC)')])),\n    'MSTBV_01x08_GF_5.08mm' : generate_params( 8, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777138', '12A'), ('1924583', '16A (HC)')])),\n    'MSTBV_01x09_GF_5.08mm' : generate_params( 9, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777141', '12A'), ('1924596', '16A (HC)')])),\n    'MSTBV_01x10_GF_5.08mm' : generate_params(10, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777154', '12A'), ('1924606', '16A (HC)')])),\n    'MSTBV_01x11_GF_5.08mm' : generate_params(11, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777167', '12A'), ('1924619', '16A (HC)')])),\n    'MSTBV_01x12_GF_5.08mm' : generate_params(12, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777170', '12A'), ('1924622', '16A (HC)')])),\n    'MSTBV_01x13_GF_5.08mm' : generate_params(13, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777183', '12A')])),\n    'MSTBV_01x14_GF_5.08mm' : generate_params(14, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777196', '12A')])),\n    'MSTBV_01x15_GF_5.08mm' : generate_params(15, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777206', '12A')])),\n    'MSTBV_01x16_GF_5.08mm' : generate_params(16, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777219', '12A')])),\n    ###################################################################################################################\n    'MSTBV_01x02_GF_5.08mm_MH' : generate_params( 2, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777073', '12A'), ('1924525', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x03_GF_5.08mm_MH' : generate_params( 3, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777086', '12A'), ('1924538', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x04_GF_5.08mm_MH' : generate_params( 4, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777099', '12A'), ('1924541', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x05_GF_5.08mm_MH' : generate_params( 5, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777109', '12A'), ('1924554', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x06_GF_5.08mm_MH' : generate_params( 6, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777112', '12A'), ('1924567', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x07_GF_5.08mm_MH' : generate_params( 7, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777125', '12A'), ('1924570', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x08_GF_5.08mm_MH' : generate_params( 8, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777138', '12A'), ('1924583', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x09_GF_5.08mm_MH' : generate_params( 9, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777141', '12A'), ('1924596', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x10_GF_5.08mm_MH' : generate_params(10, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777154', '12A'), ('1924606', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x11_GF_5.08mm_MH' : generate_params(11, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777167', '12A'), ('1924619', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x12_GF_5.08mm_MH' : generate_params(12, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777170', '12A'), ('1924622', '16A (HC)')]), mount_hole=True),\n    'MSTBV_01x13_GF_5.08mm_MH' : generate_params(13, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777183', '12A')]), mount_hole=True),\n    'MSTBV_01x14_GF_5.08mm_MH' : generate_params(14, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777196', '12A')]), mount_hole=True),\n    'MSTBV_01x15_GF_5.08mm_MH' : generate_params(15, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777206', '12A')]), mount_hole=True),\n    'MSTBV_01x16_GF_5.08mm_MH' : generate_params(16, \"MSTBV-GF\", 5.08, False, True, OrderedDict([('1777219', '12A')]), mount_hole=True),\n    ##################################################################################################################\n    # High Voltage Versions (pin pitch 7.5mm)\n    ##################################################################################################################\n    'GMSTBA_01x02_G_7.50mm' : generate_params( 2, \"GMSTBA-G\", 7.50, True, False, OrderedDict([('1766343', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x03_G_7.50mm' : generate_params( 3, \"GMSTBA-G\", 7.50, True, False, OrderedDict([('1766356', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x04_G_7.50mm' : generate_params( 4, \"GMSTBA-G\", 7.50, True, False, OrderedDict([('1766369', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x05_G_7.50mm' : generate_params( 5, \"GMSTBA-G\", 7.50, True, False, OrderedDict([('1766372', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x06_G_7.50mm' : generate_params( 6, \"GMSTBA-G\", 7.50, True, False, OrderedDict([('1766385', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x07_G_7.50mm' : generate_params( 7, \"GMSTBA-G\", 7.50, True, False, OrderedDict([('1766398', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x08_G_7.50mm' : generate_params( 8, \"GMSTBA-G\", 7.50, True, False, OrderedDict([('1766408', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x09_G_7.50mm' : generate_params( 9, \"GMSTBA-G\", 7.50, True, False, OrderedDict([('1766411', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x10_G_7.50mm' : generate_params(10, \"GMSTBA-G\", 7.50, True, False, OrderedDict([('1766424', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x11_G_7.50mm' : generate_params(11, \"GMSTBA-G\", 7.50, True, False, OrderedDict([('1766437', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x12_G_7.50mm' : generate_params(12, \"GMSTBA-G\", 7.50, True, False, OrderedDict([('1766440', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    ##################################################################################################################\n    'GMSTBVA_01x02_G_7.50mm' : generate_params( 2, \"GMSTBVA-G\", 7.50, False, False, OrderedDict([('1766660', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x03_G_7.50mm' : generate_params( 3, \"GMSTBVA-G\", 7.50, False, False, OrderedDict([('1766673', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x04_G_7.50mm' : generate_params( 4, \"GMSTBVA-G\", 7.50, False, False, OrderedDict([('1766686', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x05_G_7.50mm' : generate_params( 5, \"GMSTBVA-G\", 7.50, False, False, OrderedDict([('1766699', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x06_G_7.50mm' : generate_params( 6, \"GMSTBVA-G\", 7.50, False, False, OrderedDict([('1766709', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x07_G_7.50mm' : generate_params( 7, \"GMSTBVA-G\", 7.50, False, False, OrderedDict([('1766712', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x08_G_7.50mm' : generate_params( 8, \"GMSTBVA-G\", 7.50, False, False, OrderedDict([('1766725', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x09_G_7.50mm' : generate_params( 9, \"GMSTBVA-G\", 7.50, False, False, OrderedDict([('1766738', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x10_G_7.50mm' : generate_params(10, \"GMSTBVA-G\", 7.50, False, False, OrderedDict([('1766741', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x11_G_7.50mm' : generate_params(11, \"GMSTBVA-G\", 7.50, False, False, OrderedDict([('1766754', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x12_G_7.50mm' : generate_params(12, \"GMSTBVA-G\", 7.50, False, False, OrderedDict([('1766767', '12A 630V')]), side_to_pin=3.75, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    ##################################################################################################################\n    # High Voltage Versions (pin pitch 7.62mm)\n    ##################################################################################################################\n    'GMSTBA_01x02_G_7.62mm' : generate_params( 2, \"GMSTBA-G\", 7.62, True, False, OrderedDict([('1766233', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x03_G_7.62mm' : generate_params( 3, \"GMSTBA-G\", 7.62, True, False, OrderedDict([('1766246', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x04_G_7.62mm' : generate_params( 4, \"GMSTBA-G\", 7.62, True, False, OrderedDict([('1766259', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x05_G_7.62mm' : generate_params( 5, \"GMSTBA-G\", 7.62, True, False, OrderedDict([('1766262', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x06_G_7.62mm' : generate_params( 6, \"GMSTBA-G\", 7.62, True, False, OrderedDict([('1766275', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x07_G_7.62mm' : generate_params( 7, \"GMSTBA-G\", 7.62, True, False, OrderedDict([('1766288', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x08_G_7.62mm' : generate_params( 8, \"GMSTBA-G\", 7.62, True, False, OrderedDict([('1766291', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x09_G_7.62mm' : generate_params( 9, \"GMSTBA-G\", 7.62, True, False, OrderedDict([('1766301', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x10_G_7.62mm' : generate_params(10, \"GMSTBA-G\", 7.62, True, False, OrderedDict([('1766314', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x11_G_7.62mm' : generate_params(11, \"GMSTBA-G\", 7.62, True, False, OrderedDict([('1766327', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBA_01x12_G_7.62mm' : generate_params(12, \"GMSTBA-G\", 7.62, True, False, OrderedDict([('1766330', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    ###################################################################################################################\n    'GMSTB_01x02_GF_7.62mm' : generate_params( 2, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806229', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x03_GF_7.62mm' : generate_params( 3, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806232', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x04_GF_7.62mm' : generate_params( 4, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806245', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x05_GF_7.62mm' : generate_params( 5, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806258', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x06_GF_7.62mm' : generate_params( 6, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806261', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x07_GF_7.62mm' : generate_params( 7, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806274', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x08_GF_7.62mm' : generate_params( 8, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806287', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x09_GF_7.62mm' : generate_params( 9, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806290', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x10_GF_7.62mm' : generate_params(10, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806300', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x11_GF_7.62mm' : generate_params(11, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806313', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x12_GF_7.62mm' : generate_params(12, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806326', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    ###################################################################################################################\n    'GMSTB_01x02_GF_7.62mm_MH' : generate_params( 2, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806229', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x03_GF_7.62mm_MH' : generate_params( 3, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806232', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x04_GF_7.62mm_MH' : generate_params( 4, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806245', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x05_GF_7.62mm_MH' : generate_params( 5, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806258', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x06_GF_7.62mm_MH' : generate_params( 6, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806261', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x07_GF_7.62mm_MH' : generate_params( 7, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806274', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x08_GF_7.62mm_MH' : generate_params( 8, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806287', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x09_GF_7.62mm_MH' : generate_params( 9, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806290', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x10_GF_7.62mm_MH' : generate_params(10, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806300', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x11_GF_7.62mm_MH' : generate_params(11, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806313', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTB_01x12_GF_7.62mm_MH' : generate_params(12, \"GMSTB-GF\", 7.62, True, True, OrderedDict([('1806326', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    ###################################################################################################################\n    'GMSTBVA_01x02_G_7.62mm' : generate_params( 2, \"GMSTBVA-G\", 7.62, False, False, OrderedDict([('1766770', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x03_G_7.62mm' : generate_params( 3, \"GMSTBVA-G\", 7.62, False, False, OrderedDict([('1766783', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x04_G_7.62mm' : generate_params( 4, \"GMSTBVA-G\", 7.62, False, False, OrderedDict([('1766796', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x05_G_7.62mm' : generate_params( 5, \"GMSTBVA-G\", 7.62, False, False, OrderedDict([('1766806', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x06_G_7.62mm' : generate_params( 6, \"GMSTBVA-G\", 7.62, False, False, OrderedDict([('1766819', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x07_G_7.62mm' : generate_params( 7, \"GMSTBVA-G\", 7.62, False, False, OrderedDict([('1766822', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x08_G_7.62mm' : generate_params( 8, \"GMSTBVA-G\", 7.62, False, False, OrderedDict([('1766835', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x09_G_7.62mm' : generate_params( 9, \"GMSTBVA-G\", 7.62, False, False, OrderedDict([('1766848', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x10_G_7.62mm' : generate_params(10, \"GMSTBVA-G\", 7.62, False, False, OrderedDict([('1766851', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x11_G_7.62mm' : generate_params(11, \"GMSTBVA-G\", 7.62, False, False, OrderedDict([('1766864', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBVA_01x12_G_7.62mm' : generate_params(12, \"GMSTBVA-G\", 7.62, False, False, OrderedDict([('1766877', '12A 630V')]), side_to_pin=3.81, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    ###################################################################################################################\n    'GMSTBV_01x02_GF_7.62mm' : generate_params( 2, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829154', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x03_GF_7.62mm' : generate_params( 3, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829167', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x04_GF_7.62mm' : generate_params( 4, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829170', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x05_GF_7.62mm' : generate_params( 5, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829183', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x06_GF_7.62mm' : generate_params( 6, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829196', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x07_GF_7.62mm' : generate_params( 7, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829206', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x08_GF_7.62mm' : generate_params( 8, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829219', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x09_GF_7.62mm' : generate_params( 9, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829222', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x10_GF_7.62mm' : generate_params(10, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829235', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x11_GF_7.62mm' : generate_params(11, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829248', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x12_GF_7.62mm' : generate_params(12, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829251', '12A 630V')]), mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    ###################################################################################################################\n    'GMSTBV_01x02_GF_7.62mm_MH' : generate_params( 2, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829154', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x03_GF_7.62mm_MH' : generate_params( 3, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829167', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x04_GF_7.62mm_MH' : generate_params( 4, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829170', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x05_GF_7.62mm_MH' : generate_params( 5, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829183', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x06_GF_7.62mm_MH' : generate_params( 6, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829196', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x07_GF_7.62mm_MH' : generate_params( 7, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829206', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x08_GF_7.62mm_MH' : generate_params( 8, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829219', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x09_GF_7.62mm_MH' : generate_params( 9, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829222', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x10_GF_7.62mm_MH' : generate_params(10, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829235', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x11_GF_7.62mm_MH' : generate_params(11, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829248', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance),\n    'GMSTBV_01x12_GF_7.62mm_MH' : generate_params(12, \"GMSTBV-GF\", 7.62, False, True, OrderedDict([('1829251', '12A 630V')]), mount_hole=True, mount_hole_to_pin=6.1, side_to_pin=9.1, min_pad_to_pad_clearance=seriesParams.GMSTB_min_pad_to_pad_clearance)\n}\n\n#lock_cutout=\n\ndef dimensions(params):\n    lenght = (params.num_pins-1)*params.pin_pitch + 2*params.side_to_pin\n    width = 12 if params.angled else 8.6\n    upper_to_pin = -2 if params.angled else -8.6+3.8\n    left_to_pin = -params.side_to_pin\n    mount_hole_y = 2.5 if params.angled else 0.0\n    mount_hole_left = [-params.mount_hole_to_pin,mount_hole_y]\n    mount_hole_right = [(params.num_pins-1)*params.pin_pitch+params.mount_hole_to_pin,mount_hole_y]\n    inner_len = params.num_pins*params.pin_pitch-1.6 + (0 if params.pin_pitch>5.08 else 2)\n    return lenght, width, upper_to_pin, left_to_pin,\\\n        mount_hole_left, mount_hole_right, inner_len\n\ndef generate_description(params, mpn):\n    d = \"Generic Phoenix Contact connector footprint for: \" + mpn + \"; number of pins: \" + (\"%02d\" %params.num_pins) + \"; pin pitch: \" + (('%.2f' % params.pin_pitch))\\\n        +\"mm\" + ('; Angled' if params.angled else '; Vertical')\\\n        + ('; threaded flange' + ('; footprint includes mount hole for mounting screw: ' + seriesParams.mount_screw_info if params.mount_hole else '') if params.flanged else '')\n    for order_num, info in params.order_info.items():\n        d += \" || order number: \" + order_num + \" \" + info\n    return d\n"
  },
  {
    "path": "scripts/Connector/Connector_SMD_single_row_plus_mounting_pad/conn_hirose.yaml",
    "content": "group_definitions:\n    manufacturer: 'Hirose'\n\ndevice_definition:\n    DF3EA:\n        series: ''\n        mpn_format_string: 'DF3EA-{pincount:02d}P-2H'\n        orientation: 'H'\n        datasheet: 'https://www.hirose.com/product/document?clcode=CL0543-0332-0-51&productname=DF3EA-5P-2H(51)&series=DF3&documenttype=2DDrawing&lang=en&documentid=0001163317'\n        pinrange: ['list', [2,3,4,5,6,7,8,9,10,11,12,13,14,15]]\n        text_inside_pos: 'center'\n        pitch: 2\n        pad1_position: 'top-left'\n        mounting_pad_size: [2.3, 3.3]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 3.37 #(D-B)/2\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 8.8\n        rel_pad_y_inside_edge: 5.7\n        pad_size_x: 1.2\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0.45\n        body_size_y: 5.9\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 3.25\n    # DF13C:\n    #     series: 'DF13C'\n    #     mpn_format_string: 'CL535-04{pincount:02d}-{param_1:s}-51'\n    #     mpn_param_1: ['2','5','8','0','3','6','9','1','4','3','6','1','4']\n    #     orientation: 'V'\n    #     datasheet: 'https://www.hirose.com/product/en/products/DF13/DF13C-10P-1.25V%2851%29/'\n    #     pinrange: ['list', [2,3,4,5,6,7,8,9,10,11,12,14,15]]\n    #     text_inside_pos: 'center'\n    #     pitch: 1.25\n    #     pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n    #     mounting_pad_size: [1.6, 2.2]\n    #     # x position mounting inner mounting pad edge relative to nearest pad center\n    #     center_pad_to_mounting_pad_edge: 1.45\n    #     # y dimensions for pad given relative to mounting pad edge\n    #     rel_pad_y_outside_edge: 4.7\n    #     rel_pad_y_inside_edge: 2.9\n    #     pad_size_x: 0.7\n    #     # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n    #     rel_body_edge_y: 0.6\n    #     body_size_y: 3.4\n    #     # body_fin_protrusion: 1.6\n    #     # body_fin_width: 0.8\n    #     # x body edge relative to nearest pin\n    #     rel_body_edge_x: 2.2\n    #     # todo: keepout\n    DF52:\n        series: ''\n        mpn_format_string: 'DF52-{pincount:d}S-0.8H'\n        orientation: 'H'\n        datasheet: 'https://www.hirose.com/product/en/products/DF52/DF52-3S-0.8H%2821%29/'\n        pinrange: ['list', [2,3,4,5,6,7,8,9,10,11,12,14,15]]\n        text_inside_pos: 'bottom'\n        pitch: 0.8\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [0.9, 1.6]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.8\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 3.22\n        rel_pad_y_inside_edge: 2.22\n        pad_size_x: 0.5\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.1\n        body_size_y: 2.77\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n    # FH12_34:\n    #     series: ''\n    #     mpn_format_string: 'FH12-{pincount:d}S-0.8H'\n    #     orientation: 'H'\n    #     datasheet: 'https://www.hirose.com/product/en/products/FH12/FH12-24S-0.5SH(55)/'\n    #     pinrange: ['list', [6,8,10,11,12,13,14,15,16,17,18,19,20,22,24,25,26,28,30,32,33,34]]\n    #     text_inside_pos: 'bottom'\n    #     pitch: 0.5\n    #     pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n    #     mounting_pad_size: [1.8, 2.2]\n    #     # x position mounting inner mounting pad edge relative to nearest pad center\n    #     center_pad_to_mounting_pad_edge: 1\n    #     # y dimensions for pad given relative to mounting pad edge\n    #     rel_pad_y_outside_edge: 5\n    #     rel_pad_y_inside_edge: 3.7\n    #     pad_size_x: 0.3\n    #     # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n    #     rel_body_edge_y: 1.9\n    #     body_size_y: 5.6\n    #     # body_fin_protrusion: 1.6\n    #     # body_fin_width: 0.8\n    #     # x body edge relative to nearest pin\n    #     rel_body_edge_x: 1.8\n    # FH12_35: # I could not find a difference between the <=34 section and the >= 35 pin section.\n    #     series: ''\n    #     mpn_format_string: 'FH12-{pincount:d}S-0.8H'\n    #     orientation: 'H'\n    #     datasheet: 'https://www.hirose.com/product/en/products/FH12/FH12-24S-0.5SH(55)/'\n    #     pinrange: ['list', [35,36,40,45,50,53]]\n    #     text_inside_pos: 'bottom'\n    #     pitch: 0.5\n    #     pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n    #     mounting_pad_size: [1.8, 2.2]\n    #     # x position mounting inner mounting pad edge relative to nearest pad center\n    #     center_pad_to_mounting_pad_edge: 1\n    #     # y dimensions for pad given relative to mounting pad edge\n    #     rel_pad_y_outside_edge: 5\n    #     rel_pad_y_inside_edge: 3.7\n    #     pad_size_x: 0.3\n    #     # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n    #     rel_body_edge_y: 1.9\n    #     body_size_y: 5.6\n    #     # body_fin_protrusion: 1.6\n    #     # body_fin_width: 0.8\n    #     # x body edge relative to nearest pin\n    #     rel_body_edge_x: 1.8\n"
  },
  {
    "path": "scripts/Connector/Connector_SMD_single_row_plus_mounting_pad/conn_jst.yaml",
    "content": "group_definitions:\n    manufacturer: 'JST'\n\ndevice_definition:\n    ACH_top_entry_1:\n        series: 'ACH'\n        mpn_format_string: 'BM{pincount:02d}B-ACHSS-A-GAN-ETF'\n        orientation: 'V'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eACH.pdf'\n        pinrange: ['list', [1]]\n        text_inside_pos: 0\n        pitch: 1.2\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [0.75, 1.1]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.9\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 4.6\n        rel_pad_y_inside_edge: 3.75\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0\n        body_size_y: 4.3\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.6 #3.2/2\n        edge_modifier_mount_pad_side:\n            depth: 0.4 # > 0: cutout, < 0: protrusion\n            width_start: 1.6\n            # start_from_body_side\n            width_end: 0.8\n            # end_from_body_side\n\n\n    ACH_top_entry_23:\n        series: 'ACH'\n        mpn_format_string: 'BM{pincount:02d}B-ACHSS-GAN-ETF'\n        orientation: 'V'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eACH.pdf'\n        pinrange: ['list', [2,3]]\n        text_inside_pos: 0\n        pitch: 1.2\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [0.7, 0.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.8\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 4.6\n        rel_pad_y_inside_edge: 3.75\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0\n        body_size_y: 4.3\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n        edge_modifier_mount_pad_side:\n            depth: 0.5 # > 0: cutout, < 0: protrusion\n            width_start: 1.8\n            # start_from_body_side\n            width_end: 1\n            # end_from_body_side\n\n    ACH_top_entry_45:\n        series: 'ACH'\n        mpn_format_string: 'BM{pincount:02d}B-ACHSS-A-GAN-ETF'\n        orientation: 'V'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eACH.pdf'\n        pinrange: ['list', [4,5]]\n        text_inside_pos: 0\n        pitch: 1.2\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [0.75, 1.1]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.8\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 4.6\n        rel_pad_y_inside_edge: 3.75\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0\n        body_size_y: 4.3\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n        edge_modifier_mount_pad_side:\n            depth: 0.5 # > 0: cutout, < 0: protrusion\n            width_start: 1.8\n            # start_from_body_side\n            width_end: 1\n            # end_from_body_side\n\n    AUH_top_entry:\n        series: 'AUH'\n        mpn_format_string: 'BM{pincount:02d}B-AUHKS-GA-TB'\n        orientation: 'V'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eAUH.pdf'\n        pinrange: ['list', [3,5]]\n        text_inside_pos: 0\n        pitch: 1.5\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [0.6, 1.45]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.15\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 5.05\n        rel_pad_y_inside_edge: 4\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.3\n        body_size_y: 4.3\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.775\n        edge_modifier_mount_pad_side:\n            depth: 1 # > 0: cutout, < 0: protrusion\n            #width_start: 1.6\n            start_from_body_side: 1\n            #width_end: 0.8\n            end_from_body_side: 1\n\n    LEA_top_entry:\n        series: 'LEA'\n        mpn_format_string: 'SM{pincount:02d}B-LEASS-TF'\n        orientation: 'H'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eLEA.pdf'\n        pinrange: ['list', [2]]\n        text_inside_pos: 0\n        pitch: 4.2\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [0.85, 1.75]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.15\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 6.45\n        rel_pad_y_inside_edge: 4.65\n        pad_size_x: 1.05\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0.2\n        body_size_y: 6.3\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.95\n        edge_modifier_mount_pad_side:\n            depth: 0.4 # > 0: cutout, < 0: protrusion\n            #width_start: 1.6\n            start_from_body_side: 1.2\n            #width_end: 0.8\n            end_from_body_side: 1.2\n        edge_modifier_pin_side:\n            length: -1.6 # > 0: fin, < 0: cutout\n            width: 1.5\n\n    GH_side_entry:\n        series: 'GH'\n        mpn_format_string: 'SM{pincount:02d}B-GHS-TB'\n        orientation: 'H'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eGH.pdf'\n        pinrange: ['range', [2, 16]]\n        text_inside_pos: 0\n        pitch: 1.25\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1, 2.7]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.35\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 5.4\n        rel_pad_y_inside_edge: 3.7\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.25\n        body_size_y: 4.05\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 2.25\n\n    GH_top_entry:\n        series: 'GH'\n        mpn_format_string: 'BM{pincount:02d}B-GHS-TBT'\n        orientation: 'V'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eGH.pdf'\n        pinrange: ['range', [2, 16]]\n        text_inside_pos: -1.5\n        pitch: 1.25\n        pad1_position: 'bottom-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1, 2.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.35\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 5.6\n        rel_pad_y_inside_edge: 3.9\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.3\n        body_size_y: 4.25\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 2.25\n        additional_drawing:\n            -\n                layer: 'F.Fab'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['center', -0.25] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                rectangle:\n                    size: [0.5, 0.5] # centered around reference_point\n                    # start: [-0.25, -0.25] #releative to reference_point\n                    # end: [0.25, 0.25] #relative to reference_point\n                # polygone:\n                #     - [-0.25,-0.25]\n                #     - [-0.25,0.25]\n                #     - [0.25,0.25]\n                #     - [0.25,-0.25]\n                #     - [-0.25,-0.25]\n                repeat:\n                    spacing: ['pitch', 0] # x,y= 'pitch' | value\n                    reference_is: 'center' # 'center' | 'first' | 'last'\n                    count: 'pincount' # 'pincount' | value\n\n\n    PH_side_entry:\n        series: 'PH'\n        mpn_format_string: 'S{pincount:d}B-PH-SM4-TB'\n        orientation: 'H'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/ePH.pdf'\n        pinrange: ['range', [2, 16]]\n        text_inside_pos: 1.5\n        pitch: 2\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.5, 3.4]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.6\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 9.2\n        rel_pad_y_inside_edge: 5.7\n        pad_size_x: 1\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.2\n        body_size_y: 6\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 2.95 #(7.9-2)/2\n        edge_modifier_pin_side:\n            length: 1.6 # > 0: fin, < 0: cutout\n            width: 0.8\n\n    PH_top_entry:\n        series: 'PH'\n        mpn_format_string: 'B{pincount:d}B-PH-SM4-TB'\n        orientation: 'V'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/ePH.pdf'\n        pinrange: ['range', [2, 17]]\n        text_inside_pos: -1\n        pitch: 2\n        pad1_position: 'bottom-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.6, 3]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.6\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 6.5\n        rel_pad_y_inside_edge: 1\n        pad_size_x: 1\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 1\n        body_size_y: 5\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 2.975 #(7.95-2)/2\n        additional_drawing:\n            -\n                layer: 'F.Fab'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['center', -2.5] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                rectangle:\n                    size: [0.5, 0.5] # centered around reference_point\n                    # start: [-0.25, -0.25] #releative to reference_point\n                    # end: [0.25, 0.25] #relative to reference_point\n                # polygone:\n                #     - [-0.25,-0.25]\n                #     - [-0.25,0.25]\n                #     - [0.25,0.25]\n                #     - [0.25,-0.25]\n                #     - [-0.25,-0.25]\n                repeat:\n                    spacing: ['pitch', 0] # x,y= 'pitch' | value\n                    reference_is: 'center' # 'center' | 'first' | 'last'\n                    count: 'pincount' # 'pincount' | value\n\n    SFH_side_entry:\n        series: 'SFH'\n        mpn_format_string: 'SM{pincount:02}B-SFHRS-TF'\n        orientation: 'H'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eSFH.pdf'\n        pinrange: ['list', [2]]\n        text_inside_pos: 0.5\n        pitch: 4.2\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [0.85, 1.75]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: -0.325\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 6.45\n        rel_pad_y_inside_edge: 4.65\n        pad_size_x: 1.05\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.2\n        body_size_y: 5.9\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 0.5\n        no_automatic_silk_autline: 'True'\n        additional_drawing:\n            -\n                layer: 'F.SilkS'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['center', 'top'] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                polygone:\n                    - [-1.315, -0.11]\n                    - [1.315, -0.11]\n            -\n                layer: 'F.SilkS'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['center', 'bottom'] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                polygone:\n                    - [-1.515, 0.11]\n                    - [1.515, 0.11]\n            -\n                layer: 'F.SilkS'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['left', 0] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                polygone:\n                    - [-0.11, -1.165]\n                    - [-0.11, 1.215]\n            -\n                layer: 'F.SilkS'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['right', 0] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                polygone:\n                    - [0.11, -1.165]\n                    - [0.11, 1.215]\n\n    SHL_side_entry:\n        series: 'SHL'\n        mpn_format_string: 'SM{pincount:02}B-SHLS-TF'\n        orientation: 'H'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eSHL.pdf'\n        pinrange: ['list', [2,5,6,7,8,10,11,12,14,16,20,22,26,30]]\n        text_inside_pos: 0.5\n        pitch: 1\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [0.9, 1.7]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 4.6\n        rel_pad_y_inside_edge: 3.35\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0.7\n        body_size_y: 4.3\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.9\n\n    SH_side_entry:\n        series: 'SH'\n        mpn_format_string: 'SM{pincount:02}B-SRSS-TB'\n        orientation: 'H'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eSH.pdf'\n        pinrange: ['list', [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 20]]\n        text_inside_pos: 0\n        pitch: 1\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.2, 1.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.7\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 5.55\n        rel_pad_y_inside_edge: 4\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.2\n        body_size_y: 4.25\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n\n    SH_top_entry:\n        series: 'SH'\n        mpn_format_string: 'BM{pincount:02}B-SRSS-TB'\n        orientation: 'V'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eSH.pdf'\n        pinrange: ['range', [2,16]]\n        text_inside_pos: -0.25\n        pitch: 1\n        pad1_position: 'bottom-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.2, 1.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.7\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 4.2\n        rel_pad_y_inside_edge: 2.65\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.2\n        body_size_y: 2.9\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n        additional_drawing:\n            -\n                layer: 'F.Fab'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['center', -1.25] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                rectangle:\n                    size: [0.3, 0.6] # centered around reference_point\n                    # start: [-0.25, -0.25] #releative to reference_point\n                    # end: [0.25, 0.25] #relative to reference_point\n                # polygone:\n                #     - [-0.25,-0.25]\n                #     - [-0.25,0.25]\n                #     - [0.25,0.25]\n                #     - [0.25,-0.25]\n                #     - [-0.25,-0.25]\n                repeat:\n                    spacing: ['pitch', 0] # x,y= 'pitch' | value\n                    reference_is: 'center' # 'center' | 'first' | 'last'\n                    count: 'pincount' # 'pincount' | value\n\n    SUR_side_entry:\n        series: 'SUR'\n        mpn_format_string: 'SM{pincount:02}B-SURS-TF'\n        orientation: 'H'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eSUR.pdf'\n        pinrange: ['list', [2, 3, 4, 5, 6, 8, 10, 12, 14, 15, 16, 17, 20, 22]]\n        text_inside_pos: 0\n        pitch: 0.8\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.2, 1.7]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.7\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 3.3\n        rel_pad_y_inside_edge: 2.3\n        pad_size_x: 0.5\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.35\n        body_size_y: 2.7\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n        edge_modifier_pin_side:\n            length: -0.3 # > 0: fin, < 0: cutout\n            width: 0.85\n\n    SUR_top_entry:\n        series: 'SUR'\n        mpn_format_string: 'BM{pincount:02}B-SURS-TF'\n        orientation: 'V'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eSUR.pdf'\n        pinrange: ['list', [2, 3, 4, 5, 6, 8, 10, 12, 14, 15, 16, 17, 20]]\n        text_inside_pos: -0.4\n        pitch: 0.8\n        pad1_position: 'bottom-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.2, 1.7]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.7\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 2.8\n        rel_pad_y_inside_edge: 1.7\n        pad_size_x: 0.5\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.3\n        body_size_y: 2\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n\n    XAG_side_entry:\n        series: 'XAG'\n        mpn_format_string: 'SM{pincount:02d}B-XAGKS-BN-TB'\n        orientation: 'H'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eXAG.pdf'\n        pinrange: ['list', [5]]\n        text_inside_pos: 0\n        pitch: 2.5\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.8, 3.9]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 4.7\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 12.6\n        rel_pad_y_inside_edge: 8.4\n        pad_size_x: 1.3\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.2\n        body_size_y: 9.5\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 6.15\n        edge_modifier_pin_side:\n            length: 2.1 # > 0: fin, < 0: cutout\n            width: 4.6\n\n    ZE_side_entry:\n        series: 'ZE'\n        mpn_format_string: 'SM{pincount:02}B-ZESS-TB'\n        orientation: 'H'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eZE.pdf'\n        pinrange: ['range', [2, 17]]\n        text_inside_pos: 0\n        pitch: 1.5\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.8, 3.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.7\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 8.05\n        rel_pad_y_inside_edge: 5.15\n        pad_size_x: 0.8\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 1.45\n        body_size_y: 7.5\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 3\n\n    ZE_top_entry:\n        series: 'ZE'\n        mpn_format_string: 'BM{pincount:02}B-ZESS-TBT'\n        orientation: 'V'\n        datasheet: 'http://www.jst-mfg.com/product/pdf/eng/eZE.pdf'\n        pinrange: ['range', [2, 17]]\n        text_inside_pos: -1.5\n        pitch: 1.5\n        pad1_position: 'bottom-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.8, 3.3]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.7\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 7.9\n        rel_pad_y_inside_edge: 5.5\n        pad_size_x: 0.8\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.4\n        body_size_y: 5.8\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 3\n        additional_drawing:\n            -\n                layer: 'F.Fab'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['center', -0.25] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                rectangle:\n                    size: [0.5, 0.5] # centered around reference_point\n                    # start: [-0.25, -0.25] #releative to reference_point\n                    # end: [0.25, 0.25] #relative to reference_point\n                repeat:\n                    spacing: ['pitch', 0] # x,y= 'pitch' | value\n                    reference_is: 'center' # 'center' | 'first' | 'last'\n                    count: 'pincount' # 'pincount' | value\n"
  },
  {
    "path": "scripts/Connector/Connector_SMD_single_row_plus_mounting_pad/conn_molex.yaml",
    "content": "group_definitions:\n    manufacturer: 'Molex'\n\ndevice_definition:\n    Panelmate_side_entry:\n        series: 'Panelmate'\n        mpn_format_string: '53780-{pincount:02d}70'\n        orientation: 'H'\n        datasheet: ''\n        pinrange: ['list', [2,3,4,5,6,7,8,9,10,12,14,15,18,30]]\n        text_inside_pos: 'center'\n        pitch: 1.25\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.3, 3.35]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 2.2\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 7.5\n        rel_pad_y_inside_edge: 5.6\n        pad_size_x: 0.8\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.1\n        body_size_y: 5.9\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 3.2\n        edge_modifier_mount_pad_side:\n            depth: 1 # > 0: cutout, < 0: protrusion\n            # width_start: 1.6\n            start_from_body_side: 1.9\n            # width_end: 0.8\n            end_from_body_side: 2.3\n\n    PicoEZ_top_entry:\n        series: 'Pico-EZmate'\n        mpn_format_string: '78171-00{pincount:02d}'\n        orientation: 'V'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/781710002_sd.pdf'\n        pinrange: ['list', [2,3,4,5]]\n        text_inside_pos: 'center'\n        pitch: 1.2\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [0.7, 0.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.8\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 4.6\n        rel_pad_y_inside_edge: 3.75\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0.22\n        body_size_y: 4.5\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n        edge_modifier_mount_pad_side:\n            depth: 0.5 # > 0: cutout, < 0: protrusion\n            # width_start: 1.6\n            start_from_body_side: 1.35\n            # width_end: 0.8\n            end_from_body_side: 1.65\n\n    PicoEZSlim_top_entry:\n        series: 'Pico-EZmate_Slim'\n        mpn_format_string: '202656-0{pincount:02d}1'\n        orientation: 'V'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/2026560021_sd.pdf'\n        pinrange: ['list', [2]]\n        text_inside_pos: 'center'\n        pitch: 1.2\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [0.7, 0.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.95\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 4.85\n        rel_pad_y_inside_edge: 4\n        pad_size_x: 0.7\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0.18\n        body_size_y: 4.72\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.65\n        edge_modifier_mount_pad_side:\n            depth: 0.8 # > 0: cutout, < 0: protrusion\n            width_start: 2.3\n            #start_from_body_side: 1.35\n            width_end: 2.3\n            #end_from_body_side: 1.65\n\n    PicoBlade_top_entry:\n        series: 'PicoBlade'\n        mpn_format_string: '53398-{pincount:02d}71'\n        orientation: 'V'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/533980271_sd.pdf'\n        pinrange: ['range', [2,16]]\n        text_inside_pos: 0.4\n        pitch: 1.25\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [2.1, 3]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.5\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 4.9\n        rel_pad_y_inside_edge: 3.6\n        pad_size_x: 0.8\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.4\n        body_size_y: 3.7\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n        # amount to shift y position of center for pick-and-place (positive -> shift whole footprint up)\n        center_shift_y: -0.55\n        additional_drawing:\n            -\n                layer: 'F.Fab'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['center', 1.525] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                rectangle:\n                    size: [0.3, 0.6] # centered around reference_point\n                    # start: [-0.25, -0.25] #releative to reference_point\n                    # end: [0.25, 0.25] #relative to reference_point\n                repeat:\n                    spacing: ['pitch', 0] # x,y= 'pitch' | value\n                    reference_is: 'center' # 'center' | 'first' | 'last'\n                    count: 'pincount' # 'pincount' | value\n            -\n                layer: 'F.Fab'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['left', 'bottom'] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                polygone:\n                    - [0, 0]\n                    - [-1.5, 0]\n                    - [-1.7, -0.2]\n                    - [-1.7, -2.0]\n                    - [-1.5, -2.2]\n                    - [-1.5, -2.8]\n                    - [0, -2.8]\n            -\n                layer: 'F.Fab'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['right', 'bottom'] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                polygone:\n                    - [0, 0]\n                    - [1.5, 0]\n                    - [1.7, -0.2]\n                    - [1.7, -2.0]\n                    - [1.5, -2.2]\n                    - [1.5, -2.8]\n                    - [0, -2.8]\n\n    PicoBlade_side_entry:\n        series: 'PicoBlade'\n        mpn_format_string: '53261-{pincount:02d}71'\n        orientation: 'H'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/532610271_sd.pdf'\n        pinrange: ['list', [2,3,4,5,6,7,8,9,10,11,12,13,14,15,17]]\n        text_inside_pos: 'bottom'\n        pitch: 1.25\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [2.1, 3]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.5\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 5.2\n        rel_pad_y_inside_edge: 3.6\n        pad_size_x: 0.8\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0.6\n        body_size_y: 4.2\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n        # amount to shift y position of center for pick-and-place (positive -> shift whole footprint up)\n        center_shift_y: 0.6\n        additional_drawing:\n            -\n                layer: 'F.Fab'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['left', 'top'] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                polygone:\n                    - [0, 1]\n                    - [-1.5, 1]\n                    - [-1.7, 1.2]\n                    - [-1.7, 3.0]\n                    - [-1.5, 3.2]\n                    - [-1.5, 3.8]\n                    - [0, 3.8]\n            -\n                layer: 'F.Fab'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['right', 'top'] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                polygone:\n                    - [0, 1]\n                    - [1.5, 1]\n                    - [1.7, 1.2]\n                    - [1.7, 3.0]\n                    - [1.5, 3.2]\n                    - [1.5, 3.8]\n                    - [0, 3.8]\n\n    PicoClasp_top_entry_1:\n        series: 'Pico-Clasp'\n        mpn_format_string: '501331-{pincount:02d}07'\n        orientation: 'V'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/5013310207_sd.pdf'\n        pinrange: ['range', [2,6]]\n        text_inside_pos: 'top'\n        pitch: 1\n        pad1_position: 'bottom-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.2, 1.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.7\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 4.2\n        rel_pad_y_inside_edge: 2.65\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.25\n        body_size_y: 3\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n        additional_drawing:\n            -\n                layer: 'F.Fab'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['center', 0] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                rectangle:\n                    size: [0.25, 0.5] # centered around reference_point\n                    # start: [-0.25, -0.25] #releative to reference_point\n                    # end: [0.25, 0.25] #relative to reference_point\n                repeat:\n                    spacing: ['pitch', 0] # x,y= 'pitch' | value\n                    reference_is: 'center' # 'center' | 'first' | 'last'\n                    count: 'pincount' # 'pincount' | value\n\n    PicoClasp_top_entry_2:\n        series: 'Pico-Clasp'\n        mpn_format_string: '501331-{pincount:02d}07'\n        orientation: 'V'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/5013310207_sd.pdf'\n        pinrange: ['range', [6,16]]\n        text_inside_pos: 'top'\n        pitch: 1\n        pad1_position: 'bottom-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.2, 1.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.7\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 4.2\n        rel_pad_y_inside_edge: 2.65\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -0.25\n        body_size_y: 3\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n        edge_modifier_mount_pad_side:\n            depth: -1.47 # > 0: cutout, < 0: protrusion\n            width_start: 4.5\n            #start_from_body_side: 1.9\n            width_end: 4.5\n            #end_from_body_side: 2.3\n        additional_drawing:\n            -\n                layer: 'F.Fab'\n                # thickness: 0.1 #optional parameter. If not given: take fab_line_width and silk_line_width from config file. Needed if layer not silk or fab!\n                reference_point: ['center', 0] # [x,y]: x = 'left' | 'center' | 'right' | value; y = 'top' | 'center' | 'bottom' | value; named values are relative to body\n                rectangle:\n                    size: [0.25, 0.5] # centered around reference_point\n                    # start: [-0.25, -0.25] #releative to reference_point\n                    # end: [0.25, 0.25] #relative to reference_point\n                repeat:\n                    spacing: ['pitch', 0] # x,y= 'pitch' | value\n                    reference_is: 'center' # 'center' | 'first' | 'last'\n                    count: 'pincount' # 'pincount' | value\n\n    PicoClasp_side_entry:\n        series: 'Pico-Clasp'\n        mpn_format_string: '202396-{pincount:02d}07'\n        orientation: 'H'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/2023960207_sd.pdf'\n        pinrange: ['range', [2,16]]\n        text_inside_pos: 'bottom'\n        pitch: 1\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.2, 1.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 0.7\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 5.55\n        rel_pad_y_inside_edge: 4.05\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0.7\n        body_size_y: 5.35\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 1.5\n\n    PicoLock_side_entry:\n        series: 'Pico-Lock'\n        mpn_format_string: '504050-{pincount:02d}91'\n        orientation: 'H'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/5040500891_sd.pdf'\n        pinrange: ['list', [4,5,6,7,8,10,12]]\n        text_inside_pos: 'center'\n        pitch: 1.5\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.25, 1.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.98\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 6.59\n        rel_pad_y_inside_edge: 5.59\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0.02\n        body_size_y: 6.1\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 2.625\n        edge_modifier_mount_pad_side:\n            depth: 2 # > 0: cutout, < 0: protrusion\n            #width_start: 4.5\n            start_from_body_side: 1.95\n            #width_end: 4.5\n            end_from_body_side: 1.95\n\n    CLIKmate_top_entry:\n        series: 'CLIK-Mate'\n        mpn_format_string: '502382-{pincount:02d}70'\n        orientation: 'V'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/5023820270_sd.pdf'\n        pinrange: ['range', [2,16]]\n        text_inside_pos: 'center'\n        pitch: 1.25\n        pad1_position: 'bottom-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1, 2.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.35\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 5.6\n        rel_pad_y_inside_edge: 3.9\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0.7\n        body_size_y: 5.45\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 2.3\n\n    CLIKmate_top_entry_15:\n        series: 'CLIK-Mate'\n        mpn_format_string: '505405-{pincount:02d}70'\n        orientation: 'V'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/5054050270_sd.pdf'\n        pinrange: ['range', [2,16]]\n        text_inside_pos: 'center'\n        pitch: 1.5\n        pad1_position: 'bottom-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.8, 3.3]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.7\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 7.9\n        rel_pad_y_inside_edge: 5.5\n        pad_size_x: 0.8\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0.27\n        body_size_y: 6.35\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 2.9\n\n    CLIKmate_top_entry_20:\n        series: 'CLIK-Mate'\n        mpn_format_string: '502443-{pincount:02d}70'\n        orientation: 'V'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/5024430270_sd.pdf'\n        pinrange: ['list', [2,3,4,5,6,7,8,9,12,13,14,15]]\n        text_inside_pos: 'center'\n        pitch: 2.0\n        pad1_position: 'bottom-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.8, 3.6]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.45\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 7.9\n        rel_pad_y_inside_edge: 5.0\n        pad_size_x: 1.0\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: 0.45\n        body_size_y: 6.85\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 3.0\n\n    CLIKmate_side_entry:\n        series: 'CLIK-Mate'\n        mpn_format_string: '502386-{pincount:02d}70'\n        orientation: 'H'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/5023860270_sd.pdf'\n        pinrange: ['range', [2,16]]\n        text_inside_pos: 'center'\n        pitch: 1.25\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1, 2.7]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.35\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 5.4\n        rel_pad_y_inside_edge: 3.7\n        pad_size_x: 0.6\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -1.35\n        body_size_y: 3.15\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 2.3\n        edge_modifier_mount_pad_side:\n            depth: -1.25 # > 0: cutout, < 0: protrusion\n            #width_start: 4.5\n            start_from_body_side: 0.33\n            #width_end: 4.5\n            end_from_body_side: 0.33\n\n    CLIKmate_side_entry_15:\n        series: 'CLIK-Mate'\n        mpn_format_string: '502585-{pincount:02d}70'\n        orientation: 'H'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/5025850270_sd.pdf'\n        pinrange: ['range', [2,16]]\n        text_inside_pos: 'center'\n        pitch: 1.5\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.8, 3.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.7\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 8.05\n        rel_pad_y_inside_edge: 5.15\n        pad_size_x: 0.8\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -1.35\n        body_size_y: 4.35\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 2.9\n        edge_modifier_mount_pad_side:\n            depth: -2.6 # > 0: cutout, < 0: protrusion\n            start_from_body_side: 0.33\n            end_from_body_side: 0.33\n\n    CLIKmate_side_entry_20:\n        series: 'CLIK-Mate'\n        mpn_format_string: '502494-{pincount:02d}70'\n        orientation: 'H'\n        datasheet: 'http://www.molex.com/pdm_docs/sd/5024940270_sd.pdf'\n        pinrange: ['list', [2,3,4,6,8,10,12,13,14,15]]\n        text_inside_pos: 'center'\n        pitch: 2.0\n        pad1_position: 'top-left' # 'top-left' | 'bottom-left' -> pin 2 always to the right of pin 1\n        mounting_pad_size: [1.8, 3.8]\n        # x position mounting inner mounting pad edge relative to nearest pad center\n        center_pad_to_mounting_pad_edge: 1.45\n        # y dimensions for pad given relative to mounting pad edge\n        rel_pad_y_outside_edge: 7.7\n        rel_pad_y_inside_edge: 5.0\n        pad_size_x: 1.0\n        # y position for body edge relative to mounting pad edge (positive -> body extends outside bounding box)\n        rel_body_edge_y: -1.3\n        body_size_y: 4.35\n        # body_fin_protrusion: 1.6\n        # body_fin_width: 0.8\n        # x body edge relative to nearest pin\n        rel_body_edge_x: 3.0\n        edge_modifier_mount_pad_side:\n            depth: -2.6 # > 0: cutout, < 0: protrusion\n            start_from_body_side: 0.33\n            end_from_body_side: 0.33\n"
  },
  {
    "path": "scripts/Connector/Connector_SMD_single_row_plus_mounting_pad/helpers.py",
    "content": "\nfrom KicadModTree import *\n\ndef roundToBase(value, base):\n    return round(value/base) * base\n\ndef parseAdditionalDrawing(footprint, drawing_definition, configuration, series_definition, body_edges, pincount):\n    ref = drawing_definition.get('reference_point', ['center','center']).copy()\n\n    if ref[0] == 'left':\n        ref[0] = body_edges['left']\n    elif ref[0] == 'center':\n        ref[0] = (body_edges['left'] + body_edges['right'])/2\n    elif ref[0] == 'right':\n        ref[0] = body_edges['right']\n\n    if ref[1] == 'top':\n        ref[1] = body_edges['top']\n    elif ref[1] == 'center':\n        ref[1] = (body_edges['top'] + body_edges['bottom'])/2\n    elif ref[1] == 'bottom':\n        ref[1] = body_edges['bottom']\n\n    if 'rectangle' in drawing_definition:\n        if 'size' in drawing_definition['rectangle']:\n            size = drawing_definition['rectangle']['size']\n            start = [ref[0] - size[0]/2, ref[1] - size[1]/2]\n            end = [ref[0] + size[0]/2, ref[1] + size[1]/2]\n        elif 'start' in drawing_definition['rectangle'] and 'end' in drawing_definition['rectangle']:\n            start = drawing_definition['rectangle']['start']\n            start = [ref[0] + start[0], ref[1] + start[1]]\n            end = drawing_definition['rectangle']['end']\n            end = [ref[0] + end[0], ref[1] + end[1]]\n        else:\n            print('rectangle without size size defintion found. Ignored')\n            return\n    elif 'polygone' in drawing_definition:\n        # ToDo: implement\n        polygone = []\n        for point in drawing_definition['polygone']:\n            polygone.append({'x':ref[0]+point[0], 'y':ref[1]+point[1]})\n    else:\n        # not implemented.\n        return\n    #print(polygone)\n\n    layer=drawing_definition.get('layer', 'F.Fab')\n    if 'thickness' in drawing_definition:\n        thickness = drawing_definition['thickness']\n    elif 'Fab' in layer:\n        thickness = configuration['fab_line_width']\n    elif 'SilkS' in layer:\n        thickness = configuration['silk_line_width']\n    else:\n        print('drawing not on silk or fab but no line thickness given.')\n        return\n\n    if 'repeat' in drawing_definition:\n        repeat_def = drawing_definition['repeat']\n        spacing = repeat_def['spacing']\n        if spacing[0] == 'pitch':\n            spacing[0] = series_definition['pitch']\n        if spacing[1] == 'pitch':\n            spacing[1] = series_definition['pitch']\n\n        count = repeat_def['count']\n        if count == 'pincount':\n            count = pincount\n\n        first = ref.copy()\n        if repeat_def['reference_is'] == 'last':\n            first[0] = (count-1)*spacing[0]\n            first[1] = (count-1)*spacing[1]\n            spacing[0] *= -1\n            spacing[1] *= -1\n\n        elif repeat_def['reference_is'] == 'center':\n            first[0] = -(count-1)*spacing[0]/2\n            first[1] = -(count-1)*spacing[1]/2\n\n\n        for i in range(count):\n            translation = Translation(first[0]+i*spacing[0], first[1]+i*spacing[1])\n            if 'rectangle' in drawing_definition:\n                translation.append(RectLine(start=start, end=end, layer=layer, width=thickness))\n            elif 'polygone' in drawing_definition:\n                translation.append(PolygoneLine(polygone=polygone, layer=layer, width=thickness))\n            footprint.append(translation)\n\n    else:\n        if 'rectangle' in drawing_definition:\n            footprint.append(RectLine(start=start, end=end, layer=layer, width=thickness))\n        elif 'polygone' in drawing_definition:\n            #print(polygone)\n            footprint.append(PolygoneLine(polygone=polygone, layer=layer, width=thickness))\n"
  },
  {
    "path": "scripts/Connector/Connector_SMD_single_row_plus_mounting_pad/smd_single_row_plus_mounting_pad.py",
    "content": "#!/usr/bin/env python3\n\n# Generator for jst smd connectors (single row with two mounting pads)\n\nimport sys\nimport os\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\nfrom math import sqrt\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\ndef generate_one_footprint(idx, pincount, series_definition, configuration, group_definition):\n    if 'mpn_param_1' in series_definition:\n        mpn_param_1 = series_definition['mpn_param_1']\n        mpn = series_definition['mpn_format_string'].format(pincount=pincount, param_1=mpn_param_1[idx])\n    else:\n        mpn = series_definition['mpn_format_string'].format(pincount=pincount)\n\n    pins_toward_bottom = series_definition['pad1_position'] == 'bottom-left'\n    needs_additional_silk_pin1_marker = False\n\n    pad_size = [series_definition['pad_size_x'],\n        series_definition['rel_pad_y_outside_edge'] - series_definition['rel_pad_y_inside_edge']]\n    pad_pos_y = -series_definition['rel_pad_y_outside_edge']/2 + pad_size[1]/2\n\n    mounting_pad_size = series_definition['mounting_pad_size']\n    mount_pad_y_pos = series_definition['rel_pad_y_outside_edge']/2 - mounting_pad_size[1]/2\n    if 'center_shift_y' in series_definition:\n        mount_pad_y_pos -= series_definition['center_shift_y']\n        pad_pos_y -= series_definition['center_shift_y']\n    mount_pad_center_x_to_pin = series_definition['center_pad_to_mounting_pad_edge'] + mounting_pad_size[0]/2.0\n\n    # center pin 1 to center pin n\n    dimension_A = (pincount-1)*series_definition['pitch']\n\n    body_edge = {}\n    if pins_toward_bottom:\n        pad_pos_y *= -1\n        mount_pad_y_pos *= -1\n        mount_pad_edge_y_outside = mount_pad_y_pos - mounting_pad_size[1]/2\n        body_edge['top'] = mount_pad_edge_y_outside - series_definition['rel_body_edge_y']\n        body_edge['bottom'] = body_edge['top'] + series_definition['body_size_y']\n    else:\n        mount_pad_edge_y_outside = mount_pad_y_pos + mounting_pad_size[1]/2\n        body_edge['bottom'] = mount_pad_edge_y_outside + series_definition['rel_body_edge_y']\n        body_edge['top'] = body_edge['bottom'] - series_definition['body_size_y']\n\n    body_edge['right'] = dimension_A/2 + series_definition['rel_body_edge_x']\n    body_edge['left'] = -body_edge['right']\n\n    orientation = configuration['orientation_options'][series_definition['orientation']]\n    footprint_name = configuration['fp_name_format_string'].format(man=group_definition['manufacturer'],\n        series=series_definition['series'],\n        mpn=mpn, num_rows=1, pins_per_row=pincount, mounting_pad = \"-1MP\",\n        pitch=series_definition['pitch'], orientation=orientation)\n    footprint_name = footprint_name.replace('__', '_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"{:s} {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(group_definition['manufacturer'],\n        series_definition['series'], mpn, series_definition['datasheet']))\n    kicad_mod.setAttribute('smd')\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series_definition['series'],\n        orientation=orientation, man=group_definition['manufacturer'],\n        entry=configuration['entry_direction'][series_definition['orientation']]))\n\n\n    ############################# Pads ##################################\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        pad_shape=Pad.SHAPE_RECT\n    else:\n        pad_shape=Pad.SHAPE_ROUNDRECT\n        optional_pad_params['radius_ratio'] = configuration.get('radius_ratio', 0.25)\n        optional_pad_params['maximum_radius'] = configuration.get('maximum_radius', 0.25)\n\n    kicad_mod.append(PadArray(\n        center=[0, pad_pos_y], x_spacing=series_definition['pitch'], pincount=pincount,\n        size=pad_size, type=Pad.TYPE_SMT, shape=pad_shape, layers=Pad.LAYERS_SMT,\n        **optional_pad_params))\n\n    mount_pad_left_x_pos = -dimension_A/2 - mount_pad_center_x_to_pin\n    kicad_mod.append(Pad(\n        number = configuration['mounting_pad_number'], type=Pad.TYPE_SMT,\n        shape=pad_shape, at=[mount_pad_left_x_pos, mount_pad_y_pos],\n        size=mounting_pad_size, layers=Pad.LAYERS_SMT,\n        **optional_pad_params))\n    kicad_mod.append(Pad(\n        number = configuration['mounting_pad_number'], type=Pad.TYPE_SMT,\n        shape=pad_shape, at=[-mount_pad_left_x_pos, mount_pad_y_pos],\n        size=mounting_pad_size, layers=Pad.LAYERS_SMT,\n        **optional_pad_params))\n\n    ######################### Body outline ###############################\n    pad_edge_silk_center_offset = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    pad_1_x_outside_edge = -dimension_A/2 - pad_size[0]/2\n\n    if pins_toward_bottom: #Man i wish there where a rotate footprint function available.\n        body_edge_pin = body_edge['bottom']\n        body_edge_mount_pad = body_edge['top']\n        silk_y_mp_pin_side = mount_pad_y_pos + mounting_pad_size[1]/2 + pad_edge_silk_center_offset\n        mp_edge_outside = mount_pad_y_pos - mounting_pad_size[1]/2\n        silk_y_mp_outside = mp_edge_outside - pad_edge_silk_center_offset\n        pin_edge_outside = pad_pos_y + pad_size[1]/2\n        silk_y_offset_pin_side = configuration['silk_fab_offset']\n    else:\n        body_edge_pin = body_edge['top']\n        body_edge_mount_pad = body_edge['bottom']\n        silk_y_mp_pin_side = mount_pad_y_pos - mounting_pad_size[1]/2 - pad_edge_silk_center_offset\n        mp_edge_outside = mount_pad_y_pos + mounting_pad_size[1]/2\n        silk_y_mp_outside = mp_edge_outside + pad_edge_silk_center_offset\n        pin_edge_outside = pad_pos_y - pad_size[1]/2\n        silk_y_offset_pin_side = -configuration['silk_fab_offset']\n\n\n    # Pin side\n    bounding_box_y_pin_side = pad_pos_y + (pad_size[1]/2 if pins_toward_bottom else -pad_size[1]/2)\n    side_line_y_pin_side = body_edge_pin\n    mp_inner_edge_x_left_silk = mount_pad_left_x_pos + mounting_pad_size[0]/2 + pad_edge_silk_center_offset\n    modified_pinside_x_inner = body_edge['left']\n    if 'edge_modifier_pin_side' in series_definition:\n        modifier = series_definition['edge_modifier_pin_side']\n        modified_pinside_x_inner = body_edge['left'] + modifier['width']\n\n        if pins_toward_bottom:\n            side_line_y_pin_side += modifier['length']\n            if side_line_y_pin_side > bounding_box_y_pin_side:\n                bounding_box_y_pin_side = side_line_y_pin_side\n        else:\n            side_line_y_pin_side -= modifier['length']\n            if side_line_y_pin_side < bounding_box_y_pin_side:\n                bounding_box_y_pin_side = side_line_y_pin_side\n\n        poly_fab_pin_side=[\n            {'x': body_edge['left'], 'y': side_line_y_pin_side},\n            {'x': modified_pinside_x_inner, 'y': side_line_y_pin_side},\n            {'x': modified_pinside_x_inner, 'y': body_edge_pin},\n            {'x': -modified_pinside_x_inner, 'y': body_edge_pin},\n            {'x': -modified_pinside_x_inner, 'y': side_line_y_pin_side},\n            {'x': body_edge['right'], 'y': side_line_y_pin_side}\n        ]\n\n        if modifier['length'] < 0:\n            silk_x_offset = -configuration['silk_fab_offset']\n        else:\n            silk_x_offset = configuration['silk_fab_offset']\n\n        if modified_pinside_x_inner + silk_x_offset > pad_1_x_outside_edge - pad_edge_silk_center_offset:\n            poly_silk_edge_left = [\n                {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': silk_y_mp_pin_side},\n                {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': side_line_y_pin_side + silk_y_offset_pin_side},\n                {'x': pad_1_x_outside_edge - pad_edge_silk_center_offset, 'y': side_line_y_pin_side + silk_y_offset_pin_side},\n                {'x': pad_1_x_outside_edge - pad_edge_silk_center_offset, 'y': pin_edge_outside}\n            ]\n            if abs(pin_edge_outside) - abs(side_line_y_pin_side + silk_y_offset_pin_side) < configuration['silk_line_lenght_min']:\n                needs_additional_silk_pin1_marker = True\n\n            poly_silk_edge_right = [\n                {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': silk_y_mp_pin_side},\n                {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': side_line_y_pin_side + silk_y_offset_pin_side},\n                {'x': -pad_1_x_outside_edge + pad_edge_silk_center_offset, 'y': side_line_y_pin_side + silk_y_offset_pin_side}\n            ]\n\n        else:\n            poly_silk_edge_left = [\n                {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': silk_y_mp_pin_side},\n                {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': side_line_y_pin_side + silk_y_offset_pin_side},\n                {'x': modified_pinside_x_inner + silk_x_offset, 'y': side_line_y_pin_side + silk_y_offset_pin_side},\n                {'x': modified_pinside_x_inner + silk_x_offset, 'y': body_edge_pin + silk_y_offset_pin_side},\n                {'x': pad_1_x_outside_edge - pad_edge_silk_center_offset, 'y': body_edge_pin + silk_y_offset_pin_side},\n                {'x': pad_1_x_outside_edge - pad_edge_silk_center_offset, 'y': pin_edge_outside}\n            ]\n            if abs(pin_edge_outside) - abs(body_edge_pin + silk_y_offset_pin_side) < configuration['silk_line_lenght_min']:\n                needs_additional_silk_pin1_marker = True\n\n            poly_silk_edge_right = [\n                {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': silk_y_mp_pin_side},\n                {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': side_line_y_pin_side + silk_y_offset_pin_side},\n                {'x': -modified_pinside_x_inner - silk_x_offset, 'y': side_line_y_pin_side + silk_y_offset_pin_side},\n                {'x': -modified_pinside_x_inner - silk_x_offset, 'y': body_edge_pin + silk_y_offset_pin_side},\n                {'x': -pad_1_x_outside_edge + pad_edge_silk_center_offset, 'y': body_edge_pin + silk_y_offset_pin_side}\n            ]\n    else:\n        poly_fab_pin_side=[\n            {'x': body_edge['left'], 'y': body_edge_pin},\n            {'x': body_edge['right'], 'y': body_edge_pin}\n        ]\n        poly_silk_edge_left = [\n            {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': silk_y_mp_pin_side},\n            {'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': side_line_y_pin_side + silk_y_offset_pin_side},\n            {'x': pad_1_x_outside_edge - pad_edge_silk_center_offset, 'y': body_edge_pin + silk_y_offset_pin_side},\n            {'x': pad_1_x_outside_edge - pad_edge_silk_center_offset, 'y': pin_edge_outside}\n        ]\n        if abs(pin_edge_outside) - abs(body_edge_pin + silk_y_offset_pin_side) < configuration['silk_line_lenght_min']:\n            needs_additional_silk_pin1_marker = True\n\n        poly_silk_edge_right = [\n            {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': silk_y_mp_pin_side},\n            {'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': side_line_y_pin_side + silk_y_offset_pin_side},\n            {'x': -pad_1_x_outside_edge + pad_edge_silk_center_offset, 'y': body_edge_pin + silk_y_offset_pin_side}\n        ]\n    kicad_mod.append(PolygoneLine(polygone=poly_fab_pin_side, layer='F.Fab', width=configuration['fab_line_width']))\n    if series_definition.get('no_automatic_silk_autline','False') != 'True':\n        kicad_mod.append(PolygoneLine(polygone=poly_silk_edge_left, layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=poly_silk_edge_right, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    # Mount pad side\n    bounding_box_y_mount_pad_side = mount_pad_y_pos + (-mounting_pad_size[1]/2 if pins_toward_bottom else mounting_pad_size[1]/2)\n    if abs(bounding_box_y_mount_pad_side) < abs(body_edge_mount_pad):\n        bounding_box_y_mount_pad_side = body_edge_mount_pad\n    mid_line_y_mount_pad_side = body_edge_mount_pad\n    if 'edge_modifier_mount_pad_side' in series_definition:\n        modifier = series_definition['edge_modifier_mount_pad_side']\n\n        if 'width_start' in modifier:\n            modified_mp_start_x_inner = - modifier['width_start']/2 # We assume centered body!\n        if 'start_from_body_side' in modifier:\n            modified_mp_start_x_inner = body_edge['left'] + modifier['start_from_body_side']\n        modified_mp_end_x_inner = modified_mp_start_x_inner\n        if 'width_end' in modifier:\n            modified_mp_end_x_inner = - modifier['width_end']/2 # We assume centered body!\n        if 'end_from_body_side' in modifier:\n            modified_mp_end_x_inner = body_edge['left'] + modifier['end_from_body_side']\n\n        if pins_toward_bottom:\n            mid_line_y_mount_pad_side += modifier['depth']\n            if mid_line_y_mount_pad_side < bounding_box_y_mount_pad_side:\n                bounding_box_y_mount_pad_side = mid_line_y_mount_pad_side\n        else:\n            mid_line_y_mount_pad_side -= modifier['depth']\n            if mid_line_y_mount_pad_side > bounding_box_y_mount_pad_side:\n                bounding_box_y_mount_pad_side = mid_line_y_mount_pad_side\n\n        if modifier['depth'] < 0:\n            silk_x_offset = -configuration['silk_fab_offset']\n        else:\n            silk_x_offset = configuration['silk_fab_offset']\n\n        poly_fab_mp_side=[\n            {'x': body_edge['left'], 'y': body_edge_mount_pad},\n            {'x': modified_mp_start_x_inner, 'y': body_edge_mount_pad},\n            {'x': modified_mp_end_x_inner, 'y': mid_line_y_mount_pad_side},\n            {'x': -modified_mp_end_x_inner, 'y': mid_line_y_mount_pad_side},\n            {'x': -modified_mp_start_x_inner, 'y': body_edge_mount_pad},\n            {'x': body_edge['right'], 'y': body_edge_mount_pad}\n        ]\n\n        poly_silk_mp_side=[\n            {'x': mp_inner_edge_x_left_silk, 'y': body_edge_mount_pad - silk_y_offset_pin_side},\n            {'x': modified_mp_start_x_inner + silk_x_offset, 'y': body_edge_mount_pad - silk_y_offset_pin_side},\n            {'x': modified_mp_end_x_inner + silk_x_offset, 'y': mid_line_y_mount_pad_side - silk_y_offset_pin_side},\n            {'x': -modified_mp_end_x_inner - silk_x_offset, 'y': mid_line_y_mount_pad_side - silk_y_offset_pin_side},\n            {'x': -modified_mp_start_x_inner - silk_x_offset, 'y': body_edge_mount_pad - silk_y_offset_pin_side},\n            {'x': -mp_inner_edge_x_left_silk, 'y': body_edge_mount_pad - silk_y_offset_pin_side}\n        ]\n        if modified_mp_start_x_inner + configuration['silk_fab_offset'] < mp_inner_edge_x_left_silk:\n            poly_silk_mp_side=[\n                {'x': mp_inner_edge_x_left_silk, 'y': mid_line_y_mount_pad_side - silk_y_offset_pin_side},\n                {'x': -mp_inner_edge_x_left_silk, 'y': mid_line_y_mount_pad_side - silk_y_offset_pin_side}\n            ]\n    else:\n        poly_fab_mp_side=[\n            {'x': body_edge['left'], 'y': body_edge_mount_pad},\n            {'x': body_edge['right'], 'y': body_edge_mount_pad}\n        ]\n        poly_silk_mp_side=[\n            {'x': mp_inner_edge_x_left_silk, 'y': body_edge_mount_pad - silk_y_offset_pin_side},\n            {'x': -mp_inner_edge_x_left_silk, 'y': body_edge_mount_pad - silk_y_offset_pin_side}\n        ]\n\n    if series_definition['rel_body_edge_y'] > pad_edge_silk_center_offset:\n        poly_silk_mp_side[0]['x'] = body_edge['left']\n        poly_silk_mp_side[len(poly_silk_mp_side)-1]['x'] = body_edge['right']\n\n    if series_definition['rel_body_edge_y'] > pad_edge_silk_center_offset + configuration['silk_line_lenght_min']:\n        poly_silk_mp_side[0]['x'] = body_edge['left'] - configuration['silk_fab_offset']\n        poly_silk_mp_side[len(poly_silk_mp_side)-1]['x'] = body_edge['right'] + configuration['silk_fab_offset']\n\n        poly_silk_mp_side.insert(0,{'x': body_edge['left'] - configuration['silk_fab_offset'], 'y': silk_y_mp_outside})\n        poly_silk_mp_side.append({'x': body_edge['right'] + configuration['silk_fab_offset'], 'y': silk_y_mp_outside})\n\n    if series_definition.get('no_automatic_silk_autline','False') != 'True':\n        kicad_mod.append(PolygoneLine(polygone=poly_silk_mp_side, layer='F.SilkS', width=configuration['silk_line_width']))\n\n    kicad_mod.append(PolygoneLine(polygone=poly_fab_mp_side, layer='F.Fab', width=configuration['fab_line_width']))\n\n    kicad_mod.append(Line(start=[body_edge['left'], side_line_y_pin_side], end=[body_edge['left'], body_edge_mount_pad],\n                            layer='F.Fab', width=configuration['fab_line_width']))\n\n    kicad_mod.append(Line(start=[body_edge['right'], side_line_y_pin_side], end=[body_edge['right'], body_edge_mount_pad],\n                            layer='F.Fab', width=configuration['fab_line_width']))\n\n    ###################### Additional Drawing ###########################\n    if 'additional_drawing' in series_definition:\n        for drawing in series_definition['additional_drawing']:\n            parseAdditionalDrawing(kicad_mod, drawing, configuration, series_definition, body_edge, pincount)\n\n    ############################# CrtYd ##################################\n    mp_left_edge = mount_pad_left_x_pos - mounting_pad_size[0]/2\n    bounding_box_x1 = body_edge['left'] if body_edge['left'] < mp_left_edge else mp_left_edge\n    bounding_box_x2 = -bounding_box_x1\n    if pins_toward_bottom:\n        bounding_box_y1 = bounding_box_y_mount_pad_side\n        bounding_box_y2 = bounding_box_y_pin_side\n\n    else:\n        bounding_box_y1 = bounding_box_y_pin_side\n        bounding_box_y2 = bounding_box_y_mount_pad_side\n\n\n    cx1 = roundToBase(bounding_box_x1 - configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cx2 = roundToBase(bounding_box_x2 + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cy1 = roundToBase(bounding_box_y1 - configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box_y2 + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Pin 1 marker ##############################\n\n    if series_definition['pad1_position'] == 'bottom-left':\n        poly_pin1_marker = [\n            {'x':-dimension_A/2 - configuration['fab_pin1_marker_length']/2,'y': body_edge['bottom']},\n            {'x':-dimension_A/2,'y': body_edge['bottom'] - configuration['fab_pin1_marker_length']/sqrt(2)},\n            {'x':-dimension_A/2 + configuration['fab_pin1_marker_length']/2,'y': body_edge['bottom']}\n        ]\n        poly_pin1_marker_small = [\n            {'x':-dimension_A/2-configuration['fab_pin1_marker_length']/4,'y': cy2 + configuration['fab_pin1_marker_length']/sqrt(8)},\n            {'x':-dimension_A/2,'y': cy2},\n            {'x':-dimension_A/2+configuration['fab_pin1_marker_length']/4,'y': cy2 + configuration['fab_pin1_marker_length']/sqrt(8)},\n            {'x':-dimension_A/2-configuration['fab_pin1_marker_length']/4,'y': cy2 + configuration['fab_pin1_marker_length']/sqrt(8)}\n        ]\n    else:\n        poly_pin1_marker = [\n            {'x':-dimension_A/2 - configuration['fab_pin1_marker_length']/2,'y': body_edge['top']},\n            {'x':-dimension_A/2,'y': body_edge['top'] + configuration['fab_pin1_marker_length']/sqrt(2)},\n            {'x':-dimension_A/2 + configuration['fab_pin1_marker_length']/2,'y': body_edge['top']}\n        ]\n        poly_pin1_marker_small = [\n            {'x':-dimension_A/2-configuration['fab_pin1_marker_length']/4,'y': cy1 - configuration['fab_pin1_marker_length']/sqrt(8)},\n            {'x':-dimension_A/2,'y': cy1},\n            {'x':-dimension_A/2+configuration['fab_pin1_marker_length']/4,'y': cy1 - configuration['fab_pin1_marker_length']/sqrt(8)},\n            {'x':-dimension_A/2-configuration['fab_pin1_marker_length']/4,'y': cy1 - configuration['fab_pin1_marker_length']/sqrt(8)}\n        ]\n\n    if modified_pinside_x_inner < -dimension_A/2 - configuration['fab_pin1_marker_length']/2:\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.Fab', width=configuration['fab_line_width']))\n    else:\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker_small, layer='F.Fab', width=configuration['fab_line_width']))\n\n    if needs_additional_silk_pin1_marker:\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker_small, layer='F.SilkS', width=configuration['silk_line_width']))\n\n\n    ######################### Text Fields ###############################\n    text_center = series_definition.get('text_inside_pos', 'center')\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position=text_center)\n\n    ########################### file names ###############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(man=group_definition['manufacturer'],\n        series=series_definition['series'])\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\ndef generate_series(configuration, series_definition, id, group_definition):\n    idx = 0\n    pinrange_def_type, pinrange_def = series_definition['pinrange']\n    if pinrange_def_type == 'range':\n        pinrange = range(*pinrange_def)\n    elif pinrange_def_type == 'list':\n        pinrange = pinrange_def\n    else:\n        print(\"Pinrange definition error in part {:s}\".format(id))\n        return\n\n    for pincount in pinrange:\n        generate_one_footprint(idx, pincount, series_definition, configuration, group_definition)\n        idx += 1\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('files', metavar='file', type=str, nargs='+',\n                        help='list of files holding information about what devices should be created.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for filepath in args.files:\n        with open(filepath, 'r') as stream:\n            try:\n                yaml_file = yaml.safe_load(stream)\n            except yaml.YAMLError as exc:\n                print(exc)\n        series_definitions = yaml_file['device_definition']\n        for series_definition_id in series_definitions:\n            generate_series(configuration,\n                series_definitions[series_definition_id], series_definition_id,\n                yaml_file['group_definitions'])\n"
  },
  {
    "path": "scripts/Connector/Connector_Samtec/conn_samtec_LSHM_smd_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"\"\nseries_long = 'LSHM 0.50 mm Razor Beam High-Speed Hermaphroditic Terminal/Socket Strip'\nmanufacturer = 'Samtec'\norientation = 'V'\nnumber_of_rows = 2\ndatasheet = 'http://suddendocs.samtec.com/prints/lshm-1xx-xx.x-x-dv-a-x-x-tr-footprint.pdf'\n\n#pins_per_row per row\npins_per_row_range = [5,10,20,30,40,50]\n\n#Molex part number\n#n = number of circuits per row\npart_code = \"LSHM-1{n:02d}-xx.x-x-DV-{shield:s}\"\n\nvariant_params = {\n    'shileded': {\n        'mpn_option': 'S',\n        'shield_pad': True,\n    },\n    'plain': {\n        'mpn_option': 'N',\n        'shield_pad': False,\n    }\n}\n\npitch = 0.5\n\npad_size = [0.3, 1.5]\nboss_drill = 1.45\n\nshield_pad_drill = 1\nshield_pad_size = 1.5\n\npin_number_shield = \"SH\"\n\ndef generate_one_footprint(pins_per_row, params, configuration):\n    mpn = part_code.format(n=pins_per_row, shield=params['mpn_option'])\n\n    CrtYd_off = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n    off = configuration['silk_fab_offset']\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    body_edge = {}\n    bounding_box = {}\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    if params['shield_pad']:\n        footprint_name = configuration['fp_name_format_string_shielded'].format(man=manufacturer,\n            series=series,\n            mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row,\n            pitch=pitch, orientation=orientation_str, shield_pins=1)\n    else:\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    footprint_name = footprint_name.replace('__','_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setAttribute('smd')\n    kicad_mod.setDescription(\"Molex {:s}, {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\".format(series_long, mpn, pins_per_row, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    A = (pins_per_row-1)*pitch\n    B = A + 2.5\n    C = A + 5.45\n    D = A + 6.75\n    E = A + 5.2\n\n    pad_to_pad_inside = 1.95+0.25\n    pad_y = (pad_to_pad_inside + pad_size[1])/2\n\n    boss_x = B/2\n    boss_y = -pad_y + pad_size[1]/2 + 0.25\n\n    shield_pad_x = C/2\n    shield_pad_y = boss_y + 2\n\n    body_chamfer = 0.3\n\n\n    body_edge['left'] = -D/2 if params['shield_pad'] else -E/2\n    body_edge['right'] = -body_edge['left']\n    body_edge['top'] = -4.98/2\n    body_edge['bottom'] = -body_edge['top']\n\n    bounding_box['left'] = (-shield_pad_x - shield_pad_size/2) if params['shield_pad'] else body_edge['left']\n    bounding_box['right'] = -bounding_box['left']\n    bounding_box['top'] = -pad_y - pad_size[1]/2\n    bounding_box['bottom'] = -bounding_box['top']\n\n\n    ################################ Pads #####################################\n\n    kicad_mod.append(PadArray(initial=1, increment=2,\n        center=[0, -pad_y], x_spacing=pitch, pincount=pins_per_row,\n        size=pad_size, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=Pad.LAYERS_SMT))\n    kicad_mod.append(PadArray(initial=2, increment=2,\n        center=[0, pad_y], x_spacing=pitch, pincount=pins_per_row,\n        size=pad_size, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, layers=Pad.LAYERS_SMT))\n\n    kicad_mod.append(Pad(number ='\"\"', type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n                        at=[boss_x, boss_y],\n                        size=boss_drill, drill=boss_drill,\n                        layers=Pad.LAYERS_NPTH))\n    kicad_mod.append(Pad(number ='\"\"', type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n                        at=[-boss_x, boss_y],\n                        size=boss_drill, drill=boss_drill,\n                        layers=Pad.LAYERS_NPTH))\n\n    if params['shield_pad']:\n        kicad_mod.append(Pad(number = pin_number_shield,\n                            type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n                            at=[shield_pad_x, shield_pad_y],\n                            size=shield_pad_size, drill=shield_pad_drill,\n                            layers=Pad.LAYERS_THT))\n        kicad_mod.append(Pad(number = pin_number_shield,\n                            type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n                            at=[-shield_pad_x, shield_pad_y],\n                            size=shield_pad_size, drill=shield_pad_drill,\n                            layers=Pad.LAYERS_THT))\n\n    ########################### Outline ################################\n    poly_fab = [\n        {'x': 0, 'y': body_edge['top']},\n        {'x': body_edge['left']+body_chamfer, 'y': body_edge['top']},\n        {'x': body_edge['left'], 'y': body_edge['top']+body_chamfer},\n        {'x': body_edge['left'], 'y': body_edge['bottom']-body_chamfer},\n        {'x': body_edge['left']+body_chamfer, 'y': body_edge['bottom']},\n        {'x': 0, 'y': body_edge['bottom']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_fab,\n        layer='F.Fab', width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=poly_fab, x_mirror=0,\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    pad_x_outside_edge = A/2 + pad_size[0]/2 + pad_silk_off\n    if not params['shield_pad']:\n        poly_silk = [\n            {'x': -pad_x_outside_edge, 'y': body_edge['top']-off},\n            {'x': body_edge['left']+body_chamfer-off, 'y': body_edge['top']-off},\n            {'x': body_edge['left']-off, 'y': body_edge['top']+body_chamfer-off},\n            {'x': body_edge['left']-off, 'y': body_edge['bottom']-body_chamfer+off},\n            {'x': body_edge['left']+body_chamfer-off, 'y': body_edge['bottom']+off},\n            {'x': -pad_x_outside_edge, 'y': body_edge['bottom']+off}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_silk,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=poly_silk, x_mirror=0,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    else:\n        r = (shield_pad_size/2 + pad_silk_off)\n        x = (D-C)/2\n        dy = sqrt(r**2 - x**2)\n        poly_silk_top = [\n            {'x': -pad_x_outside_edge, 'y': body_edge['top']-off},\n            {'x': body_edge['left']+body_chamfer-off, 'y': body_edge['top']-off},\n            {'x': body_edge['left']-off, 'y': body_edge['top']+body_chamfer-off},\n            {'x': body_edge['left']-off, 'y': shield_pad_y-dy},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_silk_top,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=poly_silk_top, x_mirror=0,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n        poly_silk_bottom = [\n            {'x': body_edge['left']-off, 'y': shield_pad_y+dy},\n            {'x': body_edge['left']-off, 'y': body_edge['bottom']-body_chamfer+off},\n            {'x': body_edge['left']+body_chamfer-off, 'y': body_edge['bottom']+off},\n            {'x': -pad_x_outside_edge, 'y': body_edge['bottom']+off}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_silk_bottom,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        kicad_mod.append(PolygoneLine(polygone=poly_silk_bottom, x_mirror=0,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ########################### Pin 1 #################################\n    p1s_sl = 0.4\n    p1s_y = -pad_y - pad_size[1]/2 - pad_silk_off\n    p1_x = -A/2\n    p1s_poly = [\n        {'x': p1_x, 'y':p1s_y},\n        {'x': p1_x-p1s_sl/2, 'y':p1s_y-p1s_sl/sqrt(2)},\n        {'x': p1_x+p1s_sl/2, 'y':p1s_y-p1s_sl/sqrt(2)},\n        {'x': p1_x, 'y':p1s_y}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=p1s_poly,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    p1f_sl = 2*pitch\n    p1f_poly = [\n        {'x': p1_x-p1f_sl/2, 'y':body_edge['top']},\n        {'x': p1_x, 'y':body_edge['top']+p1f_sl/sqrt(2)},\n        {'x': p1_x+p1f_sl/2, 'y':body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=p1f_poly,\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2},\n        fp_name=footprint_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n    for variant in variant_params:\n        for pins_per_row in pins_per_row_range:\n            generate_one_footprint(pins_per_row, variant_params[variant], configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Samtec/conn_samtec_hle.py",
    "content": "#!/usr/bin/env python\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = 'HLE'\nseries_long = 'HLE .100\" Tiger Beam Cost-effective Single Beam Socket Strip'\nmanufacturer = 'Samtec'\norientation = 'H'\nnumber_of_rows = 2\npitch = 2.54\n\ndatasheet_tht = 'http://suddendocs.samtec.com/prints/hle-1xx-02-xx-dv-xe-xx-mkt.pdf'\ndatasheet_smd = 'http://suddendocs.samtec.com/prints/hle-1xx-02-xxx-dv-xx-xx-xx-mkt.pdf'\nfootprint_tht = 'http://suddendocs.samtec.com/prints/hle-thru.pdf'\nfootprint_smd = 'http://suddendocs.samtec.com/prints/hle-dv-footprint.pdf'\n\n# BE = Bottem Enty\n# TE = Top Entry\n# PE = Pass Through Entry\n\ndrill = 0.71\npe_npth_drill = 1.4\nbe_npth_drill = 0.97\nlc_npth_drill = 1.19\na_npth_drill = 1.78\n\npad_size_smd = [1.27, 2.29]\npad_size_smd_be = [1.27, 1.68]\npad_pitch_y_smd = 5.05\npad_pitch_y_smd_be = 5.44\npad_pitch_y_pe = 7.62\n\npad_to_pad_clearance = 1.2\nmax_annular_ring = 0.3\nmin_annular_ring = 0.15\n\nvariant_params = {\n    'smd-be-a': {\n        'smd': True,\n        'pins_per_row_range': range(4,51),\n        'npth_drill': be_npth_drill,\n        'peg_drill': a_npth_drill,\n        'pad_size': pad_size_smd_be,\n        'pad_pitch_y': pad_pitch_y_smd_be,\n        'datasheets': [datasheet_smd, footprint_smd],\n        'part_code': \"HLE-1{n:02}-02-xxx-DV-BE-A\",\n        },\n    'smd-be-lc': {\n        'smd': True,\n        'pins_per_row_range': range(2,51),\n        'npth_drill': be_npth_drill,\n        'peg_drill': lc_npth_drill,\n        'pad_size': pad_size_smd_be,\n        'pad_pitch_y': pad_pitch_y_smd_be,\n        'datasheets': [datasheet_smd, footprint_smd],\n        'part_code': \"HLE-1{n:02}-02-xxx-DV-BE-LC\",\n        },\n    'smd-be': {\n        'smd': True,\n        'pins_per_row_range': range(2,51),\n        'npth_drill': be_npth_drill,\n        'pad_size': pad_size_smd_be,\n        'pad_pitch_y': pad_pitch_y_smd_be,\n        'datasheets': [datasheet_smd, footprint_smd],\n        'part_code': \"HLE-1{n:02}-02-xxx-DV-BE\",\n        },\n    'smd-a': {\n        'smd': True,\n        'pins_per_row_range': range(4,51),\n        'peg_drill': a_npth_drill,\n        'pad_size': pad_size_smd,\n        'pad_pitch_y': pad_pitch_y_smd,\n        'datasheets': [datasheet_smd, footprint_smd],\n        'part_code': \"HLE-1{n:02}-02-xxx-DV-A\",\n        },\n    'smd-lc': {\n        'smd': True,\n        'pins_per_row_range': range(2,51),\n        'peg_drill': lc_npth_drill,\n        'pad_size': pad_size_smd,\n        'pad_pitch_y': pad_pitch_y_smd,\n        'datasheets': [datasheet_smd, footprint_smd],\n        'part_code': \"HLE-1{n:02}-02-xxx-DV-LC\",\n        },\n    'smd': {\n        'smd': True,\n        'pins_per_row_range': range(2,51),\n        'pad_size': pad_size_smd,\n        'pad_pitch_y': pad_pitch_y_smd,\n        'datasheets': [datasheet_smd, footprint_smd],\n        'part_code': \"HLE-1{n:02}-02-xxx-DV\",\n        },\n    'tht-te': {\n        'pins_per_row_range': range(4,51),\n        'pad_drill': drill,\n        'datasheets': [datasheet_tht, footprint_tht],\n        'part_code': \"HLE-1{n:02}-02-xx-DV-TE\",\n        },\n    'tht-pe': {\n        'pins_per_row_range': range(4,51),\n        'npth_drill': pe_npth_drill,\n        'pad_drill': drill,\n        'pad_pitch_y': pad_pitch_y_pe,\n        'datasheets': [datasheet_tht, footprint_tht],\n        'part_code': \"HLE-1{n:02}-02-xx-DV-PE\",\n        'alternative_codes': [\n            \"HLE-1{n:02}-02-xx-DV-PE-BE\"\n            ],\n        },\n    'tht-pe-lc': {\n        'pins_per_row_range': range(4,51),\n        'npth_drill': pe_npth_drill,\n        'peg_drill': lc_npth_drill,\n        'pad_drill': drill,\n        'pad_pitch_y': pad_pitch_y_pe,\n        'datasheets': [datasheet_tht, footprint_tht],\n        'part_code': \"HLE-1{n:02}-02-xx-DV-PE-LC\",\n        },\n}\n\ndef generate_one_footprint(pins_per_row, variant, configuration):\n    is_smd = variant_params[variant].get('smd', False)\n\n    mpn = variant_params[variant]['part_code'].format(n=pins_per_row)\n    alt_mpn = [code.format(n=pins_per_row) for code in variant_params[variant].get('alternative_codes', [])]\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(\n        man=manufacturer,\n        series='',\n        mpn=mpn,\n        num_rows=number_of_rows,\n        pins_per_row=pins_per_row,\n        pitch=pitch,\n        mounting_pad = \"\",\n        orientation=orientation_str)\n    footprint_name = footprint_name.replace('__','_')\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"{manufacturer} {series}, {mpn}{alt_mpn}, {pins_per_row} Pins per row ({datasheet}), generated with kicad-footprint-generator\".format(\n        manufacturer = manufacturer,\n        series = series_long,\n        mpn = mpn,\n        alt_mpn = ' (compatible alternatives: {})'.format(', '.join(alt_mpn)) if len(alt_mpn) > 0 else \"\",\n        pins_per_row = pins_per_row,\n        datasheet = ', '.join(variant_params[variant]['datasheets'])))\n\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    if is_smd:\n        kicad_mod.setAttribute('smd')\n\n    ########################## Dimensions ##############################\n\n    # Solder pads pitch\n    pad_pitch_x = pitch\n    pad_pitch_y = variant_params[variant].get('pad_pitch_y', pitch)\n\n    # Size of the connector (without pins)\n    size_x = pins_per_row * pitch\n    size_y = 5.08\n\n    # Offset everything\n    if is_smd:\n        offset_x = -size_x/2 + pitch/2\n        offset_y = -size_y/2 + pitch/2\n    else:\n        offset_x = 0\n        offset_y = (pad_pitch_y - pitch)/2\n\n    # Position of connector pins. This is either used for npth holes at pin position or for tht pads\n    pin_row1_y = offset_y + 0\n    pin_row2_y = pin_row1_y + pitch\n    pin1_x = offset_x + 0\n\n    if is_smd:\n        pad1_x = pin1_x\n        pad_row1_y = offset_y + pitch/2 - pad_pitch_y/2\n        pad_row2_y = pad_row1_y + pad_pitch_y\n        pad_size = variant_params[variant].get('pad_size', None)\n        pad_shape = Pad.SHAPE_RECT\n        pad1_shape = pad_shape\n        pad_layer = Pad.LAYERS_SMT\n        pad_type = Pad.TYPE_SMT\n        pad_drill = None\n    else:\n        # By definition pad1 needs to be at 0,0 for THT\n        pad1_x = 0\n        pad_row1_y = 0\n        pad_row2_y = pad_row1_y + pad_pitch_y\n        pad_layer = Pad.LAYERS_THT\n        pad_drill = variant_params[variant].get('pad_drill', None)\n        pad_type = Pad.TYPE_THT\n\n        pad_size = [pitch - pad_to_pad_clearance, pad_drill + 2*max_annular_ring]\n        if pad_size[0] - pad_drill < 2*min_annular_ring:\n            pad_size[0] = pad_drill + 2*min_annular_ring\n        if pad_size[0] - pad_drill > 2*max_annular_ring:\n            pad_size[0] = pad_drill + 2*max_annular_ring\n\n        if pad_size[1] - pad_drill < 2*min_annular_ring:\n            pad_size[1] = pad_drill + 2*min_annular_ring\n        if pad_size[1] - pad_drill > 2*max_annular_ring:\n            pad_size[1] = pad_drill + 2*max_annular_ring\n\n        pad_shape=Pad.SHAPE_OVAL\n        if pad_size[1] == pad_size[0]:\n            pad_shape=Pad.SHAPE_CIRCLE\n\n    peg1_x = offset_x + pitch/2\n    peg2_x = offset_x - pitch/2 + size_x - pitch\n    peg_y = offset_y + pitch/2\n\n    body_edge={\n        'left': offset_x - pitch/2,\n        'right': offset_x + size_x - pitch/2,\n        'top': offset_y - pitch/2,\n        'bottom': offset_y + size_y - pitch/2,\n        }\n\n    bounding_box={\n        'left': body_edge['left'],\n        'right': body_edge['right'],\n        'top': min(pad_row1_y - pad_size[1]/2, body_edge['top']),\n        'bottom': max(pad_row2_y + pad_size[1]/2, body_edge['bottom']),\n        }\n\n    # ############################# Pads ##################################\n\n    # Pegs\n    peg_drill = variant_params[variant].get('peg_drill', None)\n    if peg_drill != None:\n        kicad_mod.append(Pad(at=[peg1_x, peg_y], number=\"\",\n            type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n            drill=peg_drill, layers=Pad.LAYERS_NPTH))\n        if (peg1_x != peg2_x):\n            kicad_mod.append(Pad(at=[peg2_x, peg_y], number=\"\",\n                type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=peg_drill,\n                drill=peg_drill, layers=Pad.LAYERS_NPTH))\n\n    # NPTH Holes for Connector Pins\n    npth_drill = variant_params[variant].get('npth_drill', None)\n    if npth_drill:\n        for x in range(0, pins_per_row):\n            for y in range(0, number_of_rows):\n                kicad_mod.append(Pad(at=[pin1_x+x*pitch, pin_row1_y+y*pitch], number=\"\",\n                    type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=npth_drill,\n                    drill=npth_drill, layers=Pad.LAYERS_NPTH))\n\n    # Pads\n    optional_pad_params = {}\n    if not is_smd:\n        if configuration['kicad4_compatible']:\n            optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n        else:\n            optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(start=[pad1_x, pad_row1_y], initial=1,\n        pincount=pins_per_row, increment=2,  x_spacing=pitch, size=pad_size,\n        type=pad_type, shape=pad_shape, layers=pad_layer, drill=pad_drill,\n        **optional_pad_params))\n    kicad_mod.append(PadArray(start=[pad1_x, pad_row2_y], initial=2,\n        pincount=pins_per_row, increment=2, x_spacing=pitch, size=pad_size,\n        type=pad_type, shape=pad_shape, layers=pad_layer, drill=pad_drill,\n        **optional_pad_params))\n\n    # ######################## Fabrication Layer ###########################\n\n    poly_f = [\n        {'x': body_edge['left'], 'y': body_edge['top']},\n        {'x': body_edge['right'], 'y': body_edge['top']},\n        {'x': body_edge['right'], 'y': body_edge['bottom']},\n        {'x': body_edge['left'], 'y': body_edge['bottom']},\n        {'x': body_edge['left'], 'y': body_edge['top']},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_f,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    # Pin 1 marking\n    p1m_sl = 1\n    p1m_poly = [\n        {'x': pad1_x - p1m_sl/2, 'y': body_edge['top']},\n        {'x': pad1_x, 'y': body_edge['top'] + p1m_sl/sqrt(2)},\n        {'x': pad1_x + p1m_sl/2, 'y': body_edge['top']}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=p1m_poly,\n        width=configuration['fab_line_width'], layer=\"F.Fab\"))\n\n    ############################ SilkS ##################################\n\n    s_pad_offset = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    s_offset = configuration['silk_fab_offset']\n\n    # Check if we can draw a solid box for the connector or we need to interrupt it for pads\n    if ((pad_row1_y - pad_size[1]/2 - s_pad_offset) < body_edge['top']) and ((pad_row1_y + pad_size[1]/2 + s_pad_offset) > body_edge['top']):\n        s_xp1_left = pad1_x - pad_size[0]/2 - s_pad_offset\n        s_xpn_right = pad1_x + size_x - pitch + pad_size[0]/2 + s_pad_offset\n\n        poly_s_l = [\n            {'x': s_xp1_left, 'y': pad_row1_y - pad_size[1]/2},\n            {'x': s_xp1_left, 'y': body_edge['top'] - s_offset},\n            {'x': body_edge['left'] - s_offset, 'y': body_edge['top'] - s_offset},\n            {'x': body_edge['left'] - s_offset, 'y': body_edge['bottom'] + s_offset},\n            {'x': s_xp1_left, 'y': body_edge['bottom'] + s_offset},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_s_l,\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n        poly_s_r = [\n            {'x': s_xpn_right, 'y': body_edge['top'] - s_offset},\n            {'x': body_edge['right'] + s_offset, 'y': body_edge['top'] - s_offset},\n            {'x': body_edge['right'] + s_offset, 'y': body_edge['bottom'] + s_offset},\n            {'x': s_xpn_right, 'y': body_edge['bottom'] + s_offset},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_s_r,\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n        for i in range(0, pins_per_row-1):\n            s_xpi_left = pad1_x + i * pitch + pad_size[0]/2 + s_pad_offset\n            s_xpi_right = pad1_x + (i+1) * pitch - pad_size[0]/2 - s_pad_offset\n\n            poly_s_t = [\n                {'x': s_xpi_left, 'y': body_edge['top'] - s_offset},\n                {'x': s_xpi_right, 'y': body_edge['top'] - s_offset},\n            ]\n            kicad_mod.append(PolygoneLine(polygone=poly_s_t,\n                width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n            poly_s_b = [\n                {'x': s_xpi_left, 'y': body_edge['bottom'] + s_offset},\n                {'x': s_xpi_right, 'y': body_edge['bottom'] + s_offset},\n            ]\n            kicad_mod.append(PolygoneLine(polygone=poly_s_b,\n                width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    else:\n        poly_s = [\n            {'x': body_edge['left'] - s_offset, 'y': body_edge['top'] - s_offset},\n            {'x': body_edge['right'] + s_offset, 'y': body_edge['top'] - s_offset},\n            {'x': body_edge['right'] + s_offset, 'y': body_edge['bottom'] + s_offset},\n            {'x': body_edge['left'] - s_offset, 'y': body_edge['bottom'] + s_offset},\n            {'x': body_edge['left'] - s_offset, 'y': body_edge['top'] - s_offset},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_s,\n            width=configuration['silk_line_width'], layer=\"F.SilkS\"))\n\n    # ############################ CrtYd ##################################\n\n    cy_offset = configuration['courtyard_offset']['connector']\n    cy_grid = configuration['courtyard_grid']\n\n    cy_top = roundToBase(bounding_box['top'] - cy_offset, cy_grid)\n    cy_bottom = roundToBase(bounding_box['bottom'] + cy_offset, cy_grid)\n    cy_left = roundToBase(bounding_box['left'] - cy_offset, cy_grid)\n    cy_right = roundToBase(bounding_box['right'] + cy_offset, cy_grid)\n\n    poly_cy = [\n        {'x': cy_left, 'y': cy_top},\n        {'x': cy_right, 'y': cy_top},\n        {'x': cy_right, 'y': cy_bottom},\n        {'x': cy_left, 'y': cy_bottom},\n        {'x': cy_left, 'y': cy_top},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_cy,\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy_top, 'bottom':cy_bottom}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n    lib_name_suffix = '_SMD' if is_smd else '_THT'\n\n    lib_name = configuration['lib_name_format_string_full'].format(series=series, man=manufacturer, suffix=lib_name_suffix)\n\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        for pins_per_row in variant_params[variant]['pins_per_row_range']:\n            generate_one_footprint(pins_per_row, variant, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Samtec/helpers.py",
    "content": "def roundToBase(value, base):\n    if base == 0:\n        return value\n    return round(value/base) * base\n"
  },
  {
    "path": "scripts/Connector/Connector_Samtec/mecf_connector.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nimport math\n\nfrom operator import add\nfrom helpers import *\nfrom math import sqrt\nimport argparse\nimport yaml\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\n# from drawing_tools import *\n# from footprint_scripts_potentiometers import *\nfrom footprint_text_fields import addTextFields\n\nlib_name_category = 'PCBEdge'\n\npinrange = ['05', '08', '20', '30', '40', '50', '60', '70']\n\npad_size = [0.56,4.00]\nlayers_top = ['F.Cu', 'F.Mask']\nlayers_bottom = ['B.Cu', 'B.Mask']\n\npad_type = Pad.TYPE_CONNECT\n\n\nK = {   '05': 8.10,\n        '08': 11.91,\n        '20': 27.15,\n        '30': 39.85,\n        '40': 52.55,\n        '50': 65.25,\n        '60': 77.95,\n        '70': 90.65\n    }\n\nL = {   '05': 2.79,\n        '08': 4.06,\n        '20': 10.41,\n        '30': 14.22,\n        '40': 20.57,\n        '50': 26.92,\n        '60': 20.57,\n        '70': 34.54\n    }\n\nM = {   '60': 40.89,\n        '70': 73.91\n    }\n\nPOL = { '05': [ 3],\n        '08': [ 5],\n        '20': [15],\n        '30': [21],\n        '40': [31],\n        '50': [41],\n        '60': [31, 63],\n        '70': [53, 115]\n      }\n\ndef generate_one_footprint(pol, n, configuration):\n    off = configuration['silk_fab_offset']\n    CrtYd_offset = configuration['courtyard_offset']['default']\n    fp_name = 'Samtec_MECF-' + n + '-0_-'\n    if pol == False:\n        fp_name = fp_name + 'NP-'\n    fp_name += 'L-DV'\n\n    fp_name += '_{:d}x{:02d}_P{:.2f}mm'.format(2,int(n),1.27)\n    if pol:\n        fp_name += '_Polarized'\n    fp_name += '_Edge'\n\n    kicad_mod = Footprint(fp_name)\n\n    description = \"Highspeed card edge connector for PCB's with \" + n + \" contacts \"\n\n    if pol == True:\n        description = description + '(polarized)'\n    else:\n        description = description + '(not polarized)'\n\n    kicad_mod.setAttribute('virtual')\n\n    #set the FP description\n    kicad_mod.setDescription(description)\n\n    tags = \"conn samtec card-edge high-speed\"\n\n    #set the FP tags\n    kicad_mod.setTags(tags)\n\n\n    # set general values\n\n    top = -(5.0)\n    bot =  (5.0)\n\n    left = -(K[n]/2.0)\n    right = (K[n]/2.0)\n    body_edge={\n        'left': left,\n        'right': right,\n        'top': top,\n        'bottom': bot\n    }\n\n    top_left =  [left, top]\n    bot_right = [ right, bot]\n\n    # create Fab Back(exact outline)\n    kicad_mod.append(Line(start=[left + 1.27, bot], end=[right, bot],\n        layer='F.Fab', width=configuration['fab_line_width']))   #bot line\n    kicad_mod.append(Line(start=[left, top], end=[ right, top],\n        layer='F.Fab', width=configuration['fab_line_width']))   #top line\n    kicad_mod.append(Line(start=[left, bot - 1.27], end=[left, top],\n        layer='F.Fab', width=configuration['fab_line_width']))   #left line\n    kicad_mod.append(Line(start=[right, bot], end=[ right, top],\n        layer='F.Fab', width=configuration['fab_line_width']))   #right line\n    kicad_mod.append(Line(start=[left, bot - 1.27], end=[left + 1.27, bot],\n        layer='F.Fab', width=configuration['fab_line_width']))   #corner\n\n    # create Fab Front(exact outline)\n    kicad_mod.append(Line(start=[left, bot], end=[right, bot],\n        layer='B.Fab', width=configuration['fab_line_width']))   #bot line\n    kicad_mod.append(Line(start=[left, top], end=[ right, top],\n        layer='B.Fab', width=configuration['fab_line_width']))   #top line\n    kicad_mod.append(Line(start=[left, bot ], end=[left, top],\n        layer='B.Fab', width=configuration['fab_line_width']))   #left line\n    kicad_mod.append(Line(start=[right, bot], end=[ right, top],\n        layer='B.Fab', width=configuration['fab_line_width']))   #right line\n\n\n    top = top - off\n    #bot = bot + 0.11\n    left = left - off\n    right = right + off\n\n    # create silscreen Back(exact + 0.11)\n    kicad_mod.append(Line(start=[round(left, 2) + 1.27, round(bot, 2)],\n                          end=[round(right, 2), round(bot, 2)],\n                          layer='F.SilkS', width=configuration['silk_line_width'])) #bot line\n    kicad_mod.append(Line(start=[round(left, 2), round(top, 2)],\n                          end=[round(right, 2), round(top, 2)],\n                          layer='F.SilkS', width=configuration['silk_line_width'])) #top line\n    kicad_mod.append(Line(start=[round(left, 2), round(bot, 2) - 1.27],\n                          end=[round(left, 2), round(top, 2)],\n                          layer='F.SilkS', width=configuration['silk_line_width'])) #left line\n    kicad_mod.append(Line(start=[round(right, 2), round( bot, 2)],\n                          end=[round(right, 2), round(top, 2)],\n                          layer='F.SilkS', width=configuration['silk_line_width'])) #right line\n    kicad_mod.append(Line(start=[round(left, 2) + 1.27, round(bot, 2) ],\n                          end=[round(left, 2), round(bot, 2) - 1.27],\n                          layer='F.SilkS', width=configuration['silk_line_width']))   #corner\n\n    # create silscreen Front(exact + 0.11)\n    kicad_mod.append(Line(start=[round(left, 2), round(bot, 2)],\n                          end=[round(right, 2), round(bot, 2)],\n                          layer='B.SilkS', width=configuration['silk_line_width'])) #bot line\n    kicad_mod.append(Line(start=[round(left, 2), round(top, 2)],\n                          end=[round(right, 2), round(top, 2)],\n                          layer='B.SilkS', width=configuration['silk_line_width'])) #top line\n    kicad_mod.append(Line(start=[round(left, 2), round(bot, 2)],\n                          end=[round(left, 2), round(top, 2)],\n                          layer='B.SilkS', width=configuration['silk_line_width'])) #left line\n    kicad_mod.append(Line(start=[round(right, 2), round( bot, 2)],\n                          end=[round(right, 2), round(top, 2)],\n                          layer='B.SilkS', width=configuration['silk_line_width'])) #right line\n\n    top = roundToBase(body_edge['top'] - CrtYd_offset, configuration['courtyard_grid'])\n    bot = roundToBase(body_edge['bottom'], configuration['courtyard_grid'])\n    left = roundToBase(body_edge['left'] - CrtYd_offset, configuration['courtyard_grid'])\n    right = roundToBase(body_edge['right'] + CrtYd_offset, configuration['courtyard_grid'])\n\n    cy1 = top\n    cy2 = bot\n\n    # create courtyard (exact + 0.25)\n    kicad_mod.append(RectLine(start=[left, top], end=[right , bot],\n            layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    kicad_mod.append(RectLine(start=[left, top], end=[right , bot],\n            layer='B.CrtYd', width=configuration['courtyard_line_width']))\n\n\n\n\n    top = body_edge['top']\n    bot =  body_edge['bottom']\n    slot_height = 7.0\n\n\n    ## create cutout\n    kicad_mod.append(Line(start=[-K[n]/2.0, bot, 2],\n                          end=[-K[n]/2.0, top, 2], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #left line\n    kicad_mod.append(Line(start=[K[n]/2.0, bot, 2],\n                          end=[K[n]/2.0, top], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #right line\n\n\n    ## grid ends\n    nextGrid = math.ceil((K[n]/2.0)/0.25 + 1.0) * 0.25\n    #nextGrid = roundToBase(K[n]/2, 0.25)\n    kicad_mod.append(Line(start=[-nextGrid, top, 2],\n        end=[-K[n]/2.0, top, 2], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #left line\n    kicad_mod.append(Line(start=[+nextGrid, top, 2],\n        end=[K[n]/2.0, top], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #right line\n\n\n\n    if pol == True:   # Cutouts\n\n        kicad_mod.append(Line(start=[-K[n]/2.0, bot],\n                              end=[-K[n]/2.0+L[n]-1.24/2.0, bot], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #bot line\n\n        kicad_mod.append(Line(start=[-K[n]/2.0+L[n]-1.24/2.0, bot],\n                              end=[-K[n]/2.0+L[n]-1.24/2.0, bot - slot_height], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #up\n        kicad_mod.append(Line(start=[-K[n]/2.0+L[n]+1.24/2.0, bot],\n                              end=[-K[n]/2.0+L[n]+1.24/2.0, bot - slot_height], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #down\n        kicad_mod.append(Line(start=[-K[n]/2.0+L[n]-1.24/2.0, bot - slot_height],\n                              end=[-K[n]/2.0+L[n]+1.24/2.0, bot - slot_height], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #cut\n\n        if n in ['60','70']:\n            kicad_mod.append(Line(start=[-K[n]/2.0+L[n]+1.24/2.0, bot],\n                              end=[-K[n]/2.0+M[n]-1.24/2.0, bot], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #bot line\n\n            kicad_mod.append(Line(start=[-K[n]/2.0+M[n]-1.24/2.0, bot],\n                              end=[-K[n]/2.0+M[n]-1.24/2.0, bot - slot_height], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #up\n            kicad_mod.append(Line(start=[-K[n]/2.0+M[n]+1.24/2.0, bot],\n                              end=[-K[n]/2.0+M[n]+1.24/2.0, bot - slot_height], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #down\n            kicad_mod.append(Line(start=[-K[n]/2.0+M[n]-1.24/2.0, bot - slot_height],\n                              end=[-K[n]/2.0+M[n]+1.24/2.0, bot - slot_height], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #cut\n\n            kicad_mod.append(Line(start=[-K[n]/2.0+M[n]+1.24/2.0, bot],\n                              end=[K[n]/2.0, bot], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #bot line\n        else:\n            kicad_mod.append(Line(start=[-K[n]/2.0+L[n]+1.24/2.0, bot],\n                              end=[K[n]/2.0, bot], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #bot line\n\n    else:\n        kicad_mod.append(Line(start=[-K[n]/2.0, bot],\n                              end=[K[n]/2.0, bot], layer='Edge.Cuts', width=configuration['edge_cuts_line_width'])) #bot line\n\n\n\n    # create pads\n    for i in range(0,int(n)):\n        start = - K[n]/2.0 + 1.52\n\n        if pol == True:\n            if (i*2+1) not in POL[n]:\n                kicad_mod.append(Pad(number=i*2 + 1, type=pad_type, shape=Pad.SHAPE_RECT,\n                    at=[start + i*1.27, bot - 2.0 - 0.5], size=pad_size, layers=layers_top))\n                kicad_mod.append(Pad(number=i*2 + 2, type=pad_type, shape=Pad.SHAPE_RECT,\n                    at=[start + i*1.27, bot - 2.0 - 0.5], size=pad_size, layers=layers_bottom))\n        else:\n            kicad_mod.append(Pad(number=i*2 + 1, type=pad_type, shape=Pad.SHAPE_RECT,\n                at=[start + i*1.27, bot - 2.0 - 0.5], size=pad_size, layers=layers_top))\n            kicad_mod.append(Pad(number=i*2 + 2, type=pad_type, shape=Pad.SHAPE_RECT,\n                at=[start + i*1.27, bot - 2.0 - 0.5], size=pad_size, layers=layers_bottom))\n\n\n\n    # output kicad model\n    #print(kicad_mod\n\n    # print render tree\n    #print(kicad_mod.getRenderTree())\n    #print(kicad_mod.getCompleteRenderTree())\n\n    # kicad_mod.append(Text(type='reference', text='REF**', at=[0,-6.35], layer='F.SilkS'))\n    # kicad_mod.append(Text(type='user', text='%R', at=[0,-2.54], layer='F.Fab'))\n    # kicad_mod.append(Text(type='value', text=fp_name, at=[0,-3.81], layer='F.Fab'))\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=fp_name, text_y_inside_position=-2.54)\n\n    lib_name = configuration['lib_name_specific_function_format_string'].format(category=lib_name_category)\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=fp_name)\n\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for pol in [True, False]:\n        for pincount in pinrange:\n            generate_one_footprint(pol, pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Samtec/mecf_socket.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nimport math\n\nfrom operator import add\nfrom helpers import *\nfrom math import sqrt\nimport argparse\nimport yaml\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\n# from drawing_tools import *\n# from footprint_scripts_potentiometers import *\nfrom footprint_text_fields import addTextFields\n\nlib_name_category = 'PCBEdge'\n\nA = {   '05': 8.64,\n        '08': 12.45,\n        '20': 27.69,\n        '30': 40.39,\n        '40': 53.09,\n        '50': 65.79,\n        '60': 78.49,\n        '70': 91.19\n    }\n\nB = {   '05': 5.08,\n        '08': 8.89,\n        '20': 24.13,\n        '30': 36.83,\n        '40': 49.53,\n        '50': 62.23,\n        '60': 74.93,\n        '70': 87.63\n    }\n\nC = {   '05': 2.54,\n        '08': 3.81,\n        '20': 10.16,\n        '30': 13.97,\n        '40': 20.32,\n        '50': 26.67,\n        '60': 20.32,\n        '70': 34.29\n    }\n\nD = {   '08': 1.27,\n        '20': 7.62,\n        '30': 11.43,\n        '40': 17.78,\n        '50': 24.13,\n        '60': 17.78,\n        '70': 31.75\n    }\n\n\nE = {   '05': 12.45,\n        '08': 16.26,\n        '20': 31.50,\n        '30': 44.20,\n        '40': 56.90,\n        '50': 69.60,\n        '60': 82.30,\n        '70': 95.00\n    }\n\nF = {   '01': 3.81,\n        '02': 4.60\n    }\n\nG = {   '60': 40.64,\n        '70': 73.66\n    }\n\nH = {   '60': 38.10,\n        '70': 71.12\n    }\n\nPOL = { '05': [ 3],\n        '08': [ 5],\n        '20': [15],\n        '30': [21],\n        '40': [31],\n        '50': [41],\n        '60': [31, 63],\n        '70': [53, 115]\n      }\n\npad_size = [0.66,1.35]\n\ndef generate_one_footprint(weld, pol, pcb_thickness, n, configuration):\n    off = configuration['silk_fab_offset']\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n\n    fp_name = 'Samtec_MECF-' + n + '-' + pcb_thickness + '-'\n    if pol == False:\n        fp_name = fp_name + 'NP-'\n    fp_name = fp_name + 'L-DV'\n    if weld == True:\n        fp_name = fp_name + '-WT'\n\n    fp_name += '_{:d}x{:02d}_P{:.2f}mm'.format(2,int(n),1.27)\n    if pol:\n        fp_name += '_Polarized'\n\n    fp_name = fp_name + '_Socket'\n    fp_name = fp_name + '_Horizontal'\n\n    kicad_mod = Footprint(fp_name)\n\n    description = \"Highspeed card edge connector for \"\n    if pcb_thickness == '01':\n        description = description + '1.6mm'\n    else:\n        description = description + '2.4mm'\n\n    description = description + \" PCB's with \" + n + \" contacts \"\n\n    if pol == True:\n        description = description + '(polarized)'\n    else:\n        description = description + '(not polarized)'\n\n    #set the FP description\n    kicad_mod.setDescription(description)\n    kicad_mod.setAttribute('smd')\n\n    tags = \"conn samtec card-edge high-speed\"\n\n    #set the FP tags\n    kicad_mod.setTags(tags)\n\n\n    top = -(F[pcb_thickness]/2.0 + 0.9)\n    bot =  (F[pcb_thickness]/2.0 + 0.9)\n\n    left = 0\n    right = 0\n    if weld == True:\n        left = -(E[n]/2.0 + 0.91)\n        right = (E[n]/2.0 + 0.91)\n    else:\n        left = -(A[n]/2.0 + 0.91)\n        right = (A[n]/2.0 + 0.91)\n\n    body_edge={\n        'left': left,\n        'right': right,\n        'top': top,\n        'bottom': bot\n    }\n\n\n    top_left =  [left, top]\n    bot_right = [ right, bot]\n\n    # create Fab (exact outline)\n    kicad_mod.append(Line(start=[left + 1.27, bot], end=[right, bot],\n        layer='F.Fab', width=configuration['fab_line_width']))   #bot line\n    kicad_mod.append(Line(start=[left, top], end=[ right, top],\n        layer='F.Fab', width=configuration['fab_line_width']))   #top line\n    kicad_mod.append(Line(start=[left, bot - 1.27], end=[left, top],\n        layer='F.Fab', width=configuration['fab_line_width']))   #left line\n    kicad_mod.append(Line(start=[right, bot], end=[ right, top],\n        layer='F.Fab', width=configuration['fab_line_width']))   #right line\n    kicad_mod.append(Line(start=[left, bot - 1.27], end=[left + 1.27, bot],\n        layer='F.Fab', width=configuration['fab_line_width']))   #corner\n\n    top = top - off\n    bot = bot + off\n    left = left - off\n    right = right + off\n\n    # create silscreen (exact + 0.11)\n    kicad_mod.append(Line(start=[round(left, 2) + 1.27, round(bot, 2)],\n                          end=[round(right, 2), round(bot, 2)],\n                          layer='F.SilkS', width=configuration['silk_line_width'])) #bot line\n    kicad_mod.append(Line(start=[round(left, 2), round(top, 2)],\n                          end=[round(right, 2), round(top, 2)],\n                          layer='F.SilkS', width=configuration['silk_line_width'])) #top line\n    kicad_mod.append(Line(start=[round(left, 2), round(bot, 2) - 1.27],\n                          end=[round(left, 2), round(top, 2)],\n                          layer='F.SilkS', width=configuration['silk_line_width'])) #left line\n    kicad_mod.append(Line(start=[round(right, 2), round( bot, 2)],\n                          end=[round(right, 2), round(top, 2)],\n                          layer='F.SilkS', width=configuration['silk_line_width'])) #right line\n    kicad_mod.append(Line(start=[round(left, 2) + 1.27, round(bot, 2) ],\n                          end=[round(left, 2), round(bot, 2) - 1.27],\n                          layer='F.SilkS', width=configuration['silk_line_width']))   #corner\n\n\n    top = roundToBase(body_edge['top'] - CrtYd_offset, configuration['courtyard_grid'])\n    bot = roundToBase(body_edge['bottom'] + CrtYd_offset, configuration['courtyard_grid'])\n    left = roundToBase(body_edge['left'] - CrtYd_offset, configuration['courtyard_grid'])\n    right = roundToBase(body_edge['right'] + CrtYd_offset, configuration['courtyard_grid'])\n\n    cy1 = top\n    cy2 = bot\n\n    # create courtyard (exact + 0.25)\n    kicad_mod.append(RectLine(start=[round(left,2), round(top,2)],\n                          end=[round(right,2), round(bot,2)],\n                          layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n\n\n\n\n    # create pads\n    for i in range(0,int(n)):\n        start = - B[n]/2.0\n\n        if pol == True:\n            if (i*2+1) not in POL[n]:\n                kicad_mod.append(Pad(number=i*2 + 1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                    at=[start + i*1.27, F[pcb_thickness]/2.0], size=pad_size, layers=Pad.LAYERS_SMT))\n                kicad_mod.append(Pad(number=i*2 + 2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                    at=[start + i*1.27, - F[pcb_thickness]/2.0], size=pad_size, layers=Pad.LAYERS_SMT))\n        else:\n            kicad_mod.append(Pad(number=i*2 + 1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                at=[start + i*1.27, F[pcb_thickness]/2.0], size=pad_size, layers=Pad.LAYERS_SMT))\n            kicad_mod.append(Pad(number=i*2 + 2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                at=[start + i*1.27, - F[pcb_thickness]/2.0], size=pad_size, layers=Pad.LAYERS_SMT))\n\n\n\n    drill = 1.45\n    kicad_mod.append(Pad(number=\"\", type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n        at=[-A[n]/2.0, 0], size=drill, drill=drill, layers=Pad.LAYERS_NPTH))\n    kicad_mod.append(Pad(number=\"\", type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n        at=[A[n]/2.0, 1.0], size=drill, drill=drill, layers=Pad.LAYERS_NPTH))\n\n    if weld == True:\n        size = [1.5,1.5]\n        drill = 1\n        kicad_mod.append(Pad(number=\"\", type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n            at=[-E[n]/2.0, 0], size=size, drill=drill, layers=Pad.LAYERS_THT))\n        kicad_mod.append(Pad(number=\"\", type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n            at=[ E[n]/2.0, 0.0], size=size, drill=drill, layers=Pad.LAYERS_THT))\n\n    # output kicad model\n    #print(kicad_mod\n    # kicad_mod.append(Text(type='reference', text='REF**', at=[0,3.81], layer='F.SilkS'))\n    # kicad_mod.append(Text(type='user', text='%R', at=[0,0], layer='F.Fab'))\n    # kicad_mod.append(Text(type='value', text=fp_name, at=[0,-3.81], layer='F.Fab'))\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=fp_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    #lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    lib_name = configuration['lib_name_specific_function_format_string'].format(category=lib_name_category)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=fp_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=fp_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\n\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for weld in [True, False]:\n        for pol in [True, False]:\n            for pcb_thickness in ['01', '02']:\n                for n in ['05', '08', '20', '30', '40', '50', '60', '70']:\n                    generate_one_footprint(weld, pol, pcb_thickness, n, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Stocko/conn_Stocko_MKS_16xx.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom KicadModTree import *\n\noutput_dir = \"Connector_Stocko.pretty\"\n\nif not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n    os.makedirs(output_dir)\n\n#connector constraints\npad_span = 2.5\npad_size_x = 1.5\npad_size_y = 2\ndrill = 1\nfab_outline_x = 3.6\nfab_outline_y = 3.75\nfab_cut_depth = 2\nfab_cut_width = 2\nfab_arc_r = 0.5\nfab_first_pin = 0.5\n\nsilks_outline_x = fab_outline_x + 0.11\nsilks_outline_y = fab_outline_y + 0.11\nsilks_cut_depth = 2\nsilks_cut_width = 2 + 0.22\nsilks_arc_r = fab_arc_r + 0.11\n\ncourtyard_outline = 0.5\n\nfor itr in range (1, 20 + 1):\n\n    # for special case, details: https://www.stocko-contact.com/en/products-connector-system-pitch-2.5-mm-rfk-2-mks-1650.php\n    if itr == 1:\n        pin_count = 2\n    elif itr == 2:\n        pin_count = 2\n        fab_outline_x = 2.7\n        silks_outline_x = fab_outline_x + 0.11\n    else:\n        pin_count = itr\n        fab_outline_x = 3.6\n        silks_outline_x = fab_outline_x + 0.11\n\n    #init kicad footprint\n    footprint_name = \"Stocko_MKS_16{}-6-0-{}{:02d}_1x{}_P2.50mm_Vertical\".format(50 + itr, pin_count, pin_count, pin_count)\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"Stocko MKS 16xx series connector, (https://www.stocko-contact.com/downloads/steckverbindersystem-raster-2,5-mm.pdf#page=15), generated with kicad-footprint-generator\")\n    kicad_mod.setTags(\"Stocko RFK MKS 16xx\")\n\n    #CREATE PIN\n\n    #first rectangle pin\n    kicad_mod.append(Pad(number = 1, type = Pad.TYPE_THT, shape = Pad.SHAPE_ROUNDRECT,\n                        at=[0, 0], size=[pad_size_x, pad_size_y], drill=drill, layers=Pad.LAYERS_THT,\n                        radius_ratio=0.25))\n    #circle pin\n    for pin_cnt in range (2, pin_count + 1):\n        kicad_mod.append(Pad(number = pin_cnt, type = Pad.TYPE_THT, shape = Pad.SHAPE_OVAL,\n                        at=[(pin_cnt - 1) * pad_span, 0], size=[pad_size_x, pad_size_y], drill=drill, layers = Pad.LAYERS_THT))\n\n    #CREATE SILKSCREEN\n    #name\n    kicad_mod.append(Text(type = 'reference', text='REF**', at=[(pin_count - 1) * (pad_span / 2), -4.5], layer='F.SilkS'))\n    #top\n    kicad_mod.append(Line(start = [-silks_outline_x + silks_arc_r, -silks_outline_y],\n                          end = [(pin_cnt - 1) * pad_span + silks_outline_x - silks_arc_r, -silks_outline_y], layer = 'F.SilkS'))\n    #left\n    kicad_mod.append(Line(start = [-silks_outline_x, -silks_outline_y + silks_arc_r],\n                          end = [-silks_outline_x, silks_outline_y - silks_arc_r], layer = 'F.SilkS'))\n    #right\n    kicad_mod.append(Line(start = [(pin_cnt - 1) * pad_span + silks_outline_x, -silks_outline_y + silks_arc_r],\n                          end = [(pin_cnt - 1) * pad_span + silks_outline_x, silks_outline_y - silks_arc_r], layer = 'F.SilkS'))\n    #bottom left\n    kicad_mod.append(Line(start = [-silks_outline_x + silks_arc_r, silks_outline_y],\n                          end = [-silks_outline_x + silks_cut_width, silks_outline_y], layer = 'F.SilkS'))\n    kicad_mod.append(Line(start = [-silks_outline_x + silks_cut_width, silks_outline_y],\n                          end = [-silks_outline_x + silks_cut_width, silks_outline_y - silks_cut_depth], layer = 'F.SilkS'))\n    #bottom right\n    kicad_mod.append(Line(start = [(pin_cnt - 1) * pad_span + silks_outline_x - silks_arc_r, silks_outline_y],\n                          end = [(pin_cnt - 1) * pad_span + silks_outline_x - silks_cut_width, silks_outline_y], layer = 'F.SilkS'))\n    kicad_mod.append(Line(start = [(pin_cnt - 1) * pad_span + silks_outline_x - silks_cut_width, silks_outline_y],\n                          end = [(pin_cnt - 1) * pad_span + silks_outline_x - silks_cut_width, silks_outline_y - silks_cut_depth], layer = 'F.SilkS'))\n    #bottom center\n    kicad_mod.append(Line(start = [-silks_outline_x + silks_cut_width, silks_outline_y - silks_cut_depth],\n                          end = [(pin_cnt - 1) * pad_span + silks_outline_x - silks_cut_width, silks_outline_y - silks_cut_depth], layer = 'F.SilkS'))\n    #arc left top\n    kicad_mod.append(Arc(center = [-silks_outline_x + silks_arc_r, -silks_outline_y + silks_arc_r],\n                         start = [-silks_outline_x, -silks_outline_y + silks_arc_r], angle = 90, layer = 'F.SilkS'))\n    #arc right top\n    kicad_mod.append(Arc(center = [(pin_cnt - 1) * pad_span + silks_outline_x - silks_arc_r, -silks_outline_y + silks_arc_r],\n                         start = [(pin_cnt - 1) * pad_span + silks_outline_x - silks_arc_r, -silks_outline_y], angle = 90, layer = 'F.SilkS'))\n    #arc left bottom\n    kicad_mod.append(Arc(center = [-silks_outline_x + silks_arc_r, silks_outline_y - silks_arc_r],\n                         start = [-silks_outline_x + silks_arc_r, silks_outline_y], angle = 90, layer = 'F.SilkS'))\n    #arc right bottom\n    kicad_mod.append(Arc(center = [(pin_cnt - 1) * pad_span + silks_outline_x - silks_arc_r, silks_outline_y - silks_arc_r],\n                         start = [(pin_cnt - 1) * pad_span + silks_outline_x, silks_outline_y - silks_arc_r], angle = 90, layer = 'F.SilkS'))\n    #first pin indicator\n    kicad_mod.append(Line(start = [0.3, 2.9], end = [0, 2.4], layer = 'F.SilkS'))\n    kicad_mod.append(Line(start = [0, 2.4], end = [-0.3, 2.9], layer = 'F.SilkS'))\n    kicad_mod.append(Line(start = [-0.3, 2.9], end = [0.3, 2.9], layer = 'F.SilkS'))\n\n\n    #CREATE FABRICATION\n    #name\n    kicad_mod.append(Text(type = 'user', text = '%R', at = [(pin_count - 1) * (pad_span / 2), -2], layer = 'F.Fab'))\n    kicad_mod.append(Text(type = 'value', text = footprint_name, at = [(pin_count - 1) * (pad_span / 2), silks_outline_y + 2], layer = 'F.Fab'))\n    #top\n    kicad_mod.append(Line(start = [-fab_outline_x + fab_arc_r, -fab_outline_y],\n                          end = [(pin_cnt - 1) * pad_span + fab_outline_x - fab_arc_r, -fab_outline_y], layer = 'F.Fab'))\n    #left\n    kicad_mod.append(Line(start = [-fab_outline_x, -fab_outline_y + fab_arc_r],\n                          end = [-fab_outline_x, fab_outline_y - fab_arc_r], layer = 'F.Fab'))\n    #right\n    kicad_mod.append(Line(start = [(pin_cnt - 1) * pad_span + fab_outline_x, -fab_outline_y + fab_arc_r],\n                          end = [(pin_cnt - 1) * pad_span + fab_outline_x, fab_outline_y - fab_arc_r], layer = 'F.Fab'))\n    #bottom left\n    kicad_mod.append(Line(start = [-fab_outline_x + fab_arc_r, fab_outline_y],\n                          end = [-fab_outline_x + fab_cut_width, fab_outline_y], layer = 'F.Fab'))\n    kicad_mod.append(Line(start = [-fab_outline_x + fab_cut_width, fab_outline_y],\n                          end = [-fab_outline_x + fab_cut_width, fab_outline_y - fab_cut_depth], layer = 'F.Fab'))\n    #bottom right\n    kicad_mod.append(Line(start = [(pin_cnt - 1) * pad_span + fab_outline_x - fab_arc_r, fab_outline_y],\n                          end = [(pin_cnt - 1) * pad_span + fab_outline_x - fab_cut_width, fab_outline_y], layer = 'F.Fab'))\n    kicad_mod.append(Line(start = [(pin_cnt - 1) * pad_span + fab_outline_x - fab_cut_width, fab_outline_y],\n                          end = [(pin_cnt - 1) * pad_span + fab_outline_x - fab_cut_width, fab_outline_y - fab_cut_depth], layer = 'F.Fab'))\n    #bottom center and first pin indicator\n    kicad_mod.append(Line(start = [-fab_outline_x + fab_cut_width, fab_outline_y - fab_cut_depth],\n                          end = [-fab_first_pin, fab_outline_y - fab_cut_depth], layer = 'F.Fab'))\n\n    kicad_mod.append(Line(start = [fab_first_pin, fab_outline_y - fab_cut_depth],\n                          end = [(pin_cnt - 1) * pad_span + fab_outline_x - fab_cut_width, fab_outline_y - fab_cut_depth], layer = 'F.Fab'))\n\n    kicad_mod.append(Line(start = [-fab_first_pin, fab_outline_y - fab_cut_depth],\n                          end = [0, fab_outline_y - fab_cut_depth - fab_first_pin], layer = 'F.Fab'))\n\n    kicad_mod.append(Line(start = [0, fab_outline_y - fab_cut_depth - fab_first_pin],\n                          end = [fab_first_pin, fab_outline_y - fab_cut_depth], layer = 'F.Fab'))\n\n    #arc left top\n    kicad_mod.append(Arc(center = [-fab_outline_x + fab_arc_r, -fab_outline_y + fab_arc_r],\n                         start = [-fab_outline_x, -fab_outline_y + fab_arc_r], angle = 90, layer = 'F.Fab'))\n    #arc right top\n    kicad_mod.append(Arc(center = [(pin_cnt - 1) * pad_span + fab_outline_x - fab_arc_r, -fab_outline_y + fab_arc_r],\n                         start = [(pin_cnt - 1) * pad_span + fab_outline_x - fab_arc_r, -fab_outline_y], angle = 90, layer = 'F.Fab'))\n    #arc left bottom\n    kicad_mod.append(Arc(center = [-fab_outline_x + fab_arc_r, fab_outline_y - fab_arc_r],\n                         start = [-fab_outline_x + fab_arc_r, fab_outline_y], angle = 90, layer = 'F.Fab'))\n    #arc right bottom\n    kicad_mod.append(Arc(center = [(pin_cnt - 1) * pad_span + fab_outline_x - fab_arc_r, fab_outline_y - fab_arc_r],\n                         start = [(pin_cnt - 1) * pad_span + fab_outline_x, fab_outline_y - fab_arc_r], angle = 90, layer = 'F.Fab'))\n\n    #CREATE COURTYARD\n    kicad_mod.append(RectLine(start = [-fab_outline_x - courtyard_outline, -fab_outline_y - courtyard_outline],\n                              end = [(pin_cnt - 1) * pad_span + fab_outline_x + courtyard_outline, fab_outline_y + courtyard_outline],\n                              layer = 'F.CrtYd'))\n    #add 3D model\n    kicad_mod.append(Model(filename=\"${{KISYS3DMOD}}/Connector_Stocko.3dshapes/{}.wrl\".format(footprint_name),\n                        at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n    #output kicad model\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(output_dir + '/' + footprint_name + '.kicad_mod')"
  },
  {
    "path": "scripts/Connector/Connector_TE-Connectivity/conn_ffc_te_84952-84953.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\n\"\"\"\n\nThis family of parts is spread over 2 datasheets, depending on the contact side:\n\nBottom contact:\nhttp://www.te.com/commerce/DocumentDelivery/DDEController?Action=srchrtrv&DocNm=84952&DocType=Customer+Drawing&DocLang=English&DocFormat=pdf&PartCntxt=1-84952-5\n\nTop contact:\nhttp://www.te.com/commerce/DocumentDelivery/DDEController?Action=srchrtrv&DocNm=84953&DocType=Customer+Drawing&DocLang=English&DocFormat=pdf&PartCntxt=1-84953-5\n\n\"\"\"\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nmanufacturer = \"TE-Connectivity\"\nconn_category = \"FFC-FPC\"\n\nlib_by_conn_category = True\n\npartnumbers = [\"84952\",\"84953\"]\npincounts = range(4, 31)\n\ndef generate_one_footprint(partnumber, pincount, configuration):\n    # only double digit pincount parts have leading chars on the PN\n    if pincount >= 10:\n        pn_prefix = str(pincount)[0] + \"-\"\n    else:\n        pn_prefix = \"\"\n\n    footprint_name = 'TE_{pnp}{pn:s}-{pns}_1x{pc:02g}-1MP_P1.0mm_Horizontal'\\\n        .format(pnp=pn_prefix, pn=partnumber, pns=str(pincount)[-1], pc=pincount)\n    print('Building {:s}'.format(footprint_name))\n\n    # calculate working values\n    pitch = 1\n    pad_y = -1.8\n    pad_width = 0.61\n    pad_height = 2\n    pad_x_span = pitch * (pincount - 1)\n    pad1_x = pad_x_span / 2.0\n\n    tab_width = 4.33 - 1.65\n    tab_height = 3.6\n    tab_x = pad_x_span / 2.0 + 1.65 + tab_width / 2.0\n    tab_y = pad_y + pad_height / 2.0 + tab_height / 2.0\n\n    body_y1 = pad_y + pad_height / 2.0\n    half_body_width = pad_x_span / 2.0 + 3.435\n    actuator_y1 = body_y1 + 5.4\n    actuator_y2 = body_y1 + 7.3\n    half_actuator_width = pad_x_span / 2.0 + 4.46\n    ear_height = 0.89\n\n    body_edge = {\n        'left': -half_body_width,\n        'right': half_body_width,\n        'top': body_y1,\n        'bottom': actuator_y1\n    }\n\n    silk_clearance = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    marker_y = 1.8\n    nudge = configuration['silk_fab_offset']\n\n    courtyard_precision = configuration['courtyard_grid']\n    courtyard_clearance = configuration['courtyard_offset']['connector']\n    courtyard_x = roundToBase(half_actuator_width + courtyard_clearance, courtyard_precision)\n    courtyard_y1 = roundToBase(pad_y - pad_height / 2.0 - courtyard_clearance, courtyard_precision)\n    courtyard_y2 = roundToBase(actuator_y2 + courtyard_clearance, courtyard_precision)\n\n    label_y_offset = 0.7\n\n    # select correct datasheet URL depending on part number\n    if partnumber == \"84952\":\n        datasheet = \"http://www.te.com/commerce/DocumentDelivery/DDEController?Action=srchrtrv&DocNm=84952&DocType=Customer+Drawing&DocLang=English&DocFormat=pdf&PartCntxt=84952-4\"\n        side = \"bottom\"\n    elif partnumber == \"84953\":\n        datasheet = \"http://www.te.com/commerce/DocumentDelivery/DDEController?Action=srchrtrv&DocNm=84953&DocType=Customer+Drawing&DocLang=English&DocFormat=pdf&PartCntxt=84953-4\"\n        side = \"top\"\n\n    # initialise footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription('TE FPC connector, {pc:02g} {side}-side contacts, 1.0mm pitch, 1.0mm height, SMT, {ds}'.format(pc=pincount, side=side, ds=datasheet))\n    kicad_mod.setTags('te fpc {:s}'.format(partnumber))\n    kicad_mod.setAttribute('smd')\n\n\n    # create pads\n    kicad_mod.append(PadArray(pincount=pincount, x_spacing=pitch, center=[0,pad_y],\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n        size=[pad_width, pad_height], layers=Pad.LAYERS_SMT))\n\n    # create tab (smt mounting) pads\n    kicad_mod.append(Pad(number=configuration['mounting_pad_number'],\n        at=[-tab_x, tab_y], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n        size=[tab_width, tab_height], layers=Pad.LAYERS_SMT))\n    kicad_mod.append(Pad(number=configuration['mounting_pad_number'],\n        at=[tab_x, tab_y], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n        size=[tab_width, tab_height], layers=Pad.LAYERS_SMT))\n\n    # create fab outline and pin 1 marker\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            [-half_body_width, body_y1],\n            [half_body_width, body_y1],\n            [half_body_width, actuator_y1-ear_height],\n            [half_actuator_width, actuator_y1-ear_height],\n            [half_actuator_width, actuator_y1],\n            [-half_actuator_width, actuator_y1],\n            [-half_actuator_width, actuator_y1-ear_height],\n            [-half_body_width, actuator_y1-ear_height],\n            [-half_body_width, body_y1]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            [-pad1_x-0.5, body_y1],\n            [-pad1_x, body_y1+1],\n            [-pad1_x+0.5, body_y1]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    # create open actuator outline\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            [half_body_width, actuator_y1],\n            [half_body_width, actuator_y2-ear_height],\n            [half_actuator_width, actuator_y2-ear_height],\n            [half_actuator_width, actuator_y2],\n            [-half_actuator_width, actuator_y2],\n            [-half_actuator_width, actuator_y2-ear_height],\n            [-half_body_width, actuator_y2-ear_height],\n            [-half_body_width, actuator_y1]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    # create silkscreen outline and pin 1 marker\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            [half_body_width+nudge, tab_y+tab_height/2.0+silk_clearance],\n            [half_body_width+nudge, actuator_y1-ear_height-nudge],\n            [half_actuator_width+nudge, actuator_y1-ear_height-nudge],\n            [half_actuator_width+nudge, actuator_y1+nudge],\n            [-half_actuator_width-nudge, actuator_y1+nudge],\n            [-half_actuator_width-nudge, actuator_y1-ear_height-nudge],\n            [-half_body_width-nudge, actuator_y1-ear_height-nudge],\n            [-half_body_width-nudge, tab_y+tab_height/2.0+silk_clearance]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            [-tab_x+tab_width/2.0+silk_clearance, body_y1-nudge],\n            [-pad1_x-pad_width/2.0-silk_clearance, body_y1-nudge],\n            [-pad1_x-pad_width/2.0-silk_clearance, body_y1-nudge-marker_y]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    kicad_mod.append(Line(\n        start=[pad1_x+pad_width/2.0+silk_clearance, body_y1-nudge],\n        end=[tab_x-tab_width/2.0-silk_clearance, body_y1-nudge],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-courtyard_x, courtyard_y1], end=[courtyard_x, courtyard_y2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    # kicad_mod.append(Text(type='reference', text='REF**', size=[1,1], at=[0, courtyard_y1 - label_y_offset], layer='F.SilkS'))\n    # kicad_mod.append(Text(type='user', text='%R', size=[1,1], at=[0, tab_y], layer='F.Fab'))\n    # kicad_mod.append(Text(type='value', text=footprint_name, at=[0, courtyard_y2 + label_y_offset], layer='F.Fab'))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':courtyard_y1, 'bottom':courtyard_y2}, fp_name=footprint_name, text_y_inside_position=[0, tab_y])\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    if lib_by_conn_category:\n        lib_name = configuration['lib_name_specific_function_format_string'].format(category=conn_category)\n    else:\n        lib_name = configuration['lib_name_format_string'].format(man=manufacturer)\n\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    # with pincount(s) and partnumber(s) to be generated, build them all in a nested loop\n    for partnumber in partnumbers:\n        for pincount in pincounts:\n            generate_one_footprint(partnumber, pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_TE-Connectivity/conn_fpc_te_1734839.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\n\"\"\"\n\nDrawing:\nhttps://www.te.com/commerce/DocumentDelivery/DDEController?Action=showdoc&DocId=Customer+Drawing%7F1734839%7FC%7Fpdf%7FEnglish%7FENG_CD_1734839_C_C_1734839.pdf%7F4-1734839-0\n\n\"\"\"\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nmanufacturer = \"TE-Connectivity\"\nconn_category = \"FFC-FPC\"\n\nlib_by_conn_category = True\n\npartnumbers = [\"1734839\"]\npincounts = range(5, 51)\n\ndef generate_one_footprint(partnumber, pincount, configuration):\n    # leading chars on the PN\n    if pincount >= 10:\n        pn_prefix = str(pincount)[0] + \"-\"\n    else:\n        pn_prefix = \"0-\"\n\n    footprint_name = 'TE_{pnp}{pn:s}-{pns}_1x{pc:02g}-1MP_P0.5mm_Horizontal'\\\n        .format(pnp=pn_prefix, pn=partnumber, pns=str(pincount)[-1], pc=pincount)\n    print('Building {:s}'.format(footprint_name))\n\n    # calculate working values\n    pitch = 0.5\n    pad_y = -1.35\n    pad_width = 0.3\n    pad_height = 1.1\n    pad_x_span = pitch * (pincount - 1)\n    pad1_x = pad_x_span / 2.0\n\n    tab_width = 2.3\n    tab_height = 3.1\n    tab_x = pad_x_span / 2.0 + 2.82 - tab_width / 2.0\n    tab_y = pad_y - pad_height / 2.0 + 0.7 + tab_height / 2.0\n\n    body_y1 = pad_y + 0.7\n    half_body_width = pad_x_span / 2.0 + 2.31\n    actuator_y1 = body_y1 + 4.4\n    half_actuator_width = pad_x_span / 2.0 + 2.965\n    ear_height = 4.4 - 2.8\n\n    pcb_edge_gap = 0.6\n\n    body_edge = {\n        'left': -half_body_width,\n        'right': half_body_width,\n        'top': body_y1,\n        'bottom': actuator_y1\n    }\n\n    silk_clearance = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n    nudge = configuration['silk_fab_offset']\n\n    courtyard_precision = configuration['courtyard_grid']\n    courtyard_clearance = configuration['courtyard_offset']['connector']\n    courtyard_x = roundToBase(half_actuator_width + courtyard_clearance, courtyard_precision)\n    courtyard_y1 = roundToBase(pad_y - pad_height / 2.0 - courtyard_clearance, courtyard_precision)\n    courtyard_y2 = roundToBase(actuator_y1 + courtyard_clearance, courtyard_precision)\n\n    label_y_offset = 0.7\n\n    datasheet = \"https://www.te.com/commerce/DocumentDelivery/DDEController?Action=showdoc&DocId=Customer+Drawing%7F1734839%7FC%7Fpdf%7FEnglish%7FENG_CD_1734839_C_C_1734839.pdf%7F4-1734839-0\"\n    side = \"top\"\n\n    # initialise footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription('TE FPC connector, {pc:02g} {side}-side contacts, 0.5mm pitch, SMT, {ds}'.format(pc=pincount, side=side, ds=datasheet))\n    kicad_mod.setTags('te fpc {:s}'.format(partnumber))\n    kicad_mod.setAttribute('smd')\n\n\n    # create pads\n    kicad_mod.append(PadArray(pincount=pincount, x_spacing=pitch, center=[0,pad_y],\n        type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n        size=[pad_width, pad_height], layers=Pad.LAYERS_SMT))\n\n    # create tab (smt mounting) pads\n    kicad_mod.append(Pad(number=configuration['mounting_pad_number'],\n        at=[-tab_x, tab_y], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n        size=[tab_width, tab_height], layers=Pad.LAYERS_SMT))\n    kicad_mod.append(Pad(number=configuration['mounting_pad_number'],\n        at=[tab_x, tab_y], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n        size=[tab_width, tab_height], layers=Pad.LAYERS_SMT))\n\n    # create fab outline\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            [-half_body_width, body_y1],\n            [half_body_width, body_y1],\n            [half_body_width, actuator_y1-ear_height],\n            [half_actuator_width, actuator_y1-ear_height],\n            [half_actuator_width, actuator_y1],\n            [-half_actuator_width, actuator_y1],\n            [-half_actuator_width, actuator_y1-ear_height],\n            [-half_body_width, actuator_y1-ear_height],\n            [-half_body_width, body_y1]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    # create fab pin 1 marker\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            [-pad1_x-0.4, body_y1],\n            [-pad1_x, body_y1+0.8],\n            [-pad1_x+0.4, body_y1]],\n        layer='F.Fab', width=configuration['fab_line_width']))\n\n    # create silkscreen outline\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            [-half_actuator_width, actuator_y1-nudge-ear_height],\n            [-half_actuator_width-nudge, actuator_y1-nudge-ear_height],\n            [-half_actuator_width-nudge, actuator_y1-ear_height+pcb_edge_gap-nudge]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            [half_actuator_width, actuator_y1-nudge-ear_height],\n            [half_actuator_width+nudge, actuator_y1-nudge-ear_height],\n            [half_actuator_width+nudge, actuator_y1-ear_height+pcb_edge_gap-nudge]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    # create silkscreen pin 1 marker\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            [-pad1_x-0.2, body_y1+0.1],\n            [-pad1_x, body_y1+0.5],\n            [-pad1_x+0.2, body_y1+0.1],\n            [-pad1_x-0.2, body_y1+0.1]],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    # create PCB edge\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            [half_actuator_width-nudge, actuator_y1-ear_height+pcb_edge_gap],\n            [-half_actuator_width+nudge, actuator_y1-ear_height+pcb_edge_gap]],\n        layer='Dwgs.User', width=configuration['fab_line_width']))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-courtyard_x, courtyard_y1], end=[courtyard_x, courtyard_y2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n    # kicad_mod.append(Text(type='reference', text='REF**', size=[1,1], at=[0, courtyard_y1 - label_y_offset], layer='F.SilkS'))\n    # kicad_mod.append(Text(type='user', text='%R', size=[1,1], at=[0, tab_y], layer='F.Fab'))\n    # kicad_mod.append(Text(type='value', text=footprint_name, at=[0, courtyard_y2 + label_y_offset], layer='F.Fab'))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':courtyard_y1, 'bottom':courtyard_y2}, fp_name=footprint_name, text_y_inside_position=[0, tab_y])\n\n    kicad_mod.append(Text(type='value', text='PCB Edge', \n        at=[0,actuator_y1-(ear_height-pcb_edge_gap)/2.0], size=[0.5,0.5], layer='Dwgs.User', thickness=0.08, rotation=0))\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    if lib_by_conn_category:\n        lib_name = configuration['lib_name_specific_function_format_string'].format(category=conn_category)\n    else:\n        lib_name = configuration['lib_name_format_string'].format(man=manufacturer)\n\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    # with pincount(s) and partnumber(s) to be generated, build them all in a nested loop\n    for partnumber in partnumbers:\n        for pincount in pincounts:\n            generate_one_footprint(partnumber, pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_TE-Connectivity/conn_te_826576.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\ndraw_inner_details = False\n\nseries = \"826576\"\nmanufacturer = 'TE'\nmanufacturer_lib = 'TE-Connectivity'\norientation = 'V'\ndatasheet = 'https://www.te.com/commerce/DocumentDelivery/DDEController?Action=srchrtrv&DocNm=826576&DocType=Customer+Drawing&DocLang=English'\nnumber_of_rows = 1\n\n# only generate active pin counts from TE rev 7 datasheet\n#pins_per_row_range = range(1, 37)\npins_per_row_range = [2,3,5,6,7,8,9,13,15,16,17,18,20,36]\n\n# the datasheet has an equation and a table (column 'L') for body length\n# the equation of pincount * 3.96 = length is wrong\n# the table is roughly correct based on part measurement\n# table is nearly pincount * 3.96 - 0.589 but capture the table exactly\nbody_lengths = {1:3.3, 2:7.3, 3:11.3, 4:15.2, 5:19.2, 6:23.1, 7:27.1, 8:31.1, 9:35.1, 10:39,\n                11:43, 12:46.9, 13:50.9, 14:54.8, 15:58.8, 16:62.8, 17:66.7, 18:70.7, 19:74.7, 20:78.6,\n                21:82.6, 22:86.5, 23:90.5, 24:94.4, 25:98.4, 26:102.4, 27:106.3, 28:110.3, 29:114.2, 30:118.2,\n                31:122.2, 32:126.1, 33:130.1, 34:134, 35:138, 36:141.6}\n\npart_code = \"{:s}{:s}826576-{:s}\"\n\npitch = 3.96\ndrill = 1.4\nstart_pos_x = 0 # Where should pin 1 be located?\npad_size = [drill + 1, drill + 1]\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\n\ndef generate_one_footprint(pins, configuration):\n    mpn = part_code.format(str(pins)[:1] if pins > 9 else '', '-' if pins > 9 else '', str(pins)[-1])\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_no_series_format_string'].format(man=manufacturer,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    print(footprint_name)\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"{:s}, {:s}, {:d} Pins ({:s}), generated with kicad-footprint-generator\".format(manufacturer,\n        mpn, pins, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    #calculate fp dimensions\n\n    #B = distance between end-point pins\n    B = (pins - 1) * pitch\n    #A = total connector length\n    A = body_lengths[pins]\n\n    #corners\n    x1 = -(A-B) / 2\n    x2 = x1 + A\n\n    body_width = 6.4\n    y2 = body_width / 2\n    y1 = y2 - body_width\n\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n\n    out = [\n    {'x': B/2, 'y': y1},\n    {'x': x1, 'y': y1},\n    {'x': x1, 'y': y2},\n    {'x': B/2, 'y': y2},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=out,\n        layer=\"F.Fab\", width=configuration['fab_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=out,x_mirror=B/2,\n        layer=\"F.Fab\", width=configuration['fab_line_width']))\n\n    #offset\n    o = configuration['silk_fab_offset']\n    x1 -= o\n    y1 -= o\n    x2 += o\n    y2 += o\n\n    out = [\n    {'x': B/2, 'y': y1},\n    {'x': x1, 'y': y1},\n    {'x': x1, 'y': y2},\n    {'x': B/2, 'y': y2},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=out,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=out,x_mirror=B/2,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    #generate the pads\n    kicad_mod.append(PadArray(\n        pincount=pins, x_spacing=pitch, type=Pad.TYPE_THT,\n        shape=pad_shape, size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    #pin-1 marker\n    pin_mark_width = 1\n    pin_mark_height = 1\n    pin_mask_offset = 0.5\n    \n    pin = [\n        {'x': -pin_mark_width/2,'y': body_edge['bottom']},\n        {'x': 0,'y': body_edge['bottom'] - pin_mark_height},\n        {'x': pin_mark_width/2,'y': body_edge['bottom']},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        layer=\"F.Fab\", width=configuration['fab_line_width']))\n\n    pin = [\n        {'x': -pin_mark_width/2,'y': body_edge['bottom'] + pin_mark_height + pin_mask_offset},\n        {'x': 0,'y': body_edge['bottom'] + pin_mask_offset},\n        {'x': pin_mark_width/2,'y': body_edge['bottom'] + pin_mark_height + pin_mask_offset},\n        {'x': -pin_mark_width/2,'y': body_edge['bottom'] + pin_mark_height + pin_mask_offset}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(bounding_box['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(bounding_box['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(bounding_box['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(bounding_box['bottom'] + configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='top')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer_lib)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pins_per_row in pins_per_row_range:\n        generate_one_footprint(pins_per_row, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_TE-Connectivity/conn_te_mate-n-lock_tht_side.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt, asin, degrees\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\ndraw_inner_details = False\n\nseries = \"MATE-N-LOK\"\nseries_long = 'Mini-Universal MATE-N-LOK'\nman_lib = 'TE-Connectivity'\nman_short_fp_name = 'TE'\norientation = 'H'\ndatasheet = \"http://www.te.com/commerce/DocumentDelivery/DDEController?Action=srchrtrv&DocNm=82181_SOFTSHELL_HIGH_DENSITY&DocType=CS&DocLang=EN\"\n\n#Molex part number\n#n = number of circuits per row\nvariant_params = {\n    'in_line':{\n        'pins_per_row_range': [1,2,3],\n        'number_of_rows': 1,\n        'style': 'in_line',\n        'number_pegs': 1,\n        'peg_from_center': 0,\n        'part_code': {\n                1: '1-794374-x',\n                2: '1-770966-x',\n                3: '1-770967-x'\n            }\n        },\n    'dual1':{\n        'pins_per_row_range': range(2,7),\n        'number_of_rows': 2,\n        'style': 'dual_row',\n        'number_pegs': 1,\n        'peg_from_center': 0,\n        'part_code': {\n                4: '1-770968-x',\n                6: '1-770969-x',\n                8: '1-770970-x',\n                10: '1-770971-x',\n                12: '1-770972-x'\n            }\n        },\n    'dual2':{\n        'pins_per_row_range': [7,9],\n        'number_of_rows': 2,\n        'style': 'dual_row',\n        'number_pegs': 2,\n        'peg_from_center': 8.28,\n        'part_code': {\n                14: '1-770973-x',\n                18: '1-794105-x'\n            }\n        },\n    'dual3':{\n        'pins_per_row_range': [8,10,12],\n        'number_of_rows': 2,\n        'style': 'dual_row',\n        'number_pegs': 2,\n        'peg_from_center': 10.38,\n        'part_code': {\n                16: '1-770974-x',\n                20: '1-794106-x',\n                24: '1-794108-x'\n            }\n        },\n    'dual4':{\n        'pins_per_row_range': [11],\n        'number_of_rows': 2,\n        'style': 'dual_row',\n        'number_pegs': 2,\n        'peg_from_center': 12.42,\n        'part_code': {\n                22: '1-794107-x'\n            }\n        },\n}\n\npitch = 4.14\ndrill = 1.4\npad_to_pad_clearance = 1.5\nmax_annular_ring = 0.95\nmin_annular_ring = 0.15\nrow = 4.14\n\npeg_drill = 3.86\npeg_to_nearest_pin = 7.34\nwidth = 12.7\n\npeg_to_body_right = 6.86\n\ndef generate_one_footprint(pins_per_row, variant_param, configuration):\n    silk_pad_off = configuration['silk_pad_clearance']+configuration['silk_line_width']/2\n    off = configuration['silk_fab_offset']\n\n    number_of_rows = variant_param['number_of_rows']\n\n    pad_size = [row - pad_to_pad_clearance, pitch - pad_to_pad_clearance]\n    if number_of_rows == 1:\n        pad_size[0] = drill + 2*max_annular_ring\n\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n    if pad_size[0] - drill > 2*max_annular_ring:\n        pad_size[0] = drill + 2*max_annular_ring\n\n    if pad_size[1] - drill < 2*min_annular_ring:\n        pad_size[1] = drill + 2*min_annular_ring\n    if pad_size[1] - drill > 2*max_annular_ring:\n        pad_size[1] = drill + 2*max_annular_ring\n\n    pad_shape = Pad.SHAPE_OVAL\n    if pad_size[0] == pad_size[1]:\n        pad_shape = Pad.SHAPE_CIRCLE\n\n    first_to_last_pad_y = (pins_per_row-1)*pitch\n    first_to_last_pad_x = (number_of_rows-1)*row\n\n    center_y = first_to_last_pad_y/2\n    peg_x = (number_of_rows-1)*row + peg_to_nearest_pin\n    peg_pos = [[peg_x, center_y + variant_param['peg_from_center']]]\n    if variant_param['number_pegs'] == 2:\n        peg_pos.append([peg_x, center_y - variant_param['peg_from_center']])\n\n    mpn = variant_param['part_code'][pins_per_row*number_of_rows].format(n=pins_per_row*2)\n\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=man_short_fp_name,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    descr_format_str = \"Molex {:s}, old mpn/engineering number: {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(descr_format_str.format(\n        series_long, mpn, pins_per_row, datasheet))\n    tags = configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=man_short_fp_name,\n        entry=configuration['entry_direction'][orientation])\n    kicad_mod.setTags(tags)\n\n\n    x2 = peg_x + peg_to_body_right\n    x1 = x2 - width\n    body_lenght = 5.72+first_to_last_pad_y\n    y1 = -(body_lenght - first_to_last_pad_y)/2\n    y2 = y1 + body_lenght\n\n    #calculate fp dimensions\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = body_edge.copy()\n    bounding_box['left'] = -pad_size[0]/2\n\n\n    #generate the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(number_of_rows):\n        initial = row_idx*pins_per_row + 1\n        kicad_mod.append(PadArray(\n            pincount=pins_per_row, initial=initial, start=[row_idx*row, 0],\n            y_spacing=pitch, type=Pad.TYPE_THT, shape=pad_shape,\n            size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    for peg in peg_pos:\n        kicad_mod.append(Pad(at=peg, type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n            size=peg_drill, drill=peg_drill, layers=Pad.LAYERS_NPTH))\n\n\n    #draw the outline of the shape\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],\n        layer='F.Fab',width=configuration['fab_line_width']))\n\n    dx = body_edge['left'] - off - (number_of_rows-1)*row - (pad_size[0] - pad_size[1])/2\n\n    if dx < (pad_size[1]/2 + silk_pad_off):\n        dy = sqrt((pad_size[1]/2 + silk_pad_off)**2-dx**2)\n    else:\n        dy = 0\n\n    dy_rect = pad_size[1]/2 + silk_pad_off\n\n    top_silk_pad = -dy if number_of_rows == 2 else -dy_rect\n    bottom_silk_pad = (first_to_last_pad_y + dy) if pins_per_row > 1 else dy_rect\n\n    silk_poly = [\n        {'x': body_edge['left']-off,'y': top_silk_pad},\n        {'x': body_edge['left']-off,'y': body_edge['top']-off},\n        {'x': body_edge['right']+off,'y': body_edge['top']-off},\n        {'x': body_edge['right']+off,'y': body_edge['bottom']+off},\n        {'x': body_edge['left']-off,'y': body_edge['bottom']+off},\n        {'x': body_edge['left']-off,'y': bottom_silk_pad},\n    ]\n    kicad_mod.append(PolygoneLine(polygone=silk_poly,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    for i in range(pins_per_row-1):\n        yt = i*pitch + (dy if number_of_rows == 2 or i > 1 else dy_rect)\n        yb = (i+1)*pitch - dy\n        kicad_mod.append(Line(\n            start=[body_edge['left']-off, yt], end=[body_edge['left']-off, yb],\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n    O = silk_pad_off + 0.2\n\n    pin = [\n        {'x': 0,'y': -pad_size[1]/2 - O},\n        {'x': -pad_size[0]/2 - O,'y': -pad_size[1]/2 - O},\n        {'x': -pad_size[0]/2 - O,'y': 0},\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        layer=\"F.SilkS\", width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=pin,\n        width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n\n    cx1 = roundToBase(bounding_box['left'] - CrtYd_offset, CrtYd_grid)\n    cy1 = roundToBase(bounding_box['top'] - CrtYd_offset, CrtYd_grid)\n\n    cx2 = roundToBase(bounding_box['right'] + CrtYd_offset, CrtYd_grid)\n    cy2 = roundToBase(bounding_box['bottom'] + CrtYd_offset, CrtYd_grid)\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='right')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=man_lib)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        variant_param = variant_params[variant]\n\n        for pins_per_row in variant_param['pins_per_row_range']:\n            generate_one_footprint(pins_per_row, variant_param, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_TE-Connectivity/conn_te_mate-n-lock_tht_top.py",
    "content": "#!/usr/bin/env python3\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt, asin, degrees\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\ndraw_inner_details = False\n\nseries = \"MATE-N-LOK\"\nseries_long = 'Mini-Universal MATE-N-LOK'\nman_lib = 'TE-Connectivity'\nman_short_fp_name = 'TE'\norientation = 'V'\ndatasheet = \"http://www.te.com/commerce/DocumentDelivery/DDEController?Action=srchrtrv&DocNm=82181_SOFTSHELL_HIGH_DENSITY&DocType=CS&DocLang=EN\"\n\n#Molex part number\n#n = number of circuits per row\nvariant_params = {\n    'in_line':{\n        'pins_per_row_range': [2,3],\n        'number_of_rows': 1,\n        'style': 'in_line',\n        'number_pegs': 1,\n        'width': 5.58,\n        'part_code': {\n                2: '1-770866-x',\n                3: '1-770870-x'\n            }\n        },\n    'dual1':{\n        'pins_per_row_range': range(2,7),\n        'number_of_rows': 2,\n        'style': 'dual_row',\n        'number_pegs': 1,\n        'width': 9.83,\n        'part_code': {\n                4: '1-770874-x',\n                6: '1-770875-x',\n                8: '1-794073-x',\n                10: '1-770858-x',\n                12: '1-770621-x'\n            }\n        },\n    'dual2':{\n        'pins_per_row_range': range(7,13),\n        'number_of_rows': 2,\n        'style': 'dual_row',\n        'number_pegs': 2,\n        'width': 9.83,\n        'part_code': {\n                14: '1-794067-x',\n                16: '1-794068-x',\n                18: '1-794069-x',\n                20: '1-794070-x',\n                22: '1-794071-x',\n                24: '1-794072-x'\n            }\n        },\n    'matrix':{\n        'pins_per_row_range': [3,4,5],\n        'number_of_rows': 3,\n        'style': 'matrix',\n        'number_pegs': 1,\n        'width': 13.97,\n        'part_code': {\n                9: '1-770182-x',\n                12: '1-770186-x',\n                15: '1-770190-x'\n            }\n        },\n}\n\npitch = 4.14\ndrill = 1.4\npad_to_pad_clearance = 1.5\nmax_annular_ring = 0.95\nmin_annular_ring = 0.15\nrow = 4.14\n\npeg_drill = 3.18\npeg_to_nearest_pin = 4.44\n\n\ndef generate_one_footprint(pins_per_row, variant_param, configuration):\n    silk_pad_off = configuration['silk_pad_clearance']+configuration['silk_line_width']/2\n    off = configuration['silk_fab_offset']\n\n    number_of_rows = variant_param['number_of_rows']\n\n    pad_size = [row - pad_to_pad_clearance, pitch - pad_to_pad_clearance]\n    if number_of_rows == 1:\n        pad_size[0] = drill + 2*max_annular_ring\n\n    if pad_size[0] - drill < 2*min_annular_ring:\n        pad_size[0] = drill + 2*min_annular_ring\n    if pad_size[0] - drill > 2*max_annular_ring:\n        pad_size[0] = drill + 2*max_annular_ring\n\n    if pad_size[1] - drill < 2*min_annular_ring:\n        pad_size[1] = drill + 2*min_annular_ring\n    if pad_size[1] - drill > 2*max_annular_ring:\n        pad_size[1] = drill + 2*max_annular_ring\n\n    pad_shape = Pad.SHAPE_OVAL\n    if pad_size[0] == pad_size[1]:\n        pad_shape = Pad.SHAPE_CIRCLE\n\n    first_to_last_pad_y = (pins_per_row-1)*pitch\n    first_to_last_pad_x = (number_of_rows-1)*row\n\n    peg_pos = [[0, -peg_to_nearest_pin if variant_param['style'] != 'in_line' else (first_to_last_pad_y + peg_to_nearest_pin)]]\n    if variant_param['number_pegs'] == 2:\n        peg_pos.append([0, first_to_last_pad_y + peg_to_nearest_pin])\n\n    mpn = variant_param['part_code'][pins_per_row*number_of_rows].format(n=pins_per_row*2)\n\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=man_short_fp_name,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pins_per_row, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    descr_format_str = \"Molex {:s}, old mpn/engineering number: {:s}, {:d} Pins per row ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(descr_format_str.format(\n        series_long, mpn, pins_per_row, datasheet))\n    tags = configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=man_short_fp_name,\n        entry=configuration['entry_direction'][orientation])\n    kicad_mod.setTags(tags)\n\n    x1 = -(variant_param['width']-first_to_last_pad_x)/2\n    x2 = x1 + variant_param['width']\n    body_lenght = (9.83-pitch)+first_to_last_pad_y\n    y1 = -(body_lenght - first_to_last_pad_y)/2\n    y2 = y1 + body_lenght\n\n    peg_predrusion = 2.591 # from 3d model\n    peg_d = 3.94 # from 3d model, rounded\n    peg_from_body = 0.66 # from 3d model\n    peg_conn_w = 1.6 # from 3d model, rounded\n    stabalizer_width = 2.54 # from 3d model\n    stabalizer_len = 2.591 # from 3d model\n    TW = 3 # from 3d model, rounded\n    TL = 1.3 # from 3d model, rounded\n    BW = 1.14 # from 3d model, rounded\n    BL = 0.76 # from 3d model, rounded\n\n    #calculate fp dimensions\n    body_edge={\n        'left':x1,\n        'right':x2,\n        'bottom':y2,\n        'top': y1\n        }\n    bounding_box = {}\n    if variant_param['style'] != 'in_line':\n        bounding_box['top'] = peg_pos[0][1]-peg_drill/2\n        bounding_box['left'] = body_edge['left'] - TL\n        bounding_box['right'] = body_edge['right'] + BL\n        if variant_param['number_pegs'] == 2:\n            bounding_box['bottom'] = peg_pos[1][1]+peg_drill/2\n        else:\n            bounding_box['bottom'] = body_edge['bottom'] + peg_predrusion\n    else:\n        bounding_box['bottom'] = peg_pos[0][1]+peg_drill/2\n        bounding_box['top'] = body_edge['top'] - TL\n        bounding_box['left'] = body_edge['left'] - BL\n        bounding_box['right'] = body_edge['right']\n\n\n    #generate the pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for row_idx in range(variant_param['number_of_rows']):\n        initial = row_idx*pins_per_row + 1\n        kicad_mod.append(PadArray(\n            pincount=pins_per_row, initial=initial, start=[row_idx*row, 0],\n            y_spacing=pitch, type=Pad.TYPE_THT, shape=pad_shape,\n            size=pad_size, drill=drill, layers=Pad.LAYERS_THT,\n            **optional_pad_params))\n\n    for peg in peg_pos:\n        kicad_mod.append(Pad(at=peg, type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n            size=peg_drill, drill=peg_drill, layers=Pad.LAYERS_NPTH))\n\n\n    #draw the outline of the shape\n    kicad_mod.append(RectLine(start=[x1,y1],end=[x2,y2],\n        layer='F.Fab',width=configuration['fab_line_width']))\n\n    dy = peg_to_nearest_pin + body_edge['top'] - off\n    if dy < (peg_drill/2 + silk_pad_off):\n        dx = sqrt((peg_drill/2 + silk_pad_off)**2-dy**2)\n    else:\n        dx = 0\n\n    sl_poly=[\n        {'x': 0, 'y': body_edge['top']-off},\n        {'x': body_edge['left']-off, 'y': body_edge['top']-off},\n        {'x': body_edge['left']-off, 'y': body_edge['bottom']+off},\n        {'x': 0, 'y': body_edge['bottom']+off},\n    ]\n    sr_poly=[\n        {'x': 0, 'y': body_edge['top']-off},\n        {'x': body_edge['right']+off, 'y': body_edge['top']-off},\n        {'x': body_edge['right']+off, 'y': body_edge['bottom']+off},\n        {'x': 0, 'y': body_edge['bottom']+off},\n    ]\n    if variant_param['style'] == 'in_line' or variant_param['number_pegs'] == 2:\n        sl_poly[3]['x']=-dx\n        sr_poly[3]['x']=dx\n    if variant_param['style'] != 'in_line':\n        sl_poly[0]['x']=-dx\n        sr_poly[0]['x']=dx\n\n    kicad_mod.append(PolygoneLine(polygone=sl_poly,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n    kicad_mod.append(PolygoneLine(polygone=sr_poly,\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    def peg_outline(kicad_mod, center_y):\n        edge = body_edge['top'] if center_y < 0 else body_edge['bottom']\n        dir = -1 if center_y < 0 else 1\n        sy=edge + dir*peg_from_body\n        y3 = edge +dir*peg_predrusion\n        kicad_mod.append(Line(\n            start=[peg_conn_w/2, edge],\n            end=[peg_conn_w/2, sy],\n            layer='F.Fab',width=configuration['fab_line_width']\n        ))\n        kicad_mod.append(Line(\n            start=[-peg_conn_w/2, edge],\n            end=[-peg_conn_w/2, sy],\n            layer='F.Fab',width=configuration['fab_line_width']\n        ))\n        dy = center_y - sy\n        sx = sqrt((peg_d/2)**2-dy**2)\n        dy2 = y3 - center_y\n        ex = sqrt((peg_d/2)**2-dy2**2)\n        a1 = degrees(asin(abs(dy2)/(peg_d/2)))\n        a2 = degrees(asin(abs(dy)/(peg_d/2)))\n        a = a1+a2\n        kicad_mod.append(Line(\n            start=[sx, sy], end=[-sx, sy],\n            layer='F.Fab',width=configuration['fab_line_width']\n        ))\n        kicad_mod.append(Line(\n            start=[ex, y3], end=[-ex, y3],\n            layer='F.Fab',width=configuration['fab_line_width']\n        ))\n        kicad_mod.append(Arc(center=[0,center_y],\n            start=[sx,sy], angle=dir*a,\n            layer='F.Fab', width=configuration['fab_line_width']))\n        kicad_mod.append(Arc(center=[0,center_y],\n            start=[-sx,sy], angle=-a*dir,\n            layer='F.Fab', width=configuration['fab_line_width']))\n    #\n    #draw the outline of the tab\n    if variant_param['style'] == 'in_line':\n        tab_poly = [\n            {'x': -TW/2,'y': body_edge['top']},\n            {'x': -TW/2,'y': body_edge['top']-TL},\n            {'x': TW/2,'y': body_edge['top']-TL},\n            {'x': TW/2,'y': body_edge['top']},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=tab_poly,\n            layer='F.Fab', width=configuration['fab_line_width']))\n        tab_poly = [\n            {'x': -TW/2-off,'y': body_edge['top']-off},\n            {'x': -TW/2-off,'y': body_edge['top']-TL-off},\n            {'x': TW/2+off,'y': body_edge['top']-TL-off},\n            {'x': TW/2+off,'y': body_edge['top']-off},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=tab_poly,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        b_poly = [\n            {'x': body_edge['left'],'y': body_edge['top']},\n            {'x': body_edge['left']-BL,'y': body_edge['top']},\n            {'x': body_edge['left']-BL,'y': body_edge['top']+BW},\n            {'x': body_edge['left'],'y': body_edge['top']+BW},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=b_poly,\n            layer='F.Fab', width=configuration['fab_line_width']))\n        b_poly = [\n            {'x': body_edge['left']-off,'y': body_edge['top']-off},\n            {'x': body_edge['left']-BL-off,'y': body_edge['top']-off},\n            {'x': body_edge['left']-BL-off,'y': body_edge['top']+BW+off},\n            {'x': body_edge['left']-off,'y': body_edge['top']+BW+off},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=b_poly,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        for i in range(pins_per_row):\n            yc = i*pitch+pitch/2\n            b_poly = [\n                {'x': body_edge['left'],'y': yc - BW/2},\n                {'x': body_edge['left']-BL,'y': yc - BW/2},\n                {'x': body_edge['left']-BL,'y': yc + BW/2},\n                {'x': body_edge['left'],'y': yc + BW/2},\n            ]\n            kicad_mod.append(PolygoneLine(polygone=b_poly,\n                layer='F.Fab', width=configuration['fab_line_width']))\n            b_poly = [\n                {'x': body_edge['left']-off,'y': yc - BW/2-off},\n                {'x': body_edge['left']-BL-off,'y': yc - BW/2-off},\n                {'x': body_edge['left']-BL-off,'y': yc + BW/2+off},\n                {'x': body_edge['left']-off,'y': yc + BW/2+off},\n            ]\n            kicad_mod.append(PolygoneLine(polygone=b_poly,\n                layer='F.SilkS', width=configuration['silk_line_width']))\n    else:\n        cy = first_to_last_pad_y/2\n        tab_poly = [\n            {'x': body_edge['left'],'y': cy-TW/2},\n            {'x': body_edge['left']-TL,'y': cy-TW/2},\n            {'x': body_edge['left']-TL,'y': cy+TW/2},\n            {'x': body_edge['left'],'y': cy+TW/2},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=tab_poly,\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n        tab_poly = [\n            {'x': body_edge['left']-off,'y': cy-TW/2-off},\n            {'x': body_edge['left']-TL-off,'y': cy-TW/2-off},\n            {'x': body_edge['left']-TL-off,'y': cy+TW/2+off},\n            {'x': body_edge['left']-off,'y': cy+TW/2+off},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=tab_poly,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n\n        b_poly = [\n            {'x': body_edge['right'],'y': body_edge['top']},\n            {'x': body_edge['right']+BL,'y': body_edge['top']},\n            {'x': body_edge['right']+BL,'y': body_edge['top']+BW},\n            {'x': body_edge['right'],'y': body_edge['top']+BW},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=b_poly,\n            layer='F.Fab', width=configuration['fab_line_width']))\n\n        b_poly = [\n            {'x': body_edge['right']+off,'y': body_edge['top']-off},\n            {'x': body_edge['right']+BL+off,'y': body_edge['top']-off},\n            {'x': body_edge['right']+BL+off,'y': body_edge['top']+BW+off},\n            {'x': body_edge['right']+off,'y': body_edge['top']+BW+off},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=b_poly,\n            layer='F.SilkS', width=configuration['silk_line_width']))\n        if len(peg_pos) == 1:\n            center_stabalizer = (number_of_rows-1)*row\n            stab_x1 = center_stabalizer - stabalizer_width/2\n            stab_x2 = center_stabalizer + stabalizer_width/2\n            stab_y1 = body_edge['bottom'] + stabalizer_len\n            stab_poly = [\n                {'x': stab_x1,'y': body_edge['bottom']},\n                {'x': stab_x1,'y': stab_y1},\n                {'x': stab_x2,'y': stab_y1},\n                {'x': stab_x2,'y': body_edge['bottom']}\n            ]\n            kicad_mod.append(PolygoneLine(polygone=stab_poly,\n                layer='F.Fab', width=configuration['fab_line_width']))\n            stab_poly = [\n                {'x': stab_x1-off,'y': body_edge['bottom']+off},\n                {'x': stab_x1-off,'y': stab_y1+off},\n                {'x': stab_x2+off,'y': stab_y1+off},\n                {'x': stab_x2+off,'y': body_edge['bottom']+off}\n            ]\n            kicad_mod.append(PolygoneLine(polygone=stab_poly,\n                layer='F.SilkS', width=configuration['silk_line_width']))\n\n        for i in range(pins_per_row):\n            yc = i*pitch+pitch/2\n            b_poly = [\n                {'x': body_edge['right'],'y': yc - BW/2},\n                {'x': body_edge['right']+BL,'y': yc - BW/2},\n                {'x': body_edge['right']+BL,'y': yc + BW/2},\n                {'x': body_edge['right'],'y': yc + BW/2},\n            ]\n            kicad_mod.append(PolygoneLine(polygone=b_poly,\n                layer='F.Fab', width=configuration['fab_line_width']))\n\n            b_poly = [\n                {'x': body_edge['right']+off,'y': yc - BW/2-off},\n                {'x': body_edge['right']+BL+off,'y': yc - BW/2-off},\n                {'x': body_edge['right']+BL+off,'y': yc + BW/2+off},\n                {'x': body_edge['right']+off,'y': yc + BW/2+off},\n            ]\n            kicad_mod.append(PolygoneLine(polygone=b_poly,\n                layer='F.SilkS', width=configuration['silk_line_width']))\n\n    for peg in peg_pos:\n        peg_outline(kicad_mod, peg[1])\n\n\n\n    if variant_param['style'] != 'in_line':\n        L = 2.5\n        O = off + 0.3\n        dy = peg_to_nearest_pin + body_edge['top'] - O\n        if dy < (peg_drill/2 + silk_pad_off):\n            dx = sqrt((peg_drill/2 + silk_pad_off)**2-dy**2)\n\n        pin = [\n            {'x': -dx,'y': body_edge['top'] - O},\n            {'x': body_edge['left'] - O,'y': body_edge['top'] - O},\n            {'x': body_edge['left'] - O,'y': body_edge['top'] + L}\n        ]\n    else:\n        sl = 0.6\n        xs = body_edge['left']-(off + 0.3)\n        pin = [\n            {'x': xs,'y': 0},\n            {'x': xs - sl/sqrt(2),'y': sl/2},\n            {'x': xs - sl/sqrt(2),'y': -sl/2},\n            {'x': xs,'y': 0}\n        ]\n\n\n    kicad_mod.append(PolygoneLine(polygone=pin, layer=\"F.SilkS\", width=configuration['silk_line_width']))\n\n    sl = 2\n    pin = [\n        {'x': body_edge['left'],'y': -sl/2},\n        {'x': body_edge['left'] +sl/sqrt(2),'y': 0},\n        {'x': body_edge['left'],'y': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=pin, width=configuration['fab_line_width'], layer='F.Fab'))\n\n    ########################### CrtYd #################################\n    CrtYd_offset = configuration['courtyard_offset']['connector']\n    CrtYd_grid = configuration['courtyard_grid']\n\n    cx1 = roundToBase(bounding_box['left'] - CrtYd_offset, CrtYd_grid)\n    cy1 = roundToBase(bounding_box['top'] - CrtYd_offset, CrtYd_grid)\n\n    cx2 = roundToBase(bounding_box['right'] + CrtYd_offset, CrtYd_grid)\n    cy2 = roundToBase(bounding_box['bottom'] + CrtYd_offset, CrtYd_grid)\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='right')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=man_lib)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for variant in variant_params:\n        variant_param = variant_params[variant]\n\n        for pins_per_row in variant_param['pins_per_row_range']:\n            generate_one_footprint(pins_per_row, variant_param, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_TE-Connectivity/helpers.py",
    "content": "def roundToBase(value, base):\n    if base == 0:\n        return value\n    return round(value/base) * base\n"
  },
  {
    "path": "scripts/Connector/Connector_Wago/conn_wago_734_horizontal.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"\"\nseries_long = '734 Male header (for PCBs); Angled solder pin 1 x 1 mm'\nmanufacturer = 'Wago'\norientation = 'H'\nnumber_of_rows = 1\ndatasheet = 'http://www.farnell.com/datasheets/2157639.pdf'\n\npinrange= [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 24]\n\n\n# Connector voltage ratings:\n# Rated voltage  (III / 3) [V]           160 V\n# Rated impulse voltage (III / 3) [kV]   2.5 kV\n\n# Rated voltage (III/2) [V]              160 V\n# Rated impulse voltage (III / 2) [kV]   2.5 kV\n\n# Rated voltage (II / 2) [V]             320 V\n# Rated impulse voltage (II / 2) [kV]    2.5 kV\n\n# VDE 0110-1/4.97 2.5kV -> 1.5mm clearance\npad_to_pad_clearance = 1.5\n\npitch = 3.5\ndrill = 1.6 # square pins:1mm -> touching circle: √(2)mm ~ 1.4mm -> minimum drill accourding to KLC: 1.6mm\n\nstart_pos_x = 0\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\nmpn_format = '734-1{n_plus_60:02d}'\n\ndef generate_one_footprint(pincount, configuration):\n    pad_silk_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    mpn = mpn_format.format(n_plus_60=pincount+60)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    footprint_name = footprint_name.replace(\"__\", '_')\n\n    kicad_mod = Footprint(footprint_name)\n    descr_format_str = \"Molex {:s}, {:s} , {:d} Pins ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(descr_format_str.format(series_long, mpn, pincount, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    # calculate working values\n    end_pos_x = (pincount-1) * pitch\n    centre_x = (end_pos_x - start_pos_x) / 2.0\n    nudge = configuration['silk_fab_offset']\n    silk_w = configuration['silk_line_width']\n    fab_w = configuration['fab_line_width']\n\n\n    body_edge={\n        'left':start_pos_x - 2.8,\n        'right':end_pos_x + 3.1,\n        'bottom':9.3\n        }\n    body_edge['top'] = body_edge['bottom']-10.3\n\n    # create pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[start_pos_x, 0],\n        x_spacing=pitch, pincount=pincount,\n        size=pad_size, drill=drill,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    # create fab outline\n    kicad_mod.append(RectLine(start=[body_edge['left'], body_edge['top']],\n        end=[body_edge['right'], body_edge['bottom']], layer='F.Fab', width=fab_w))\n\n    # create silkscreen\n    x1 = start_pos_x -pad_size[0]/2 - pad_silk_off\n    xn = end_pos_x + pad_size[0]/2 + pad_silk_off\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': x1, 'y': body_edge['top']-nudge},\n            {'x': body_edge['left']-nudge, 'y': body_edge['top']-nudge},\n            {'x': body_edge['left']-nudge, 'y': body_edge['bottom']+nudge},\n            {'x': body_edge['right']+nudge, 'y': body_edge['bottom']+nudge},\n            {'x': body_edge['right']+nudge, 'y': body_edge['top']-nudge},\n            {'x': xn, 'y': body_edge['top']-nudge}\n        ], layer='F.SilkS', width=silk_w))\n\n    for i in range(pincount-1):\n        xl = start_pos_x + i*pitch + pad_size[0]/2 + pad_silk_off\n        xr = start_pos_x + (i+1)*pitch - pad_size[0]/2 - pad_silk_off\n        kicad_mod.append(Line(\n            start=[xl, body_edge['top']-nudge],\n            end=[xr, body_edge['top']-nudge],\n            layer='F.SilkS', width=silk_w))\n\n\n    p1s_off = configuration['silk_fab_offset'] + 0.3\n    p1s_L = 2\n    # pin 1 markers\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': body_edge['left'] - p1s_off, 'y': body_edge['top'] + p1s_L},\n            {'x': body_edge['left'] - p1s_off, 'y': body_edge['top'] - p1s_off},\n            {'x': x1, 'y': body_edge['top'] - p1s_off}\n        ],\n        layer='F.SilkS', width=silk_w))\n\n    sl = 1\n    poly_pin1_marker = [\n        {'y': body_edge['top'], 'x': -sl/2},\n        {'y': body_edge['top'] + sl/sqrt(2), 'x': 0},\n        {'y': body_edge['top'], 'x': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.Fab', width=fab_w))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(body_edge['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(body_edge['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(body_edge['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(body_edge['bottom']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pinrange:\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Wago/conn_wago_734_vertical.py",
    "content": "#!/usr/bin/env python3\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nfrom math import sqrt\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"\"\nseries_long = '734 Male header (for PCBs); Straight solder pin 1 x 1 mm'\nmanufacturer = 'Wago'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'http://www.farnell.com/datasheets/2157639.pdf'\n\npinrange= [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 24]\n\n\n# Connector voltage ratings:\n# Rated voltage  (III / 3) [V]           160 V\n# Rated impulse voltage (III / 3) [kV]   2.5 kV\n\n# Rated voltage (III/2) [V]              160 V\n# Rated impulse voltage (III / 2) [kV]   2.5 kV\n\n# Rated voltage (II / 2) [V]             320 V\n# Rated impulse voltage (II / 2) [kV]    2.5 kV\n\n# VDE 0110-1/4.97 2.5kV -> 1.5mm clearance\npad_to_pad_clearance = 1.5\n\npitch = 3.5\ndrill = 1.6 # square pins:1mm -> touching circle: √(2)mm ~ 1.4mm -> minimum drill accourding to KLC: 1.6mm\n\nstart_pos_x = 0\nmax_annular_ring = 0.5\nmin_annular_ring = 0.15\n\npad_size = [pitch - pad_to_pad_clearance, drill + 2*max_annular_ring]\nif pad_size[0] - drill < 2*min_annular_ring:\n    pad_size[0] = drill + 2*min_annular_ring\nif pad_size[0] - drill > 2*max_annular_ring:\n    pad_size[0] = drill + 2*max_annular_ring\n\npad_shape=Pad.SHAPE_OVAL\nif pad_size[1] == pad_size[0]:\n    pad_shape=Pad.SHAPE_CIRCLE\n\nmpn_format = '734-1{n_plus_30:02d}'\n\ndef generate_one_footprint(pincount, configuration):\n\n    mpn = mpn_format.format(n_plus_30=pincount+30)\n\n    # handle arguments\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    footprint_name = footprint_name.replace(\"__\", '_')\n\n    kicad_mod = Footprint(footprint_name)\n    descr_format_str = \"Molex {:s}, {:s} , {:d} Pins ({:s}), generated with kicad-footprint-generator\"\n    kicad_mod.setDescription(descr_format_str.format(series_long, mpn, pincount, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    # calculate working values\n    end_pos_x = (pincount-1) * pitch\n    centre_x = (end_pos_x - start_pos_x) / 2.0\n    nudge = configuration['silk_fab_offset']\n    silk_w = configuration['silk_line_width']\n    fab_w = configuration['fab_line_width']\n\n\n    body_edge={\n        'left':start_pos_x - 2.8,\n        'right':end_pos_x + 3.1,\n        'bottom':4.35\n        }\n    body_edge['top'] = body_edge['bottom']-8.5\n\n    # create pads\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[start_pos_x, 0],\n        x_spacing=pitch, pincount=pincount,\n        size=pad_size, drill=drill,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    # create fab outline\n    kicad_mod.append(RectLine(start=[body_edge['left'], body_edge['top']],\\\n        end=[body_edge['right'], body_edge['bottom']], layer='F.Fab', width=fab_w))\n\n    # create silkscreen\n    kicad_mod.append(RectLine(start=[body_edge['left']-nudge, body_edge['top']-nudge],\\\n        end=[body_edge['right']+nudge, body_edge['bottom']+nudge], layer='F.SilkS', width=silk_w))\n\n    # Inner silk:\n    T = 0.5\n    w1 = body_edge['right'] - end_pos_x - T\n    y1 = body_edge['top'] + 1.5\n    y2 = body_edge['bottom'] - 1.5\n    y3 = body_edge['bottom'] - T\n    x1 = body_edge['left'] + T\n    x2 = start_pos_x\n    x3 = x2 + w1\n    x4 = end_pos_x\n    x5 = x4 + w1\n\n    poly_inside = [\n        {'x': x1, 'y':y1},\n        {'x': x1, 'y':y2},\n        {'x': x2, 'y':y2},\n        {'x': x2, 'y':y3},\n        {'x': x3, 'y':y3},\n        {'x': x3, 'y':y2},\n        {'x': x4, 'y':y2},\n        {'x': x4, 'y':y3},\n        {'x': x5, 'y':y3},\n        {'x': x5, 'y':y1},\n        {'x': x1, 'y':y1}\n    ]\n\n    kicad_mod.append(PolygoneLine(polygone=poly_inside, layer='F.SilkS', width=silk_w))\n\n    p1s_off = configuration['silk_fab_offset'] + 0.3\n    p1s_L = 2\n    # pin 1 markers\n    kicad_mod.append(PolygoneLine(\n        polygone=[\n            {'x': body_edge['left'] - p1s_off, 'y': body_edge['top'] + p1s_L},\n            {'x': body_edge['left'] - p1s_off, 'y': body_edge['top'] - p1s_off},\n            {'x': body_edge['left'] + p1s_L, 'y': body_edge['top'] - p1s_off}\n        ],\n        layer='F.SilkS', width=silk_w))\n\n    sl = 1\n    poly_pin1_marker = [\n        {'y': body_edge['top'], 'x': -sl/2},\n        {'y': body_edge['top'] + sl/sqrt(2), 'x': 0},\n        {'y': body_edge['top'], 'x': sl/2}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.Fab', width=fab_w))\n\n    ########################### CrtYd #################################\n    cx1 = roundToBase(body_edge['left']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(body_edge['top']-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(body_edge['right']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(body_edge['bottom']+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n    ######################### Text Fields ###############################\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position='bottom')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in pinrange:\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Wago/helpers.py",
    "content": "def roundToBase(value, base):\n    if base == 0:\n        return value\n    return round(value/base) * base\n"
  },
  {
    "path": "scripts/Connector/Connector_Wire/Research/sources.md",
    "content": "- https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf\n\n- http://www.farnell.com/datasheets/1772974.pdf\n- http://www.farnell.com/datasheets/2818581.pdf\n- http://www.farnell.com/datasheets/1872097.pdf\n- http://www.farnell.com/datasheets/2198328.pdf\n"
  },
  {
    "path": "scripts/Connector/Connector_Wire/solder_wire_tht.py",
    "content": "import sys\nimport os\nimport argparse\nimport yaml\nimport math\n\nfrom copy import deepcopy\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.util.geometric_util import geometricLine, geometricCircle\nfrom KicadModTree.util.paramUtil import round_to\n\n # load parent path of tools\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))\nfrom footprint_text_fields import addTextFields\n\nDEFAULT_MIN_PAD_DRILL_INC = 0.2\nDEFAULT_PAD_DRILL_INC_FACTOR = 1.25\nDEFAULT_RELIEF_DRILL_INC = 0.5\n\nFOOTPRINT_TYPES = {\n    'plain':{\n        'name': '',\n        'description': '',\n        'tag': '',\n        'relief_count': 0\n    },\n    'relief':{\n        'name': '_Relief',\n        'description': ' with feed through strain relief',\n        'tag': ' strain-relief',\n        'relief_count': 1\n    },\n    'relief2x':{\n        'name': '_Relief2x',\n        'description': ' with double feed through strain relief',\n        'tag': ' double-strain-relief',\n        'relief_count': 2\n    }\n}\n\ndef bend_radius(wire_def):\n    return wire_def['outer_diameter'] * 3\n\ndef fp_name_gen(wire_def, fp_type, pincount, pitch):\n    if 'area' in wire_def:\n        size_code = '{:g}sqmm'.format(wire_def['area'])\n\n    return 'SolderWire-{}_1x{:02d}{}_D{:g}mm_OD{:g}mm{}'.format(\n                    size_code, pincount,\n                    '' if pincount == 1 else '_P{:g}mm'.format(pitch),\n                    wire_def['diameter'], wire_def['outer_diameter'], fp_type\n                )\n\ndef description_gen(wire_def, fp_type, pincount, pitch):\n    if 'area' in wire_def:\n        size_code = '{:g} mm²'.format(wire_def['area'])\n\n    d1 = 'for a single {size:s} wire' if pincount == 1 else 'for {count:d} times {size:s} wires'\n\n    return (\n        'Soldered wire connection{}, {}, '\n        '{} insulation, '\n        'conductor diameter {:g}mm, outer diameter {:g}mm, '\n        'size source {}, '\n        'bend radius 3 times outer diameter, '\n        'generated with kicad-footprint-generator'\n        .format(\n                fp_type, d1.format(count=pincount, size=size_code),\n                wire_def['insulation'],\n                wire_def['diameter'], wire_def['outer_diameter'],\n                wire_def['source']\n            )\n    )\n\ndef tag_gen(wire_def, fp_type, pincount, pitch):\n    if 'area' in wire_def:\n        size_code = '{:g}sqmm'.format(wire_def['area'])\n\n    return 'connector wire {}{}'.format(size_code, fp_type)\n\ndef make_fp(wire_def, fp_type, pincount, configuration):\n    crtyd_off= configuration['courtyard_offset']['connector']\n    silk_pad_off = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n\n    pad_drill = max(wire_def['diameter'] + configuration['min_pad_drill_inc'],\n                    wire_def['diameter'] * configuration['pad_drill_factor'])\n    pad_drill = round_to(pad_drill, 0.05)\n    pad_size = max(pad_drill + 1, wire_def['outer_diameter'])\n\n    npth_drill = wire_def['outer_diameter'] + configuration['relief_drill_inc']\n    npth_drill = round_to(npth_drill, 0.05)\n    npth_offset = bend_radius(wire_def)*2\n\n    pitch = max(2*wire_def['outer_diameter'], pad_size+2, npth_drill+2)\n\n    fp_name = fp_name_gen(wire_def, fp_type['name'], pincount, pitch)\n\n    kicad_mod = Footprint(fp_name)\n    kicad_mod.setDescription(description_gen(wire_def, fp_type['description'], pincount, pitch))\n\n    kicad_mod.setTags(tag_gen(wire_def, fp_type['tag'], pincount, pitch))\n\n    kicad_mod.setAttribute('virtual')\n\n    prototype = Translation(0, 0)\n    kicad_mod.append(PadArray(\n            initial=1, increment=1, pincount=pincount,\n            type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n            start=(0, 0), spacing=(pitch, 0),\n            drill=pad_drill, size=pad_size,\n            radius_ratio=0.25, maximum_radius=0.25,\n            layers=Pad.LAYERS_THT\n        ))\n\n    for i in range(fp_type['relief_count']):\n        prototype.append(Pad(\n                number='', type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\n                at=(0, (i+1)*npth_offset), drill=npth_drill, size=npth_drill,\n                layers=Pad.LAYERS_NPTH\n            ))\n\n    ######################### Fab Graphic ###############################\n    for i in range(fp_type['relief_count']+1):\n        prototype.append(Circle(\n                center=(0, i*npth_offset), radius=wire_def['outer_diameter']/2,\n                layer='F.Fab', width=configuration['fab_line_width']\n            ))\n\n    # wire on top side\n    if fp_type['relief_count']>0:\n        for i in range((fp_type['relief_count']+1)//2):\n            sy = 2*i * npth_offset\n            ey = (2*i+1) * npth_offset\n            prototype.append(Line(\n                    start=(-wire_def['outer_diameter']/2, sy),\n                    end=(-wire_def['outer_diameter']/2, ey),\n                    layer='F.Fab', width=configuration['fab_line_width']\n                ))\n            prototype.append(Line(\n                    start=(wire_def['outer_diameter']/2, sy),\n                    end=(wire_def['outer_diameter']/2, ey),\n                    layer='F.Fab', width=configuration['fab_line_width']\n                ))\n\n    if fp_type['relief_count']>1:\n        for i in range(fp_type['relief_count']):\n            prototype.append(Circle(\n                    center=(0, (i+1)*npth_offset), radius=wire_def['outer_diameter']/2,\n                    layer='B.Fab', width=configuration['fab_line_width']\n                ))\n        for i in range((fp_type['relief_count'])//2):\n            sy = (2*i+1) * npth_offset\n            ey = (2*i+2) * npth_offset\n            prototype.append(Line(\n                    start=(-wire_def['outer_diameter']/2, sy),\n                    end=(-wire_def['outer_diameter']/2, ey),\n                    layer='B.Fab', width=configuration['fab_line_width']\n                ))\n            prototype.append(Line(\n                    start=(wire_def['outer_diameter']/2, sy),\n                    end=(wire_def['outer_diameter']/2, ey),\n                    layer='B.Fab', width=configuration['fab_line_width']\n                ))\n\n    ######################### Silk Graphic ##############################\n\n    silk_x = wire_def['outer_diameter']/2 + configuration['silk_fab_offset']\n\n    silk_helper_line = geometricLine(start=(silk_x, 0), end=(silk_x, npth_offset))\\\n        .cut(geometricCircle(center=(0,0), radius=(npth_drill/2 + silk_pad_off)))[1]\n\n    silk_y_rel_npth = silk_helper_line.start_pos['x']\n\n    if fp_type['relief_count']>0:\n        if silk_x > pad_size/2 + silk_pad_off:\n            top = 0\n        else:\n            top = pad_size/2 + silk_pad_off\n\n        bottom = npth_offset - silk_y_rel_npth\n        prototype.append(Line(\n                start=(silk_x, top), end=(silk_x, bottom),\n                layer='F.SilkS', width=configuration['silk_line_width']\n            ))\n        prototype.append(Line(\n                start=(-silk_x, top), end=(-silk_x, bottom),\n                layer='F.SilkS', width=configuration['silk_line_width']\n            ))\n\n    if fp_type['relief_count']>1:\n        for i in range(fp_type['relief_count']-1):\n            layer = 'F.SilkS' if i%2 == 1 else 'B.SilkS'\n\n            top = (i+1)*npth_offset + silk_y_rel_npth\n            bottom = (i+2)*npth_offset - silk_y_rel_npth\n\n            prototype.append(Line(\n                    start=(silk_x, top), end=(silk_x, bottom),\n                    layer=layer, width=configuration['silk_line_width']\n                ))\n            prototype.append(Line(\n                    start=(-silk_x, top), end=(-silk_x, bottom),\n                    layer=layer, width=configuration['silk_line_width']\n                ))\n\n    ########################## Courtyard ################################\n\n    crtyd_x = max(pad_size, npth_drill)/2 + crtyd_off\n    crtyd_top = -max(pad_size, wire_def['outer_diameter'])/2 - crtyd_off\n    crtyd_top_main = crtyd_top\n    if fp_type['relief_count'] == 0:\n        crtyd_bottom = -crtyd_top\n        crtyd_bottom_main = crtyd_bottom\n    else:\n        crtyd_bottom = npth_offset + npth_drill/2 + crtyd_off\n        crtyd_bottom_main = npth_offset*fp_type['relief_count'] + npth_drill/2 + crtyd_off\n\n    layer = 'F.CrtYd'\n    prototype.append(RectLine(\n            start=Vector2D(-crtyd_x, crtyd_top).round_to(configuration['courtyard_grid']),\n            end=Vector2D(crtyd_x, crtyd_bottom).round_to(configuration['courtyard_grid']),\n            layer=layer, width=configuration['courtyard_line_width']\n        ))\n\n    if fp_type['relief_count']>0:\n        i = fp_type['relief_count']\n        layer = 'B.CrtYd' if i%2 == 1 else 'F.CrtYd'\n\n        crtyd_top = (i)*npth_offset - (npth_drill/2 + crtyd_off)\n        crtyd_bottom = (i)*npth_offset + npth_drill/2 + crtyd_off\n\n        prototype.append(RectLine(\n                start=Vector2D(-crtyd_x, crtyd_top).round_to(configuration['courtyard_grid']),\n                end=Vector2D(crtyd_x, crtyd_bottom).round_to(configuration['courtyard_grid']),\n                layer=layer, width=configuration['courtyard_line_width']\n            ))\n\n    if fp_type['relief_count']>1:\n        for i in range(fp_type['relief_count']-1):\n            layer = 'F.CrtYd' if i%2 == 1 else 'B.CrtYd'\n\n            crtyd_top = (i+1)*npth_offset - (npth_drill/2 + crtyd_off)\n            crtyd_bottom = (i+2)*npth_offset + npth_drill/2 + crtyd_off\n\n            prototype.append(RectLine(\n                    start=Vector2D(-crtyd_x, crtyd_top).round_to(configuration['courtyard_grid']),\n                    end=Vector2D(crtyd_x, crtyd_bottom).round_to(configuration['courtyard_grid']),\n                    layer=layer, width=configuration['courtyard_line_width']\n                ))\n\n\n    ######################### Text Fields ###############################\n    center_x = (pincount-1)*pitch/2\n\n    y1 = -wire_def['outer_diameter']/2\n    y2 = wire_def['outer_diameter']/2 + (npth_offset if fp_type['relief_count'] > 0 else 0)\n\n    if pincount%2 == 0 and fp_type['relief_count'] == 0:\n        y1 = crtyd_top_main\n        y2 = crtyd_bottom_main\n\n    addTextFields(\n        kicad_mod=kicad_mod, configuration=configuration,\n        body_edges={\n            'left':center_x - wire_def['outer_diameter']/2,\n            'right':center_x + wire_def['outer_diameter']/2,\n            'top':y1,\n            'bottom':y2\n            },\n        courtyard={'top':crtyd_top_main, 'bottom':crtyd_bottom_main},\n        fp_name=fp_name, text_y_inside_position='center',\n        allow_rotation=True\n        )\n\n    ##################### Output and 3d model ############################\n    for i in range(pincount):\n        prototype.offset_x = i*pitch\n        kicad_mod.append(deepcopy(prototype))\n\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = 'Connector_Wire'\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=fp_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir):\n        #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n\n    filename = '{outdir:s}{fp_name:s}.kicad_mod'\\\n            .format(outdir=output_dir, fp_name=fp_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\ndef make_for_wire(wire_def, configuration):\n    for fp_type in FOOTPRINT_TYPES:\n        for i in range(6):\n            make_fp(wire_def, FOOTPRINT_TYPES[fp_type], i+1, configuration)\n\ndef make_for_file(filepath, configuration):\n    with open(filepath, 'r') as wire_definition:\n        try:\n            wires = yaml.safe_load(wire_definition)\n            for w in wires:\n                make_for_wire(wires[w], configuration)\n        except yaml.YAMLError as exc:\n            print(exc)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(\n        description='Create footprints for directly soldering wires to a PCB.'\n        )\n    parser.add_argument(\n        'wire_def', metavar='wire_def', type=str, nargs='+',\n        help='Wire definition files'\n        )\n    parser.add_argument(\n        '--global_config', type=str, nargs='?',\n        help='The config file defining how the footprint will look like. (KLC)',\n        default='../../tools/global_config_files/config_KLCv3.0.yaml'\n        )\n    parser.add_argument(\n        '--minimum_pad_drill_oversize', type=float, default=DEFAULT_MIN_PAD_DRILL_INC,\n        help='Determines the minimum for how much the pads PTH drill is increased compared to conductor diameter.'\n        )\n    parser.add_argument(\n        '--pad_drill_factor', type=float, default=DEFAULT_PAD_DRILL_INC_FACTOR,\n        help='Determines the multiplicator for pad drill size compared to conductor diameter'\n        )\n    parser.add_argument(\n        '--relief_drill_oversize', type=float, default=DEFAULT_RELIEF_DRILL_INC,\n        help='Determines how much the relief NPTH drill is increased compared to outer diameter.'\n        )\n\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['pad_drill_factor'] = args.pad_drill_factor\n    configuration['min_pad_drill_inc'] = args.minimum_pad_drill_oversize\n    configuration['relief_drill_inc'] = args.relief_drill_oversize\n\n    for filepath in args.wire_def:\n        make_for_file(filepath, configuration)\n"
  },
  {
    "path": "scripts/Connector/Connector_Wire/wire_MC_Flexivolt.yaml",
    "content": "\"FLEXI-E_0.1\":\n  source: 'Multi-Contact FLEXI-E 0.1 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'basic'\n  area: 0.1\n  #awg:\n  diameter: 0.4\n  outer_diameter: 1\n\n\"FLEXI-E/HK_0.127\":\n  source: 'Multi-Contact FLEXI-E/HK 0.127 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'basic'\n  area: 0.127\n  #awg:\n  diameter: 0.48\n  outer_diameter: 1\n\n\"FLEXI-E_0.15\":\n  source: 'Multi-Contact FLEXI-E 0.15 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'basic'\n  area: 0.15\n  #awg:\n  diameter: 0.5\n  outer_diameter: 1.5\n\n\"FLEXI-E_0.25\":\n  source: 'Multi-Contact FLEXI-E_0.25 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'basic'\n  area: 0.25\n  #awg:\n  diameter: 0.65\n  outer_diameter: 1.7\n\n\"FLEXI-E_0.5\":\n  source: 'Multi-Contact FLEXI-E 0.5 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'basic'\n  area: 0.5\n  #awg:\n  diameter: 0.9\n  outer_diameter: 2.1\n\n\"FLEXI-E_0.75\":\n  source: 'Multi-Contact FLEXI-E 0.75 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'basic'\n  area: 0.75\n  #awg:\n  diameter: 1.25\n  outer_diameter: 2.3\n\n\"FLEXI-E_1\":\n  source: 'Multi-Contact FLEXI-E 1.0 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'basic'\n  area: 1\n  #awg:\n  diameter: 1.4\n  outer_diameter: 2.7\n\n\"FLEXI-E_1.5\":\n  source: 'Multi-Contact FLEXI-E 1.5 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'basic'\n  area: 1.5\n  #awg:\n  diameter: 1.7\n  outer_diameter: 3\n\n\"FLEXI-E_2.5\":\n  source: 'Multi-Contact FLEXI-E 2.5 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'basic'\n  area: 2.5\n  #awg:\n  diameter: 2.4\n  outer_diameter: 3.6\n\n\"FLEXI-2V_0.25\":\n  source: 'Multi-Contact FLEXI-2V 0.25 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'reinforced'\n  area: 0.25\n  #awg:\n  diameter: 0.65\n  outer_diameter: 2\n\n\"FLEXI-xV_0.5\":\n  source: 'Multi-Contact FLEXI-xV 0.5 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'reinforced'\n  area: 0.5\n  #awg:\n  diameter: 0.9\n  outer_diameter: 2.3\n\n\"FLEXI-xV_0.75\":\n  source: 'Multi-Contact FLEXI-xV 0.75 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'reinforced'\n  area: 0.75\n  #awg:\n  diameter: 1.25\n  outer_diameter: 3.5\n\n\"FLEXI-xV_1.0\":\n  source: 'Multi-Contact FLEXI-xV 1.0 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'reinforced'\n  area: 1\n  #awg:\n  diameter: 1.4\n  outer_diameter: 3.9\n\n\"FLEXI-xV_1.5\":\n  source: 'Multi-Contact FLEXI-xV 1.5 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'reinforced'\n  area: 1.5\n  #awg:\n  diameter: 1.7\n  outer_diameter: 3.9\n\n\"FLEXI-xV_2.0\":\n  source: 'Multi-Contact FLEXI-xV 2.0 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'reinforced'\n  area: 2.0\n  #awg:\n  diameter: 2.0\n  outer_diameter: 3.9\n\n\"FLEXI-xV_2.5\":\n  source: 'Multi-Contact FLEXI-xV 2.5 (https://ec.staubli.com/AcroFiles/Catalogues/TM_Cab-Main-11014119_(en)_hi.pdf)'\n  insulation: 'reinforced'\n  area: 2.5\n  #awg:\n  diameter: 2.4\n  outer_diameter: 4.4\n"
  },
  {
    "path": "scripts/Connector/Connector_Wuerth/wuerth_6480xx11622.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"WR-WTB\"\nmanufacturer = 'Wuerth'\norientation = 'V'\nnumber_of_rows = 1\ndatasheet = 'https://katalog.we-online.com/em/datasheet/6480xx11622.pdf'\nmpn_pattern = \"6480{n:02}11622\"\n\nfab_pin1_marker_type = 2\npin1_marker_offset = 0.3\npin1_marker_linelen = 1.25\n\ndrill_size = 0.87 #Datasheet: 0.7 +0.1/-0.0 => It might be better to assume 0.75 +/-0.05mm\npad_to_pad_clearance = 0.8\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\n\n\npitch = 1.5\n\n# Connector Parameters\nx_min = -1.5\ny_min = -1.3\ny_max = y_min + 3.5\n\ndef roundToBase(value, base):\n    return round(value/base) * base\n\ndef generate_one_footprint(pincount, configuration):\n    silk_x_min = x_min - configuration['silk_fab_offset']\n    silk_y_min = y_min - configuration['silk_fab_offset']\n    silk_y_max = y_max + configuration['silk_fab_offset']\n\n\n    x_mid = (pincount-1)*pitch/2.0\n    x_max = (pincount-1)*pitch + 1.5\n    silk_x_max = x_max + configuration['silk_fab_offset']\n\n    # Through-hole type shrouded header, Top entry type\n    mpn = mpn_pattern.format(n=pincount) # part number format string\n    orientation_str = configuration['orientation_options'][orientation]\n    footprint_name = configuration['fp_name_format_string'].format(man=manufacturer,\n        series=series,\n        mpn=mpn, num_rows=number_of_rows, pins_per_row=pincount, mounting_pad = \"\",\n        pitch=pitch, orientation=orientation_str)\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"{:s} {:s} series connector, {:s} ({:s}), generated with kicad-footprint-generator\".format(manufacturer, series, mpn, datasheet))\n    kicad_mod.setTags(configuration['keyword_fp_string'].format(series=series,\n        orientation=orientation_str, man=manufacturer,\n        entry=configuration['entry_direction'][orientation]))\n\n    ########################## Fab Outline ###############################\n    kicad_mod.append(RectLine(start=[x_min,y_min], end=[x_max,y_max],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    if fab_pin1_marker_type == 1:\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.Fab', width=configuration['fab_line_width']))\n    if fab_pin1_marker_type == 2:\n        poly_pin1_marker_type2 = [\n            {'x':-1, 'y':y_min},\n            {'x':0, 'y':y_min+1},\n            {'x':1, 'y':y_min}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker_type2, layer='F.Fab', width=configuration['fab_line_width']))\n\n    # create Silkscreen\n    kicad_mod.append(RectLine(start=[silk_x_min,silk_y_min], end=[silk_x_max,silk_y_max],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    \n    wall_thikness=0.2\n    if configuration['allow_silk_below_part'] == 'tht' or configuration['allow_silk_below_part'] == 'both':\n        poly_silk_inner_outline = [\n            {'x':silk_x_min, 'y':-0.35},\n            {'x':silk_x_min+wall_thikness, 'y':-0.35},\n            {'x':silk_x_min+wall_thikness, 'y':silk_y_min+wall_thikness},\n            {'x':silk_x_max-wall_thikness, 'y':silk_y_min+wall_thikness},\n            {'x':silk_x_max-wall_thikness, 'y':-0.35},\n            {'x':silk_x_max, 'y':-0.35}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_silk_inner_outline, layer='F.SilkS', width=configuration['silk_line_width']))\n        poly_silk_inner_outline = [\n            {'x':silk_x_min+wall_thikness, 'y':-0.35},\n            {'x':silk_x_min+wall_thikness, 'y':0.35},\n            {'x':silk_x_min, 'y':0.35}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_silk_inner_outline, layer='F.SilkS', width=configuration['silk_line_width']))\n        poly_silk_inner_outline = [\n            {'x':silk_x_max-wall_thikness, 'y':-0.35},\n            {'x':silk_x_max-wall_thikness, 'y':0.35},\n            {'x':silk_x_max, 'y':0.35}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_silk_inner_outline, layer='F.SilkS', width=configuration['silk_line_width']))\n        poly_silk_inner_outline = [\n            {'x':silk_x_min+wall_thikness, 'y':0.35},\n            {'x':silk_x_min+wall_thikness, 'y':silk_y_max-wall_thikness},\n            {'x':silk_x_max-wall_thikness, 'y':silk_y_max-wall_thikness},\n            {'x':silk_x_max-wall_thikness, 'y':0.35},\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_silk_inner_outline, layer='F.SilkS', width=configuration['silk_line_width']))\n    poly_pin1_marker = [\n        {'x':silk_x_min-pin1_marker_offset+pin1_marker_linelen, 'y':silk_y_min-pin1_marker_offset},\n        {'x':silk_x_min-pin1_marker_offset, 'y':silk_y_min-pin1_marker_offset},\n        {'x':silk_x_min-pin1_marker_offset, 'y':silk_y_min-pin1_marker_offset+pin1_marker_linelen}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.SilkS', width=configuration['silk_line_width']))\n    \n    \n    ############################# CrtYd ##################################\n    part_x_min = x_min\n    part_x_max = x_max\n    part_y_min = y_min\n    part_y_max = y_max\n\n    cx1 = roundToBase(part_x_min-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(part_y_min-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(part_x_max+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(part_y_max+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n\n    ############################# Pads ##################################\n    pad_size = [pitch - pad_to_pad_clearance, drill_size + 2*pad_copper_y_solder_length]\n    if pad_size[0] - drill_size < 2*min_annular_ring:\n        pad_size[0] = drill_size + 2*min_annular_ring\n\n    # kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\n    #                     at=[0, 0], size=pad_size,\n    #                     drill=drill_size, layers=Pad.LAYERS_THT))\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    kicad_mod.append(PadArray(initial=1, start=[0, 0],\n        x_spacing=pitch, pincount=pincount,\n        size=pad_size, drill=drill_size,\n        type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    ######################### Text Fields ###############################\n    text_center_y = 1.5\n    body_edge={'left':part_x_min, 'right':part_x_max, 'top':part_y_min, 'bottom':part_y_max}\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position=text_center_y)\n\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=series, man=manufacturer)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../conn_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for pincount in range(2,11):\n        generate_one_footprint(pincount, configuration)\n"
  },
  {
    "path": "scripts/Connector/conn_config_KLCv2.yaml",
    "content": "fp_name_format_string: '{man:s}_{series:s}_{mpn:s}_{pins_per_row:02d}xPitch{pitch:.2f}mm_{orientation:s}'\norientation_options:\n    H: 'Horizontal'\n    V: 'Vertical'\nentry_direction:\n    H: 'top entry'\n    V: 'side entry'\n\n#keyword_fp_string: 'connector {man:s} {series:s} {mpn:s} {entry:s} {orientation:s}'\nkeyword_fp_string: 'connector {man:s} {series:s} {entry:s}'\n\n#lib_name_format_string: 'Conn_{man:s}_{series:s}'\nlib_name_format_string: 'Connectors_{man:s}'\nlib_name_specific_function_format_string: 'Connector_{category:s}'\n"
  },
  {
    "path": "scripts/Connector/conn_config_KLCv3.yaml",
    "content": "fp_name_format_string: '{man:s}_{series:s}_{mpn:s}_{num_rows:d}x{pins_per_row:02d}{mounting_pad:s}_P{pitch:.2f}mm_{orientation:s}'\nfp_name_format_string_shielded: '{man:s}_{series:s}_{mpn:s}_{num_rows:d}x{pins_per_row:02d}-{shield_pins:d}SH_P{pitch:.2f}mm_{orientation:s}'\nfp_name_no_series_format_string: '{man:s}_{mpn:s}_{num_rows:d}x{pins_per_row:02d}{mounting_pad:s}_P{pitch:.2f}mm_{orientation:s}'\nfp_name_dual_pitch_format_string: '{man:s}_{series:s}_{mpn:s}_{num_rows:d}x{pins_per_row:02d}{mounting_pad:s}_P{pitch_x:.2f}x{pitch_y:.2f}mm_{orientation:s}'\nfp_name_unequal_row_format_string: '{man:s}_{series:s}_{mpn:s}_{num_rows:d}Rows-{pins:02d}Pins{mounting_pad:s}_P{pitch:.2f}mm_{orientation:s}'\norientation_options:\n    H: 'Horizontal'\n    V: 'Vertical'\nentry_direction:\n    H: 'horizontal'\n    V: 'vertical'\n\n#keyword_fp_string: 'connector {man:s} {series:s} {mpn:s} {entry:s} {orientation:s}'\nkeyword_fp_string: 'connector {man:s} {series:s} {entry:s}'\n\nlib_name_format_string_full: 'Connector_{man:s}_{series:s}{suffix:s}'\nlib_name_format_string: 'Connector_{man:s}'\nlib_name_specific_function_format_string: 'Connector_{category:s}'\nmounting_pad_number: \"MP\"\n"
  },
  {
    "path": "scripts/Connector_PinSocket/canvas.py",
    "content": "#!/usr/bin/env python\n\n#\n# Generic extension module for KicadModTree in the kicad-footprint-generator framework\n#\n# This module requires the kicad-footprint-generator framework\n# by Thomas Pointhuber, https://github.com/pointhi/kicad-footprint-generator\n#\n# This module is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This module is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n\n#\n# This module contains wrapper classes and methods for parts\n# of the KicadModTree primitives.\n# They provide \"turtle style\" drawing using relative moves in order\n# to simplify the math involved in calculating and keeping track of vertex coordinates.\n# They also introduce the concept of canvases for drawing the different layers, this\n# to simplify drawing and provide functionality such as transparent grid align\n# and method chaining.\n# A canvas is somewhat similar to a workplane in CadQuery which is\n# often used for creating KiCad 3D models.\n#\n# (C) 2017 by Terje Io, <http://github.com/terjeio>\n\n#\n# NOTE:\n# The code for the the Keepout class is loosely based on code from drawing_tools.py\n# Currently oval and rectangular keepout zones are respected\n# for horizontal and vertical lines, only basic support (bounding box only) for diagonal lines.\n# Arcs and circles are not yet handled. On TODO: list.\n# More testing needs to be done for edge cases, such as for lines inside\n# the bounding box but outside the keepout area proper.\n#\n\n# 2017-11-25\n\nimport sys\nimport os\nimport math\n\nsys.path.append(os.path.dirname(os.path.realpath(__file__)) + \"\\\\..\\\\..\")\n\nfrom collections import namedtuple\n\nfrom KicadModTree import Point\nfrom KicadModTree.nodes.base import Line, Arc, Circle, Text, Pad\nfrom KicadModTree.nodes.specialized import RectFill\nfrom KicadModTree.util.kicad_util import formatFloat\n\nclass Layer:\n\n    _DEFAULT_LINE_WIDTHS = {'F.SilkS': 0.12,\n                            'B.SilkS': 0.12,\n                            'F.Fab':   0.1,\n                            'B.Fab':   0.1,\n                            'F.CrtYd': 0.05,\n                            'B.CrtYd': 0.05}\n\n    _DEFAULT_LINE_WIDTH        = 0.15\n    _DEFAULT_TEXT_OFFSET       = 1.0\n    _DEFAULT_TEXT_SIZE_MIN     = 0.25\n    _DEFAULT_TEXT_SIZE_MAX     = 2.00\n    _DEFAULT_GRID_CRT          = 0.05\n    _DEFAULT_OFFSET_CRT        = 0.25\n    _DEFAULT_SOLDERMASK_MARGIN = 0.2 # clearance?\n\n    def __init__(self, footprint, layer='F.Fab', origin=(0,0), line_width=None, offset=None):\n        self.footprint = footprint\n        self.layer = layer\n        self.polyline_start = None\n        self.gridspacing = None\n        self.keepout = None\n        self.setOrigin(origin[0], origin[1])\n        self.txt_size = [1.0] * 2\n        self.setTextDefaults()\n        self.setTextSize(1.0)\n        self.txt_offset = self._DEFAULT_TEXT_OFFSET\n        if offset == None and layer.split('.')[1] == 'CrtYd':\n            offset = self._DEFAULT_OFFSET_CRT\n        if offset != None:\n            self.offset = offset\n        self.auto_offset = offset == None\n        self.goHome()\n        self.setLineWidth(self._DEFAULT_LINE_WIDTHS.get(layer, self._DEFAULT_LINE_WIDTH) if line_width == None else line_width)\n        if layer.split('.')[1] == 'CrtYd':\n            self.setGridSpacing(self._DEFAULT_GRID_CRT)\n#        else:\n#            self.setGridSpacing(0.001)\n\n    @staticmethod        \n    def getBevel(width, height):\n        return min(1.0, min(width, height) * 0.25)\n\n    def setOrigin(self, x, y):\n        self.origin = (self._align(x), self._align(y))\n        self.goHome()\n        return self\n\n    def getOrigin(self):\n        return self.origin\n\n    def setLineWidth(self, width):\n        self.line_width = width\n        if self.auto_offset:\n            self.offset = self.line_width / 2.0\n        return self\n\n    def getSoldermaskMargin(self):\n        return self._DEFAULT_SOLDERMASK_MARGIN\n\n    def setTextDefaults(self, max_size=None, min_size=None):\n        if max_size == None and min_size == None:\n            self.text_size_min = self._DEFAULT_TEXT_SIZE_MIN\n            self.text_size_max = self._DEFAULT_TEXT_SIZE_MAX\n        else:\n            if max_size != None:\n                self.text_size_max = round(max_size, 2)\n            if min_size != None:\n                self.text_size_min = round(min_size, 2)\n        return self    \n\n    def setTextSize(self, height, width=None, thickness=None):\n        height = round(height, 2)\n        self.txt_size[0] = min(max(height, self.text_size_min), self.text_size_max)\n        self.txt_size[1] = min(max(height if width == None else round(width, 2), self.text_size_min), self.text_size_max)\n        self.txt_thickness = round(self.txt_size[0] * 0.15 if thickness == None else thickness, 2)\n        return self\n\n    def setGridSpacing(self, grid):\n        self.gridspacing = grid\n        if self.gridspacing != None:\n            self.alignToGrid()\n        return self\n\n    def goHome(self):\n        self.x = self.origin[0]\n        self.y = self.origin[1]\n        return self\n\n    def goto(self, x, y):\n        self.x = self._align(x)\n        self.y = self._align(y)\n        return self\n\n    def gotoX(self, x):\n        self.x = self._align(x)\n        return self\n\n    def gotoY(self, y):\n        self.y = self._align(y)\n        return self\n\n    def jump(self, x, y):\n        self.x += self._align(x)\n        self.y += self._align(y)\n        return self\n\n    def _align(self, value):\n        return round(value, 6) if self.gridspacing == None\\\n                      else (math.ceil(value / self.gridspacing) * self.gridspacing if value > 0.0 else math.floor(value / self.gridspacing) * self.gridspacing)\n\n    def alignToGrid(self):\n        self.x = self._align(self.x)\n        self.y = self._align(self.y)\n        self.setOrigin(self._align(self.origin[0]), self._align(self.origin[1]))\n        return self\n\n    def _line(self, x, y):\n        if self.keepout != None:\n            segments = self.keepout.processLine(self.x, self.y, self.x + x, self.y + y)\n            for line in segments: # TODO: move grid alignment to keepout code?\n                line[0] = self._align(line[0])\n                line[1] = self._align(line[1])\n                line[2] = self._align(line[2])\n                line[3] = self._align(line[3])\n                self.footprint.append(Line(start=[line[0], line[1]], end=[line[2], line[3]], layer=self.layer, width=self.line_width))\n        else:            \n            self.footprint.append(Line(start=[self.x, self.y], end=[self.x + x, self.y + y], layer=self.layer, width=self.line_width))\n\n    def to(self, x, y, draw=True):\n        x = self._align(x)\n        y = self._align(y)\n        if draw:\n            self._line(x, y)\n        self.x += x\n        self.y += y\n        return self\n\n    def left(self, distance, draw=True):\n        distance = self._align(distance)\n        if draw:\n            self._line(-distance, 0.0)\n        self.x -= distance\n        return self\n\n    def right(self, distance, draw=True):\n        distance = self._align(distance)\n        if draw:\n            self._line(distance, 0.0)\n        self.x += distance\n        return self\n\n    def up(self, distance, draw=True):\n        distance = self._align(distance)\n        if draw:\n            self._line(0.0, -distance)\n        self.y -= distance\n        return self\n\n    def down(self, distance, draw=True):\n        distance = self._align(distance)\n        if draw:\n            self._line(0.0, distance)\n        self.y += distance\n        return self\n\n    def polyline(self, vertices, close=False):\n        if self.polyline_start == None:\n            self.polyline_start = (self.x, self.y)\n        for vertex in vertices:\n            x = self._align(vertex[0])\n            y = self._align(vertex[1])\n            self._line(self.x + x, self.y + y)\n            self.x += x\n            self.y += y\n        if close:\n            self.close()\n        return self\n\n    def close(self):\n        if self.polyline_start != None:\n            if self.x != self.polyline_start[0] or self.x != self.polyline_start[1]:\n                self._line(self.polyline_start[0], self.polyline_start[1])\n            self.polyline_start = None\n        return self\n\n    def arc(self, center_x, center_y, angle):\n        arc = Arc(start=[self.x, self.y], center=[self.x + center_x, self.y + center_y], angle=angle, layer=self.layer, width=self.line_width)\n        self.footprint.append(arc)\n        end = arc._calulateEndPos()    \n        self.x += center_x + end.y\n        self.y += center_y + end.x\n        return self\n\n    def circle(self, radius, filled=False):\n        if filled:\n            line_width = radius / 3.0 + self.line_width / 2.0\n            r = line_width / 2.0\n            while r < radius:\n                self.footprint.append(Circle(center=[self.x, self.y], radius=r, layer=self.layer, width=line_width))        \n                r += line_width - self.line_width / 2.0\n        else:\n            line_width = round(min(self.line_width, radius / 2.0), 3)\n            self.footprint.append(Circle(center=[self.x, self.y], radius=radius, layer=self.layer, width=line_width))\n        return self\n   \n    def fillrect(self, w, h): #TODO: add origin handling\n        x = self.x\n        y = self.y\n        w = self._align(w)\n        h = self._align(h - self.line_width)\n        \n        #self.jump(self._align(-w / 2.0), self._align(-h / 2.0))\n        \n        l = math.ceil(h / self.line_width)\n        h = h / l\n\n        self.jump(0.0, self.line_width / 2.0)\n\n        while(l > 0):\n            self._line(w, 0.0)\n            self.jump(0.0, h)\n            l -= 1   \n\n        self.x = x\n        self.y = y\n        return self\n\n    def rect(self, w, h, bevel=(0.0, 0.0, 0.0, 0.0), draw=(True, True, True, True), origin='center'):\n\n        x = self.x\n        y = self.y\n        w = self._align(w)\n        h = self._align(h)\n        \n        if type(bevel) in [int, float]:\n            bevel = [bevel] * 4\n        elif bevel == None:\n            bevel = [0.0] * 4\n\n        if origin == 'center':\n            self.jump(self._align(-w / 2.0), self._align(-h / 2.0))\n\n        if bevel[0] != 0.0:\n            self.jump(bevel[0], 0.0)\n\n        self.right(w - bevel[0] - bevel[1], draw[0])\n\n        if bevel[1] != 0.0:\n            self.to(bevel[1], bevel[1])\n\n        self.down(h - bevel[1] - bevel[2], draw[1])\n\n        if bevel[2] != 0.0:\n            self.to(-bevel[2], bevel[2])\n\n        self.left(w - bevel[3] - bevel[2], draw[2])\n\n        if bevel[3] != 0.0:\n            self.to(-bevel[3], -bevel[3])\n\n        self.up(h - bevel[3] - bevel[0], draw[3])\n\n        if bevel[0] != 0.0:\n            self.to(bevel[0], -bevel[0])\n\n        self.x = x\n        self.y = y\n\n        return self\n\n    def rrect(self, w, h, radius, origin='center'):\n\n        x = self.x\n        y = self.y\n        w = self._align(w)\n        h = self._align(h)\n\n        if origin == 'center':\n            self.jump(self._align(-w / 2.0), self._align(-h / 2.0))\n\n        w -= radius * 2.0          \n        h -= radius * 2.0          \n\n        self.jump(radius, 0.0)\n        self.right(w)\n        self.arc(0.0, radius, 90.0)\n        self.down(h)\n        self.arc(-radius, 0.0, 90.0)\n        self.left(w)\n        self.arc(0.0, -radius, 90.0)\n        self.up(h)\n        self.arc(radius, 0.0, 90.0)\n\n        self.x = x\n        self.y = y\n\n        return self\n\n    def text(self, type, text, rotation=0):\n        self.footprint.append(Text(type=type, text=text, at=[self.x, self.y], rotation=rotation, layer=self.layer, size=self.txt_size, thickness=self.txt_thickness))\n        return self\n\n# TODO: add methods for offsetting etc\nclass PolyLine ():\n\n    def __init__(self, vertices=None):\n        self.vertices = []\n        if vertices != None:   \n            for vertex in vertices:\n                self.vertices.append(Point(vertex))\n\n    def __getattr__(self, name):\n        if name == \"isClosed\":\n            return False if len(self.vertices) < 3 else self.vertices[0].x == self.vertices[-1].x and self.vertices[0].y == self.vertices[-1].y\n        else:\n            raise AttributeError\n        \n    def append(self, x, y):\n        self.vertices.append([x, y])\n        return self\n\n    \nclass PadLayer:\n\n    def __init__(self, footprint, size, type, shape, shape_first=None, drill=None, layers=None, x_offset=0.0, y_offset=0.0):\n        self.footprint = footprint\n        self.type = type\n        self.layers = layers\n        self.shape = shape\n        self.shape_first = shape if shape_first == None else shape_first\n        self.size = size\n        self.drill = 0.5 if drill == None and type == Pad.TYPE_SMT else drill\n        self.x_offset = x_offset\n        self.y_offset = y_offset\n        self._init_layers(layers)\n        self.p = 1\n        self.last_pad = None\n\n    def _init_layers(self, layers):\n\n        if layers == None:\n            if self.type == Pad.TYPE_SMT:\n                layers = Pad.LAYERS_SMT\n            elif self.type == Pad.TYPE_THT:\n                layers = Pad.LAYERS_THT\n\n        self.layers=layers\n\n    def add(self, x, y, number=None, type=None, shape=None, size=None, x_offset=None, y_offset=None):\n\n        if number == None:\n            number = self.p\n            self.p += 1\n\n        if x_offset == None:\n            x_offset = self.x_offset\n\n        if y_offset == None:\n            y_offset = self.y_offset\n            \n        if shape == None:\n            shape=self.shape_first if number == 1 else self.shape\n\n        self.last_pad = Pad(number=number,\n                            type=self.type if type == None else type,\n                            shape=shape,\n                            at=[x + x_offset, y + y_offset],\n                            size=self.size if size == None else size,\n                            drill=self.drill, layers=self.layers)\n        self.footprint.append(self.last_pad)\n        return self\n\n    def getLast(self):\n        return self.last_pad\n\n_RectWH = namedtuple(\"_RectWH\", [\n    'x',\n    'y',\n    'height',\n    'width'\n])\n\nclass _Point: \n    def __init__(self, x, y):\n        self.x = x\n        self.y = y\n\n    def __repr__(self):\n        return \"(x={x}, y={y})\".format(x=formatFloat(self.x), y=formatFloat(self.y))\n        \nclass _Line: \n    def __init__(self, a, b, x1=None, y1=None, normalize=False):\n        if x1 == None and y1 == None:\n            self._add_points(a, b, normalize)\n        else:    \n            self._add_points(_Point(a, b), _Point(x1, y1), normalize)\n\n    def _add_points(self, a, b, normalize):\n        if normalize:  \n            self.x0 = round(min(a.x, b.x), 8)\n            self.x1 = round(max(a.x, b.x), 8)\n            self.y0 = round(min(a.y, b.y), 8)\n            self.y1 = round(max(a.y, b.y), 8)\n        elif a.y < b.y:\n            self.x0 = a.x\n            self.x1 = b.x\n            self.y0 = a.y\n            self.y1 = b.y           \n        else:\n            self.x0 = b.x\n            self.x1 = a.x\n            self.y0 = b.y\n            self.y1 = a.y           \n\n    def __repr__(self):\n        return \"(x0={x0}, y0={y0}, x1={x1}, y1={y1})\".format(x0=formatFloat(self.x0), y0=formatFloat(self.y0),\n                                                             x1=formatFloat(self.x1), y1=formatFloat(self.y1))\n\nclass _Keepout:\n    def __init__(self, a, b, x1=None, y1=None, radius=0.0):\n        self.lines = []\n        self.radius = radius\n        if x1 == None and y1 == None:\n            self._add_points(a, b)\n        else:    \n            self._add_points(_Point(a, b), _Point(x1, y1))\n\n    def _add_points(self, a, b):        \n        self.x0 = round(min(a.x, b.x), 5)\n        self.x1 = round(max(a.x, b.x), 5)\n        self.y0 = round(min(a.y, b.y), 5)\n        self.y1 = round(max(a.y, b.y), 5)\n\n    def pointIsInside(self, x, y):\n        x = round(x, 5); y = round(y, 5)\n        return x >= self.x0 and x <= self.x1 and y >= self.y0 and y <= self.y1\n\n    def _feq(self, a, b):\n        return abs(a-b) < 0.0001\n    \n    def _bbox_overlap(self, bbox):\n        x0 = min(bbox.x0, bbox.x1)\n        x1 = max(bbox.x0, bbox.x1)\n        y0 = min(bbox.y0, bbox.y1)\n        y1 = max(bbox.y0, bbox.y1)\n        return not (self.x0 < x1 and self.x1 > x0 and self.y0 > y1 and self.y1 < y0)\n\n    def lineIntersects(self, l):\n        \n        # skip proccesing if line bounding box is completely outside keepout bounding box\n        if not self._bbox_overlap(l):\n            return False\n    \n        points = []\n  \n        # get lines representing keepout bounding box\n        if len(self.lines) == 0:\n            self.lines.append(_Line(self.x0, self.y0, self.x1, self.y0))\n            self.lines.append(_Line(self.x1, self.y0, self.x1, self.y1))\n            self.lines.append(_Line(self.x0, self.y1, self.x1, self.y1))\n            self.lines.append(_Line(self.x0, self.y0, self.x0, self.y1))\n        \n        # find and return intersecting points\n        a1 = l.y1 - l.y0\n        b1 = l.x0 - l.x1\n        lr = l.x1 > l.x0\n\n        i = 0\n\n        for k in self.lines:\n            a2 = k.y1 - k.y0\n            b2 = k.x0 - k.x1\n            d = a1 * b2 - a2 * b1\n                    \n            if d != 0.0:\n                c2 = a2 * k.x0 + b2 * k.y0;\n                c1 = a1 * l.x0 + b1 * l.y0\n                xp = (b2 * c1 - b1 * c2) / d\n                yp = (a1 * c2 - a2 * c1) / d\n  \n                ka = (xp >= l.x0 and xp <= l.x1) if lr else (xp <= l.x0 and xp >= l.x1)\n                kb = self._feq(xp, k.x0) if k.x0 == k.x1 else self._feq(yp, k.y0)\n\n                if ka and kb and self.pointIsInside(xp, yp):\n                    if lr and (i == 0 or i == 3):\n                        points.insert(0, [xp, yp, i])\n                    else:\n                        points.append([xp, yp, i])\n            i += 1       \n\n        return False if len(points) == 0 else points\n\n    def HlineIntersects(self, y):\n        return y > self.y0 and y < self.y1\n\n    def VlineIntersects(self, x):\n        return round(x, 8) > self.x0 and round(x, 8) < self.x1\n\n    def _HLineTrim(self, y, r):\n        h = (self.y0 + r - y if y < self.y0 + r else y - self.y1 + r)\n        return r - math.sqrt(r * r - h * h)\n        \n    def _VLineTrim(self, x, r):\n        h = (self.x0 + r - x if x < self.x0 + r else x - self.x1 + r)\n        return r - math.sqrt(r * r - h * h)\n\n    def HLineTrim(self, l):\n\n        line = _Line(l[0], l[1], l[2], l[3], normalize=True)\n\n        # check if line is outside rectangular bounding box and exit if so\n        if line.x1 < self.x0 or line.x0 > self.x1:\n            return False\n\n        # check if line completely inside rectangular bounding box and exit with no segments if so\n        if self.radius == 0.0 and line.x0 >= self.x0 and line.x1 <= self.x1:\n            return []\n\n        r = self.radius\n        segments = []\n\n        if r == 0.0 or (line.y0 >= self.y0 + r and line.y0 <= self.y1 - r):\n            if line.x0 < self.x0:\n                segments.append([line.x0, line.y0, self.x0, line.y1])\n            if line.x1 > self.x1:\n                segments.append([self.x1, line.y0, line.x1, line.y1])\n        elif line.x1 > self.x0 and line.x0 < self.x1:\n            h = self._HLineTrim(line.y0, r) \n            if line.x0 < self.x0 + r:\n                segments.append([line.x0, line.y0, min(line.x1, self.x0 + h), line.y1])\n            if line.x1 > self.x1 - r:\n                segments.append([max(line.x0, self.x1 - h), line.y0, line.x1, line.y1])\n        return False if len(segments) == 0 else segments\n\n    def VLineTrim(self, l):\n\n        line = _Line(l[0], l[1], l[2], l[3], normalize=True)\n\n        # check if line is outside\n        if line.y1 <= self.y0 or line.y0 >= self.y1:\n            return False\n\n        # check if line completely inside rectangular bounding box and exit with no segments if so\n        if self.radius == 0.0 and line.y0 >= self.y0 and line.y1 <= self.y1:\n            return []\n\n        r = self.radius\n        segments = []\n\n        if r == 0.0 or (line.x0 >= self.x0 + r and line.x0 <= self.x1 - r):\n            if line.y0 < self.y0:\n                segments.append([line.x0, line.y0, line.x1, self.y0])\n            if line.y1 > self.y1:\n                segments.append([line.x0, self.y1, line.x1, line.y1])\n        elif line.y1 > self.y0 and line.y0 < self.y1:\n            h = self._VLineTrim(line.x0, r) \n            if line.y0 < self.y0 + r:\n                segments.append([line.x0, line.y0, line.x1, min(line.y1, self.y0 + h)])\n            if line.y1 > self.y1 - r:\n                segments.append([line.x0, max(self.y1 - h, line.y0), line.x1, line.y1])\n\n        return False if len(segments) == 0 else segments\n\n    def __repr__(self):\n        return \"(x0={x0}, y0={y0}, x1={x1}, y1={y1}, r={r})\".format(x0=formatFloat(self.x0), y0=formatFloat(self.y0),\n                                                             x1=formatFloat(self.x1), y1=formatFloat(self.y1),\n                                                             r=formatFloat(self.radius))\n\n\nclass Keepout():\n\n    DEBUG = 0\n    _NUM_RECTS = 5\n\n    def __init__(self, layer):\n        self.layer = layer\n        self.keepouts = []\n        self.min_length = 0.01\n        layer.keepout = self\n\n    # float-variant of range()\n    @staticmethod\n    def frange(x, y, jump):\n        while x < y:\n            yield x\n            x += jump\n\n    def __getattr__(self, name):\n        if name == \"offset\":\n            return self.layer.line_width / 2.0 + self.layer.getSoldermaskMargin()\n        else:\n            raise AttributeError\n\n    def _align(self, value):\n        return self.layer._align(value)\n\n    def _add(self, x0, y0, x1, y1, radius=0.0):\n        self.keepouts.append(_Keepout(self._align(x0), self._align(y0), self._align(x1), self._align(y1), radius))\n\n    # add keepout area for rectangle\n    def addRect(self, x, y, w, h, offset=None):\n        if offset == None:\n            offset = 0.0\n        w = w / 2.0 + offset\n        h = h / 2.0 + offset\n        self._add(x - w, y - h, x + w, y + h)\n        return self\n\n    # add keepout area for circular or oval object\n    def addRound(self, x, y, w, h, offset=None):\n        if offset == None:\n            offset = self.offset\n#        d = w - h         \n        r = min(h, w) / 2.0 + offset\n        w = w / 2.0 + offset\n        h = h / 2.0 + offset\n        self._add(x - w, y - h, x + w, y + h, r)\n#        self.addRect(x - w, y - w, d if d > 0.0 else 0.0, -d if d < 0.0 else 0.0, r)\n        return self\n    \n    def addPads(self):\n        nodes = self.layer.footprint.getNormalChilds()\n        offset = self.offset\n        for node in nodes:\n            if isinstance(node, Pad):\n                if node.shape == Pad.SHAPE_RECT:\n                    self.addRect(node.at.x, node.at.y, node.size.x, node.size.y, offset)\n                else:\n                    self.addRound(node.at.x, node.at.y, node.size.x, node.size.y, offset)\n\n    def getPadBB(self, number):\n        # TODO: use node.calculateBoundingBox when implemented, this is a simple version that does not honor any rotation\n        nodes = self.layer.footprint.getNormalChilds()\n        offset = self.offset * 2.0\n        bb = None\n        for node in nodes:\n            if isinstance(node, Pad) and node.number == number:\n                bb = _RectWH(x = node.at.x, y = node.at.y, width = node.size.x + offset, height = node.size.y + offset)\n        return bb\n\n    # internal method for keepout-processing\n    def _processHVLine(self, line):\n        \n        def add_segment(x0, y0, x1, y1):\n            length = x1 - x0 + y1 - y0 \n            if length >= self.min_length:\n                segments.append([x0, y0, x1, y1])\n\n        vertical = line.x0 == line.x1\n        segments = [[line.x0, line.y0, line.x1, line.y1]]\n\n        if self.DEBUG & 2:\n            print(\"S\", line)\n\n        changes = len(self.keepouts) > 0\n        while changes != False:\n            changes = False\n            for keepout in self.keepouts:\n                if keepout.VlineIntersects(line.x0) if vertical else keepout.HlineIntersects(line.y0):\n                    for i in reversed(range(0, len(segments))):\n                        segment = segments[i]\n                        changes = keepout.VLineTrim(segment) if vertical else keepout.HLineTrim(segment)\n                        if changes != False:\n                            segments.pop(i)\n                            for segment in changes:\n                                add_segment(segment[0], segment[1], segment[2], segment[3])\n                            \n                        if self.DEBUG & 2:\n                            print(\"CHOP - line:\", segment[0], segment[1], segment[2], segment[3], \"keepout:\", keepout)\n\n            if changes != False:\n                break\n\n        if self.DEBUG & 2:\n            print(\"LI\", segments)\n\n        return segments\n    \n    # split an arbitrary line so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\n    def processLine(self, x0, y0, x1, y1):\n\n        line = _Line(x0, y0, x1, y1, normalize=True)\n\n        if line.x0 == line.x1 or line.y0 == line.y1: # use simpler and faster algorithm for horizontal and vertical lines\n            return self._processHVLine(line)\n    \n        # TODO: update to handle keepout area proper, now only respects the bounding box.\n        \n        segments=[[line.x0, line.y0, line.x1, line.y1]]\n        for keepout in self.keepouts:\n            for i in reversed(range(0, len(segments))):\n                segment = segments[i]\n                changes = keepout.lineIntersects(_Line(segment[0], segment[1], segment[2], segment[3]))\n                if changes != False:\n                    segments.pop(i)\n                    segments.append([segment[0], segment[1], changes[0][0], changes[0][1]])\n                    if len(changes) == 2:\n                        segments.append([changes[1][0], changes[1][1], segment[2], segment[3]])\n        return segments       \n\n    # draws the keepouts\n    def debug_draw(self):\n        if self.DEBUG & 1:\n            x = self.layer.x\n            y = self.layer.y\n            lw = self.layer.line_width\n            self.layer.line_width = 0.01\n            self.layer.keepout = None\n            for keepout in self.keepouts:\n                self.layer.goto(keepout.x0, keepout.y0)\n                if(keepout.radius > 0.0):\n                    self.layer.rrect(keepout.x1 - keepout.x0, keepout.y1 - keepout.y0, keepout.radius, origin=\"topLeft\")\n                self.layer.rect(keepout.x1 - keepout.x0, keepout.y1 - keepout.y0, origin=\"topLeft\")\n            self.layer.line_width = lw\n            self.layer.keepout = self\n            self.layer.x = x\n            self.layer.y = y\n\n\nclass OutDir:\n\n    def __init__(self, root_dir=None):    \n        self.root_dir = \"\" if root_dir == None else root_dir\n        if root_dir != \"\" and self.root_dir[-1] != os.sep:\n            self.root_dir += os.sep\n\n    def saveTo(self, lib_name):\n        out_dir = \"\" if self.root_dir == \"\" else self.root_dir + lib_name + \".pretty\" + os.sep   \n        if not os.path.exists(out_dir):\n            os.makedirs(out_dir)\n        return out_dir\n\n### EOF ###\n"
  },
  {
    "path": "scripts/Connector_PinSocket/cq_base_parameters.py",
    "content": "# -*- coding: utf8 -*-\n#!/usr/bin/python\n#\n\n#\n# Parts script module for socket strip footprints for KicCad\n#\n# This module is built on top of the kicad-footprint-generator framework\n# by Thomas Pointhuber, https://github.com/pointhi/kicad-footprint-generator\n#\n# This module is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This module is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n\n#\n# (C) 2017 Terje Io, <http://github.com/terjeio>\n#\n\n# 2017-11-25\n\n#\n# parts of this code is based on work by other contributors\n#\n\nfrom collections import namedtuple\n\n### use enums (Phyton 3+)\n\nclass CaseType:\n    r\"\"\"A class for holding constants for part types\n\n    .. note:: will be changed to enum when Python version allows it\n    \"\"\"\n    THT = 'THT'\n    r\"\"\"THT - trough hole part\n    \"\"\"\n    SMD = 'SMD'\n    r\"\"\"SMD - surface mounted part\n    \"\"\"\n\nclass PinStyle:\n    r\"\"\"A class for holding constants for pin styles\n\n    .. note:: will be changed to enum when Python version allows it\n    \"\"\"\n    STRAIGHT = 'Straight'\n    ANGLED   = 'Angled' \n\n###\n\n#\n# The following classes must be subclassed\n#\nclass PartParametersBase:\n    \"\"\"\n\n    .. document private functions\n    .. automethod:: _make_params\n    \"\"\"\n\n    Model = namedtuple(\"Model\", [\n        'variant',      # generic model name\n        'params',       # parameters\n        'model'         # model creator class\n    ])\n    \"\"\" Internally used for passing information from the base parameters to the class instance used for creating models\n\n    .. py:attribute:: variant\n\n        The generic name from the list of parameters\n\n    .. py:attribute:: params\n\n        The final parameters passed to the class instance\n\n    .. py:attribute:: model\n\n        The class instance itself\n\n    \"\"\"\n\n    Params = namedtuple(\"Params\", [\n        'num_pins',\n        'pin_pitch',\n        'pin_style',\n        'type'\n    ])\n    \"\"\" Basic parameters for parts, if further parameters are required this should be subclassed/overriden \n\n    .. note:: The existing parameters should be kept with the same name when overriden as the framework requires them\n\n    .. py:attribute:: num_pins\n\n        Number of pins, for parts with this is usually set to None for \n\n    .. py:attribute:: pin_pitch\n\n        The final parameters passed to the class instance\n\n    .. py:attribute:: pin_style\n\n        The class instance itself\n\n    .. py:attribute:: type\n\n        The class instance itself\n\n    \"\"\"\n\n    def __init__(self):\n        self.base_params = {}\n\n    def _make_params(self, pin_pitch, num_pin_rows, pin_style, type):\n        r\"\"\"add a list of new points\n        \"\"\"\n        return self.Params(\n            num_pins = None,                # to be added programmatically\n            pin_pitch = pin_pitch,          # pin pitch\n            pin_style = pin_style,          # pin style: 'Straight' or 'Angled'\n            type = type                     # part type: 'THT' or 'SMD'\n        )\n\n    def getAllModels(self, model_classes):\n        r\"\"\"Generate model parameters for all series and variants\n\n        Loops through all base parameters and model classes instantiating the classes and checks whether a variant should be made.\n        If a variant is to be made a namedtuple is made with the index from a call to the model instance makeModelName method\n        and the base parameters are copied to this. When copying the base parameters others may be added such as number of pins (num_pins). \n\n        .. note:: Typically this method is overriden in order to add calculated parameters like number of pins.\n                  The model specific parameters are contained in the model class itself.\n\n        :param model_classes:\n            list of part creator classes inherited from :class:`cq_base_model.PartBase`\n        :type  model_classes: ``list of classes``\n\n        :rtype: ```tuple````\n\n        \"\"\"\n        models = {}\n\n        # instantiate generator classes in order to make a dictionary of all model names\n        for i in range(0, len(model_classes)):\n            for variant in self.base_params.keys():\n                params = self.base_params[variant]\n                model = model_classes[i](params)\n                if model.make_me:\n                    models[model.makeModelName(variant)] = self.Model(variant, params, model_classes[i])\n\n        return models\n\n    def getSampleModels(self, model_classes):\n        r\"\"\"Generate model parameters for all series and variants\n\n        Loops through all base parameters and model classes instantiating the classes and checks whether a variant should be made.\n        If a variant is to be made a namedtuple is made with the index from a call to the model instance makeModelName method\n        and the base parameters are copied to this. When copying the base parameters others may be added such as number of pins (num_pins). \n\n        .. note:: Typically this method is overriden in order to add calculated parameters like number of pins.\n                  The model specific parameters are contained in the model class itself.\n\n        :param model_classes:\n            list of part creator classes inherited from :class:`cq_base_model.PartBase`\n        :type  model_classes: ``list of classes``\n\n        :rtype: ```tuple````\n\n        \"\"\"\n\n        models = {}\n\n        # instantiate generator classes in order to make a dictionary of all model names\n        for i in range(0, len(model_classes)):\n            for variant in self.base_params.keys():\n                params = self.base_params[variant]\n                model = model_classes[i](params)\n                if model.make_me:\n                    models[model.makeModelName(variant)] = self.Model(variant, params, model_classes[i])\n\n        return models\n"
  },
  {
    "path": "scripts/Connector_PinSocket/main_generator.py",
    "content": "# -*- coding: utf8 -*-\n#!/usr/bin/env python\n\n#\n# Parts script module for socket strip footprints for KicCad\n#\n# This module is built on top of the kicad-footprint-generator framework\n# by Thomas Pointhuber, https://github.com/pointhi/kicad-footprint-generator\n#\n# This module is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This module is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n\n#\n# (C) 2017 Terje Io, <http://github.com/terjeio>\n#\n\n# 2017-11-25\n\n#\n# NOTE: many footprints are based on legacy dimensions which does not have any documented datasheet sources\n#       see parameter.yaml for which\n#\n\nimport sys\n\nfrom parameters import params\n\nimport socket_strips\n\nif __name__ == '__main__':\n\n    series = [\n        socket_strips.pinSocketVerticalTHT,\n        socket_strips.pinSocketHorizontalTHT,\n        socket_strips.pinSocketVerticalSMD\n    ]\n\n    params = params()\n    if params.loaded is not True:\n        print(params.loaded)\n        sys.exit(1)\n\n#    models = params.getSampleModels(series, 4)\n    models = params.getAllModels(series)\n    i = 0\n    for variant in models.keys():\n        params = models[variant].params\n        model = models[variant].model(params)\n        if model.make_me:\n            model.make()\n        i += 1\n\n    print(\"\\nFootprints made:\", i)\n\n### EOF ###\n"
  },
  {
    "path": "scripts/Connector_PinSocket/parameters.py",
    "content": "# -*- coding: utf8 -*-\n#!/usr/bin/python\n#\n\n#****************************************************************************\n#*                                                                          *\n#* class for generating and importing parameters for pin sockets parts      *\n#*                                                                          *\n#* This is part of FreeCAD & cadquery tools                                 *\n#* to export generated models in STEP & VRML format.                        *\n#*   Copyright (c) 2017                                                     *\n#* Terje Io https://github.com/terjeio                                      *\n#*                                                                          *\n#* All trademarks within this guide belong to their legitimate owners.      *\n#*                                                                          *\n#*   This program is free software; you can redistribute it and/or modify   *\n#*   it under the terms of the GNU Lesser General Public License (LGPL)     *\n#*   as published by the Free Software Foundation; either version 2 of      *\n#*   the License, or (at your option) any later version.                    *\n#*   for detail see the LICENCE text file.                                  *\n#*                                                                          *\n#*   This program is distributed in the hope that it will be useful,        *\n#*   but WITHOUT ANY WARRANTY; without even the implied warranty of         *\n#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *\n#*   GNU Library General Public License for more details.                   *\n#*                                                                          *\n#*   You should have received a copy of the GNU Library General Public      *\n#*   License along with this program; if not, write to the Free Software    *\n#*   Foundation, Inc.,                                                      *\n#*   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA           *\n#*                                                                          *\n#****************************************************************************\n\nimport os\nimport yaml\nfrom collections import namedtuple\nfrom cq_base_parameters import PartParametersBase, PinStyle, CaseType\n\nclass params (PartParametersBase):\n\n    Params = namedtuple(\"Params\", [\n        'num_pins',\n        'num_pin_rows',\n        'pin_pitch',\n        'pin_style',\n        'type',\n        'pin1start_right'\n    ])\n\n    DParams = namedtuple(\"DParams\", [\n        'type',\n        'num_pins',\n        'num_pin_rows',\n        'pin_pitch',\n        'pin_style',\n        'pin_length',\n        'pin_width',\n        'pin_thickness',\n        'pin_drill',\n        'pins_min',\n        'pins_max',\n        'pin1start_right',\n        'pad_width',\n        'pad_length',\n        'pads_lp_width',\n        'pins_offset',\n        'body_width',\n        'body_height',\n        'body_length',\n        'body_overlength',\n        'body_offset',\n        'datasheet',\n    ])\n\n    def __init__(self, parameter_file=None):\n        self.devices = {}\n        self.base_params = {\n            #\n            # E - pin rows distance\n            # P - total number of pins\n            # Case - case type\n            #   Generic name                                        E        P  Case\n                #\"THT-1x1.27mm_Horizontal\"       : self._make_params(1.27,    1, PinStyle.ANGLED, CaseType.THT, True),\n                \"THT-1x2.00mm_Horizontal\"       : self._make_params(2.00,    1, PinStyle.ANGLED, CaseType.THT, True),\n                \"THT-1x2.54mm_Horizontal\"       : self._make_params(2.54,    1, PinStyle.ANGLED, CaseType.THT, True),\n                \"THT-1x1.00mm_Vertical\"         : self._make_params(1.00,    1, PinStyle.STRAIGHT, CaseType.THT, True),\n                \"THT-1x1.27mm_Vertical\"         : self._make_params(1.27,    1, PinStyle.STRAIGHT, CaseType.THT, True),\n                \"THT-1x2.00mm_Vertical\"         : self._make_params(2.00,    1, PinStyle.STRAIGHT, CaseType.THT, True),\n                \"THT-1x2.54mm_Vertical\"         : self._make_params(2.54,    1, PinStyle.STRAIGHT, CaseType.THT, True),\n\n                \"THT-2x1.27mm_Horizontal\"       : self._make_params(1.27,    2, PinStyle.ANGLED, CaseType.THT, True),\n                \"THT-2x2.00mm_Horizontal\"       : self._make_params(2.00,    2, PinStyle.ANGLED, CaseType.THT, True),\n                \"THT-2x2.54mm_Horizontal\"       : self._make_params(2.54,    2, PinStyle.ANGLED, CaseType.THT, True),\n                \"THT-2x1.27mm_Vertical\"         : self._make_params(1.27,    2, PinStyle.STRAIGHT, CaseType.THT, True),\n                \"THT-2x2.00mm_Vertical\"         : self._make_params(2.00,    2, PinStyle.STRAIGHT, CaseType.THT, True),\n                \"THT-2x2.54mm_Vertical\"         : self._make_params(2.54,    2, PinStyle.STRAIGHT, CaseType.THT, True),\n\n                \"SMD-1x1.00mm_Vertical_Right\"   : self._make_params(1.00,    1, PinStyle.STRAIGHT, CaseType.SMD, True),\n                \"SMD-1x1.27mm_Vertical_Right\"   : self._make_params(1.27,    1, PinStyle.STRAIGHT, CaseType.SMD, True),\n                \"SMD-1x2.00mm_Vertical_Right\"   : self._make_params(2.00,    1, PinStyle.STRAIGHT, CaseType.SMD, True),\n                \"SMD-1x2.54mm_Vertical_Right\"   : self._make_params(2.54,    1, PinStyle.STRAIGHT, CaseType.SMD, True),\n\n                \"SMD-1x1.00mm_Vertical_Left\"    : self._make_params(1.00,    1, PinStyle.STRAIGHT, CaseType.SMD, False),\n                \"SMD-1x1.27mm_Vertical_Left\"    : self._make_params(1.27,    1, PinStyle.STRAIGHT, CaseType.SMD, False),\n                \"SMD-1x2.00mm_Vertical_Left\"    : self._make_params(2.00,    1, PinStyle.STRAIGHT, CaseType.SMD, False),\n                \"SMD-1x2.54mm_Vertical_Left\"    : self._make_params(2.54,    1, PinStyle.STRAIGHT, CaseType.SMD, False),\n\n                \"SMD-2x1.00mm_Vertical\"         : self._make_params(1.00,    2, PinStyle.STRAIGHT, CaseType.SMD, True),\n                \"SMD-2x1.27mm_Vertical\"         : self._make_params(1.27,    2, PinStyle.STRAIGHT, CaseType.SMD, True),\n                \"SMD-2x2.00mm_Vertical\"         : self._make_params(2.00,    2, PinStyle.STRAIGHT, CaseType.SMD, True),\n                \"SMD-2x2.54mm_Vertical\"         : self._make_params(2.54,    2, PinStyle.STRAIGHT, CaseType.SMD, True)\n            }\n\n        if parameter_file == None:\n            parameter_file = os.path.dirname(os.path.realpath(__file__)) + os.sep + \"parameters.yaml\"\n\n        try:\n            devices = yaml.safe_load_all(open(parameter_file))\n            for device in devices:\n                params = self._import_params(device)\n                if not params == False:\n                    self.devices[device['series']] = params\n                self.loaded = True\n        except Exception as exception:\n            self.loaded = 'Failed to load parameters: {e}'.format(e=exception)\n            return\n\n    def _import_params(self, device):\n        if device['series'] in self.base_params:\n            base = self.base_params[device['series']]\n            return self.DParams(\n                num_pins = None,                  # to be added programmatically\n                type = base.type,\n                num_pin_rows = base.num_pin_rows,\n                pin_pitch = base.pin_pitch,\n                pin_style = base.pin_style,\n                pin1start_right = base.pin1start_right,\n                pin_length = device['pins']['length'],\n                pin_width = device['pins']['width'],\n                pin_thickness = device['pins']['thickness'],\n                pins_offset = device['pins']['offset'],\n                pin_drill = device['pins']['drill'],\n                pins_min = int(device['pins']['min']),\n                pins_max = int(device['pins']['max']),\n                body_width = device['body']['width'],\n                body_height = device['body']['height'],\n                body_length = None, # will be calculated by the render class\n                body_overlength = device['body']['overlength'],\n                body_offset = device['body']['offset'],\n                pad_width = device['pads']['width'],\n                pad_length = device['pads']['length'],\n                pads_lp_width = device['pads']['lp_width'],\n                datasheet = device['datasheet'],\n            )\n        else:\n            return False\n\n    def _make_params(self, pin_pitch, num_pin_rows, pin_style, type, pin1start_right):\n        return self.Params(\n            num_pins = None,                  # to be added programmatically\n            num_pin_rows = num_pin_rows,      # number of pin rows\n            pin_pitch = pin_pitch,            # pin pitch\n            pin_style = pin_style,            # pin style: 'Straight' or 'Angled'\n            type = type,                      # part type: 'THT' or 'SMD'\n            pin1start_right = pin1start_right # True if pin 1 start at right\n        )\n\n    def getAllModels(self, model_classes):\n\n        models = {}\n\n        # instantiate generator classes in order to make a dictionary of all variants\n        for i in range(0, len(model_classes)):\n            for variant in self.devices.keys():\n                for pin_columns in range(self.devices[variant].pins_min, self.devices[variant].pins_max + 1):\n                    params = self.devices[variant]._replace(num_pins = pin_columns)\n                    model = model_classes[i](params)\n                    if model.make_me:\n                        models[model.makeModelName(variant)] = self.Model(variant, params, model_classes[i])\n\n        return models\n\n    def getSampleModels(self, model_classes):\n\n        models = {}\n\n        # instantiate generator classes in order to make a dictionary of all default variants\n        for i in range(0, len(model_classes)):\n            for variant in self.devices.keys():\n                params = self.devices[variant]._replace(num_pins = 5 * self.devices[variant].num_pin_rows)\n                model = model_classes[i](params)\n                if model.make_me:\n                    models[model.makeModelName(variant)] = self.Model(variant, params, model_classes[i])\n\n        return models\n\n    def getModel(self, model_class, variant):\n\n        model = variant in self.devices\n\n        # instantiate generator class in order to make a dictionary entry for a single variant\n        if model:\n            params = self.devices[variant]._replace(num_pins = 5 * self.devices[variant].num_pin_rows)\n            model = model_class(params)\n            if not model.make_me:\n                model = False\n\n        return model\n\n### EOF ###\n"
  },
  {
    "path": "scripts/Connector_PinSocket/parameters.yaml",
    "content": "#\n# Pin Sockets - footprint and 3D dimensions\n# NOTE for SMD parts: pins.length is overall length (tip to tip)\n#                     pads.lp_width is overall land pattern width\n# 2017-11-25\n#\nseries: THT-1x1.00mm_Vertical\nbody:\n    width: 1.5\n    height: 2.1\n    overlength: 0.5\n    offset: 0.0\npins:\n    min: 2\n    max: 40\n    width: 0.3\n    thickness: 0.1\n    drill: 0.5\n    length: 1.8\n    offset: 0.29\npads:\n    length: 0.85\n    width: 0.85\n    lp_width: 0\ndatasheet: https://gct.co/files/drawings/bc065.pdf\n---\nseries: THT-1x1.27mm_Vertical\nbody:\n    width: 2.54\n    height: 4.4\n    overlength: 0.0\n    offset: 0.0\npins:\n    min: 1\n    max: 40\n    width: 0.5\n    thickness: 0.2\n    drill: 0.7\n    length: 2.4\n    offset: 0.0\npads:\n    length: 1.0\n    width: 1.0\n    lp_width: 0\ndatasheet: from Kicad 4.0.7\n---\nseries: THT-1x2.00mm_Vertical\nbody:\n    width: 2.0\n    height: 5.6\n    overlength: 0.0\n    offset: 0.0\npins:\n    min: 1\n    max: 40\n    width: 0.6\n    thickness: 0.2\n    drill: 0.8\n    length: 2.5\n    offset: 0.0\npads:\n    length: 1.35\n    width: 1.35\n    lp_width: 0\ndatasheet: from Kicad 4.0.7\n---\nseries: THT-1x2.54mm_Vertical\nbody:\n    width: 2.54\n    height: 7.0\n    overlength: 0.0\n    offset: 0.0\npins:\n    min: 1\n    max: 40\n    width: 0.6\n    thickness: 0.2\n    drill: 1.0\n    length: 2.9\n    offset: 0.0\npads:\n    length: 1.7\n    width: 1.7\n    lp_width: 0\ndatasheet: from Kicad 4.0.7\n---\nseries: THT-2x1.00mm_Vertical N/A\nbody:\n    width: 1.5\n    height: 2.1\n    overlength: 0.75\n    offset: 0.0\npins:\n    min: 1\n    max: 40\n    width: 0.3\n    thickness: 0.1\n    drill: 0.5\n    length: 1.8\n    offset: 0.29\npads:\n    length: 0\n    width: 0\n    lp_width: 0\ndatasheet:\n---\nseries: THT-2x1.27mm_Vertical\nbody:\n    width: 3.05\n    height: 4.4\n    overlength: 0.0\n    offset: 0.0\npins:\n    min: 1\n    max: 40\n    width: 0.5\n    thickness: 0.2\n    drill: 0.7\n    length: 2.4\n    offset: 0.0\npads:\n    length: 1.0\n    width: 1.0\n    lp_width: 0\ndatasheet: from Kicad 4.0.7\n---\nseries: THT-2x2.00mm_Vertical\nbody:\n    width: 4.0\n    height: 5.6\n    overlength: 0.0\n    offset: 0.0\npins:\n    min: 1\n    max: 40\n    width: 0.6\n    thickness: 0.2\n    drill: 0.8\n    length: 2.5\n    offset: 0.0\npads:\n    length: 1.35\n    width: 1.35\n    lp_width: 0\ndatasheet: from Kicad 4.0.7\n---\nseries: THT-2x2.54mm_Vertical\nbody:\n    width: 5.08\n    height: 7.0\n    overlength: 0.0\n    offset: 0.0\npins:\n    min: 1\n    max: 40\n    width: 0.6\n    thickness: 0.2\n    drill: 1.0\n    length: 2.9\n    offset: 0.0\npads:\n    length: 1.7\n    width: 1.7\n    lp_width: 0\ndatasheet: from Kicad 4.0.7\n---\n#\n# Horizontal THT parts\n#\nseries: THT-1x1.00mm_Horizontal N/A\nbody:\n    width: 1.5\n    height: 2.1\n    overlength: 0.75\n    offset: 0.0\npins:\n    min: 1\n    max: 40\n    width: 0.3\n    thickness: 0.1\n    drill: 0.5\n    length: 1.8\n    offset: 0.29\npads:\n    length: 0\n    width: 0\n    lp_width: 0\ndatasheet:\n---\nseries: THT-1x1.27mm_Horizontal\nbody:\n    width: 4.3\n    height: 1.8\n    overlength: 0.35\n    offset: 0.15\npins:\n    min: 3\n    max: 40\n    width: 0.42\n    thickness: 0.15\n    drill: 0.65\n    length: 2.0\n    offset: 0.0\npads:\n    length: 1.0\n    width: 1.0\n    lp_width: 0\ndatasheet: https://gct.co/pdfjs/web/viewer.html?file=/Files/Drawings/BD090.pdf&t=1511593690632\n---\nseries: THT-1x2.00mm_Horizontal\nbody:\n    width: 6.35\n    height: 2.0\n    overlength: 0.0\n    offset: 1.27\npins:\n    min: 1\n    max: 40\n    width: 0.6\n    thickness: 0.2\n    drill: 0.8\n    length: 2.5\n    offset: 0.2\npads:\n    length: 1.35\n    width: 1.35\n    lp_width: 0\ndatasheet: from Kicad 4.0.7\n---\nseries: THT-1x2.54mm_Horizontal\nbody:\n    width: 8.51\n    height: 2.54\n    overlength: 0.0\n    offset: 1.52\npins:\n    min: 1\n    max: 40\n    width: 0.6\n    thickness: 0.2\n    drill: 1.0\n    length: 2.9\n    offset: 0.2\npads:\n    length: 1.7\n    width: 1.7\n    lp_width: 0\ndatasheet: from Kicad 4.0.7\n---\nseries: THT-2x1.00mm_Horizontal N/A\nbody:\n    width: 1.5\n    height: 2.1\n    overlength: 0.75\n    offset: 0.0\npins:\n    min: 1\n    max: 40\n    width: 0.3\n    thickness: 0.1\n    drill: 0.5\n    length: 1.8\n    offset: 0.29\npads:\n    length: 0\n    width: 0\n    lp_width: 0\ndatasheet:\n---\nseries: THT-2x1.27mm_Horizontal\nbody:\n    width: 4.4\n    height: 3.10\n    overlength: 0.35\n    offset: 0.15\npins:\n    min: 3\n    max: 50\n    width: 0.5\n    thickness: 0.15\n    drill: 0.65\n    length: 2.0\n    offset: 0.15\npads:\n    length: 1.0\n    width: 1.0\n    lp_width: 0\ndatasheet: https://gct.co/pdfjs/web/viewer.html?file=/Files/Drawings/BD091.pdf&t=1511594177220\n---\nseries: THT-2x2.00mm_Horizontal\nbody:\n    width: 6.35\n    height: 4.0\n    overlength: 0.0\n    offset: 1.27\npins:\n    min: 1\n    max: 40\n    width: 0.6\n    thickness: 0.2\n    drill: 0.8\n    length: 2.5\n    offset: 0.2\npads:\n    length: 1.35\n    width: 1.35\n    lp_width: 0\ndatasheet: from Kicad 4.0.7\n---\nseries: THT-2x2.54mm_Horizontal\nbody:\n    width: 8.51\n    height: 5.08\n    overlength: 0.0\n    offset: 1.52\npins:\n    min: 1\n    max: 40\n    width: 0.6\n    thickness: 0.2\n    drill: 1.0\n    length: 2.5\n    offset: 0.2\npads:\n    length: 1.7\n    width: 1.7\n    lp_width: 0\ndatasheet: from Kicad 4.0.7\n---\n#\n# SMD parts\n#\nseries: SMD-1x1.00mm_Vertical_Right\nbody:\n    width: 1.5\n    height: 2.25\n    overlength: 0.5\n    offset: 0.0\npins:\n    min: 2\n    max: 40\n    width: 0.3\n    thickness: 0.1\n    drill: None\n    length: 2.9\n    offset: 0.0\npads:\n    length: 1.95\n    width: 0.50\n    lp_width: 3.9\ndatasheet: https://gct.co/files/drawings/bc070.pdf\n---\nseries: SMD-1x1.00mm_Vertical_Left\nbody:\n    width: 1.5\n    height: 2.25\n    overlength: 0.5\n    offset: 0.0\npins:\n    min: 2\n    max: 40\n    width: 0.3\n    thickness: 0.1\n    drill: None\n    length: 2.9\n    offset: 0.0\npads:\n    length: 1.95\n    width: 0.50\n    lp_width: 3.9\ndatasheet: https://gct.co/files/drawings/bc070.pdf\n---\nseries: SMD-1x1.27mm_Vertical_Right\nbody:\n    width: 1.8\n    height: 4.6\n    overlength: 0.35\n    offset: 0.0\npins:\n    min: 2\n    max: 40\n    width: 0.42\n    thickness: 0.15\n    drill: None\n    length: 3.5\n    offset: 0.0\npads:\n    length: 1.8\n    width: 0.65\n    lp_width: 4.5\ndatasheet: https://gct.co/pdfjs/web/viewer.html?file=/Files/Drawings/BD075.pdf&t=1511594726925\n---\nseries: SMD-1x1.27mm_Vertical_Left\nbody:\n    width: 1.8\n    height: 4.6\n    overlength: 0.35\n    offset: 0.0\npins:\n    min: 2\n    max: 40\n    width: 0.42\n    thickness: 0.15\n    drill: None\n    length: 3.5\n    offset: 0.0\npads:\n    length: 1.8\n    width: 0.65\n    lp_width: 4.5\ndatasheet: https://gct.co/pdfjs/web/viewer.html?file=/Files/Drawings/BD075.pdf&t=1511594726925\n---\nseries: SMD-1x2.00mm_Vertical_Right\nbody:\n    width: 2.5\n    height: 4.3\n    overlength: 0.6\n    offset: 0.0\npins:\n    min: 2\n    max: 40\n    width: 0.5\n    thickness: 0.2\n    drill: None\n    length: 4.2\n    offset: 0.0\npads:\n    length: 2.0\n    width: 0.9\n    lp_width: 5.2\ndatasheet: https://www.jayconsystems.com/fileuploader/download/download/?d=1&file=custom%2Fupload%2FFile-1375728122.pdf\n---\nseries: SMD-1x2.00mm_Vertical_Left\nbody:\n    width: 2.5\n    height: 4.3\n    overlength: 0.6\n    offset: 0.0\npins:\n    min: 2\n    max: 40\n    width: 0.5\n    thickness: 0.2\n    drill: None\n    length: 4.2\n    offset: 0.0\npads:\n    length: 2.0\n    width: 0.9\n    lp_width: 5.2\ndatasheet: https://www.jayconsystems.com/fileuploader/download/download/?d=1&file=custom%2Fupload%2FFile-1375728122.pdf\n---\nseries: SMD-1x2.54mm_Vertical_Right\nbody:\n    width: 2.54\n    height: 7.1\n    overlength: 0.2\n    offset: 0.0\npins:\n    min: 2\n    max: 40\n    width: 0.6\n    thickness: 0.2\n    drill: None\n    length: 4.54\n    offset: 0.0\npads:\n    length: 1.9\n    width: 1.0\n    lp_width: 5.2\ndatasheet: https://cdn.harwin.com/pdfs/M20-786.pdf\n---\nseries: SMD-1x2.54mm_Vertical_Left\nbody:\n    width: 2.54\n    height: 7.1\n    overlength: 0.2\n    offset: 0.0\npins:\n    min: 2\n    max: 40\n    width: 0.6\n    thickness: 0.2\n    drill: None\n    length: 4.54\n    offset: 0.0\npads:\n    length: 1.9\n    width: 1.0\n    lp_width: 5.2\ndatasheet: https://cdn.harwin.com/pdfs/M20-786.pdf\n---\nseries: SMD-2x1.00mm_Vertical\nbody:\n    width: 2.5\n    height: 2.25\n    overlength: 0.5\n    offset: 0.0\npins:\n    min: 2\n    max: 40\n    width: 0.3\n    thickness: 0.1\n    drill: None\n    length: 3.9\n    offset: 0.0\npads:\n    length: 1.85\n    width: 0.50\n    lp_width: 4.9\ndatasheet: https://gct.co/files/drawings/bc085.pdf\n---\nseries: SMD-2x1.27mm_Vertical\nbody:\n    width: 2.54\n    height: 4.6\n    overlength: 0.0\n    offset: 0.0\npins:\n    min: 1\n    max: 40\n    width: 0.4\n    thickness: 0.15\n    drill: None\n    length: 5.11\n    offset: 0.0\npads:\n    length: 2.1\n    width: 0.75\n    lp_width: 5.7\ndatasheet: from Kicad 4.0.7!\n---\nseries: SMD-2x2.00mm_Vertical\nbody:\n    width: 4.0\n    height: 4.5\n    overlength: 0.0\n    offset: 0.0\npins:\n    min: 1\n    max: 40\n    width: 0.5\n    thickness: 0.2\n    drill: None\n    length: 6.0\n    offset: 0.0\npads:\n    length: 2.75\n    width: 1.0\n    lp_width: 9.0\ndatasheet: from Kicad 4.0.7\n---\nseries: SMD-2x2.54mm_Vertical\nbody:\n    width: 5.08\n    height: 7.0\n    overlength: 0.0\n    offset: 0.0\npins:\n    min: 1\n    max: 40\n    width: 0.64\n    thickness: 0.2\n    drill: None\n    length: 7.84\n    offset: 0.0\npads:\n    length: 3.0\n    width: 1.0\n    lp_width: 8.04\ndatasheet: from Kicad 4.0.7\n"
  },
  {
    "path": "scripts/Connector_PinSocket/socket_strips.py",
    "content": "#!/usr/bin/env python\n\n#\n# Parts script module for socket strip footprints for KicCad\n#\n# This script is built on top of the kicad-footprint-generator framework\n# by Thomas Pointhuber, https://github.com/pointhi/kicad-footprint-generator\n#\n# This module is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This module is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n\n#\n# based on scripts/tools/footprint_scripts_pin_headers.py\n# refactored by and (C) 2017 Terje Io, <http://github.com/terjeio>\n#\n\n# 2017-11-25\n\nimport sys\nimport os\n\nsys.path.append(os.path.dirname(os.path.realpath(__file__)) + \"/../..\")\n\nfrom KicadModTree import Footprint, Translation, Pad, Model, KicadFileHandler\nfrom canvas import Layer, PadLayer, Keepout, OutDir\nfrom cq_base_parameters import PinStyle, CaseType\n\ntxt_descr = [\"\", \", single row\", \", double cols\", \", double cols\", \", triple cols\", \", quadruple cols\"]\ntxt_tag = [\"\", \" single row\", \" double row\", \", triple cols\", \" quadruple row\"]\n\nroot_dir = OutDir(\"./\")\n\n#Keepout.DEBUG = 1\n\ndef getPadOffsets(overall_width, pad):\n    return round((overall_width - pad[0]) / 2.0, 3)\n\ndef getPinLength(overall_width, packwidth):\n    return round((overall_width - packwidth) / 2.0, 3)\n\nclass pinSocketVerticalTHT (object):\n    def __init__(self, params):\n        self.make_me = params.type == CaseType.THT and params.pin_style == PinStyle.STRAIGHT and params.pad_width > 0\n        self.params = params\n\n    def makeModelName(self, genericName):\n        return \"PinSocket_{0}x{1:02}_P{2:03.2f}mm_Vertical\".format(self.params.num_pin_rows, self.params.num_pins, self.params.pin_pitch)\n\n    def make(self, tags_additional=[], isSocket=True):\n\n        param = self.params\n\n        lib_name =\"Connector_PinSocket_{0:03.2f}mm\".format(param.pin_pitch)\n        footprint_name = self.makeModelName(\"\")\n        description = \"Through hole straight socket strip, {0}x{1:02}, {2:03.2f}mm pitch\".format(param.num_pin_rows, param.num_pins, param.pin_pitch)\n        tags = \"Through hole socket strip THT {0}x{1:02} {2:03.2f}mm\".format(param.num_pin_rows, param.num_pins, param.pin_pitch)\n\n        tags += txt_tag[param.num_pin_rows]\n        description += txt_descr[param.num_pin_rows]\n\n        pad = [param.pad_length, param.pad_width]\n        rowdist = param.pin_pitch\n\n        if len(tags_additional) > 0:\n            for t in tags_additional:\n                footprint_name = footprint_name + \"_\" + t\n                description = description + \", \" + t\n                tags = tags + \" \" + t\n\n        if len(param.datasheet) > 0:\n            description += \" (\" + param.datasheet + \")\"\n\n        description += \", script generated\"\n\n        print(\"###################\")\n        print(footprint_name, \"in\", lib_name)\n\n        # init kicad footprint\n        kicad_mod = Footprint(footprint_name)\n        kicad_mod.setDescription(description)\n        kicad_mod.setTags(tags)\n\n        if Keepout.DEBUG:\n            kicad_modg = Translation(0.0, 0.0)\n        else:\n            kicad_modg = Translation(-rowdist if isSocket and param.num_pin_rows > 1 else -param.pins_offset, 0.0)\n        kicad_mod.append(kicad_modg)\n\n        # create layer canvases\n        silk    = Layer(kicad_modg, 'F.SilkS')\n        fab     = Layer(kicad_modg, 'F.Fab')\n        crt     = Layer(kicad_modg, 'F.CrtYd', offset=0.5) # offset 0.5 for connectors\n        pads    = PadLayer(kicad_modg, pad, Pad.TYPE_THT, Pad.SHAPE_OVAL, shape_first=Pad.SHAPE_RECT, drill=param.pin_drill, x_offset=param.pins_offset)\n        keepout = Keepout(silk)\n\n        if Keepout.DEBUG:\n            kicad_mod.setSolderMaskMargin(silk.getSoldermaskMargin())\n\n        rmh = param.pin_pitch / 2.0\n        r_dist = rowdist * (param.num_pin_rows - 1)\n\n        h_fab = param.num_pins * param.pin_pitch + param.body_overlength\n        w_fab = param.body_width\n        t_fab = -rmh - param.body_overlength / 2.0\n\n        h_slk = h_fab + silk.offset * 2.0\n        w_slk = max(w_fab + silk.offset * 2.0, r_dist - pad[0] - silk.offset * 4.0)\n        t_slk = t_fab - silk.offset\n\n        w_crt = max(param.body_width, r_dist + pad[0]) + crt.offset * 2.0\n        h_crt = max(h_fab, (param.num_pins - 1) * param.pin_pitch + pad[1]) + crt.offset * 2.0\n        t_crt = t_fab - crt.offset\n\n        c_ofs = 0.0 if param.num_pin_rows == 1 else rmh\n\n        if param.num_pin_rows == 1:\n            r_dist = rowdist\n\n        # create pads\n\n        y = 0.0\n        for r in range(1, param.num_pins + 1):\n            x = rowdist if isSocket and param.num_pin_rows > 1 else 0.0\n            for c in range(1, param.num_pin_rows + 1):\n                pads.add(x, y)\n                x = x + (-rowdist if isSocket and param.num_pin_rows > 1 else rowdist)\n            y += param.pin_pitch\n\n        # add pads to silk keepout\n        keepout.addPads()\n        keepout.debug_draw()\n\n        # add text to silk layer\n        silk.goto(c_ofs, t_crt - silk.txt_offset)\\\n            .text('reference', 'REF**')\\\n            .setOrigin(-w_slk / 2.0 + c_ofs, t_slk)\n\n        # add fab layer\n        bevel = Layer.getBevel(h_fab, w_fab)\n        fab.goto(c_ofs, h_crt + t_crt + fab.txt_offset)\\\n           .text('value', footprint_name)\\\n           .goto(c_ofs, h_fab / 2.0 + t_fab)\\\n           .setTextDefaults(max_size=1.0)\\\n           .setTextSize(0.6 * (h_fab if param.num_pins == 1 and param.num_pin_rows <= 2 else w_fab))\\\n           .text('user', '%R', rotation=0 if param.num_pins == 1 and param.num_pin_rows <= 2 else 90)\\\n           .setOrigin(-w_fab / 2.0 + c_ofs, t_fab)\\\n           .rect(w_fab, h_fab, bevel=(0.0 if isSocket else bevel, bevel if isSocket else 0.0, 0.0, 0.0), origin=\"topLeft\")\n\n        # continue with silkscreen\n\n        pin1 = keepout.getPadBB(1)\n\n    #    if isSocket and param.pins_offset > 0.0: # for 1.00 mm sockets\n    #        w_slk = w_slk / 2.0 + (pin1.width / 2.0 + pin1.x)\n\n        f = -1 if isSocket else 1\n\n        if param.num_pin_rows == 1:\n            silk.jump(w_slk if isSocket else 0.0, -t_slk + rmh)\n            if param.num_pins == 1:\n                silk.down(silk.offset, draw=False)\\\n                    .right(f * w_slk)\\\n                    .up(silk.line_width)\\\n                    .jump(-f * w_slk, silk.line_width)\\\n                    .up(silk.line_width)\n            else:\n                silk.rect(f * w_slk, h_slk - rmh + t_slk, origin=\"topLeft\")\n        else:\n            if isSocket:\n                silk.right(w_slk, draw=False)\n            silk.right(f * w_slk / 2.0, draw=False)\\\n                .right(f * w_slk / 2.0)\\\n                .down(h_slk)\\\n                .left(f * w_slk)\\\n                .up(h_slk + t_slk - rowdist / 2.0)\\\n                .right(f * w_slk / 2.0)\\\n                .up(-t_slk + rowdist / 2.0)\n\n        # add pin1 marker\n        silk.goto(max(pin1.x - f * pin1.width / 2.0, w_slk / 2.0 + c_ofs), pin1.y)\\\n            .up(max(-t_slk, pin1.height / 2.0))\\\n            .right(f * (silk.x - pin1.x))\n\n        # add courtyard\n        crt.setOrigin(-w_crt / 2.0 + c_ofs, t_crt)\\\n           .rect(w_crt, h_crt, origin=\"topLeft\")\n\n        # add model\n        kicad_modg.append(Model(filename=\"${KISYS3DMOD}/\" + lib_name + \".3dshapes/\" + footprint_name + \".wrl\"))\n\n        # write file\n        file_handler = KicadFileHandler(kicad_mod)\n        file_handler.writeFile(root_dir.saveTo(lib_name) + footprint_name + '.kicad_mod')\n\n\n\n#\n#                                                          <-->pack_offset\n#                 <--------------pack_width--------------->\n#                                                             <-rowdist>\n#                 +---------------------------------------+            ---+\n#                 |                                       |  OOO      OOO |          ^\n#                 |                                       |  OOO ==== OOO |  ^       pin_width\n#                 |                                       |  OOO      OOO    |       v\n#                 +---------------------------------------+                  pin_pitch\n#                 |                                       |  OOO      OOO    |\n#                 |                                       |  OOO ==== OOO    v\n#                 |                                       |  OOO      OOO\n#                 +---------------------------------------+\n#\nclass pinSocketHorizontalTHT (object):\n    def __init__(self, params):\n        self.make_me =  params.type == CaseType.THT and params.pin_style == PinStyle.ANGLED and params.pad_width > 0\n        self.params = params\n\n    def makeModelName(self, genericName):\n        return \"PinSocket_{0}x{1:02}_P{2:03.2f}mm_Horizontal\".format(self.params.num_pin_rows, self.params.num_pins, self.params.pin_pitch)\n\n    def make(self, tags_additional=[], isSocket=True):\n\n        param = self.params\n\n        lib_name =\"Connector_PinSocket_{0:03.2f}mm\".format(param.pin_pitch)\n        footprint_name = self.makeModelName(\"\")\n        description = \"Through hole angled socket strip, {0}x{1:02}, {2:03.2f}mm pitch, {3}mm socket length\"\\\n                       .format(param.num_pin_rows, param.num_pins, param.pin_pitch, param.body_width)\n        tags = \"Through hole angled socket strip THT {0}x{1:02} {2:03.2f}mm\".format(param.num_pin_rows, param.num_pins, param.pin_pitch)\n\n        tags += txt_tag[param.num_pin_rows]\n        description += txt_descr[param.num_pin_rows]\n\n        pad = [param.pad_length, param.pad_width]\n        rowdist = param.pin_pitch\n\n        if len(tags_additional) > 0:\n            for t in tags_additional:\n                footprint_name = footprint_name + \"_\" + t\n                description = description + \", \" + t\n                tags = tags + \" \" + t\n\n        if len(param.datasheet) > 0:\n            description += \" (\" + param.datasheet + \")\"\n\n        description += \", script generated\"\n\n        print(\"###################\")\n        print(footprint_name, \"in\", lib_name)\n\n        # init kicad footprint\n        kicad_mod = Footprint(footprint_name)\n        kicad_mod.setDescription(description)\n        kicad_mod.setTags(tags)\n\n        # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n        kicad_modg = Translation(0, 0)\n        kicad_mod.append(kicad_modg)\n\n        # create layer canvases\n        silk    = Layer(kicad_modg, 'F.SilkS')\n        fab     = Layer(kicad_modg, 'F.Fab')\n        crt     = Layer(kicad_modg, 'F.CrtYd', offset=0.5) # offset 0.5 for connectors\n        pads    = PadLayer(kicad_modg, pad, Pad.TYPE_THT, Pad.SHAPE_OVAL, shape_first=Pad.SHAPE_RECT, drill=param.pin_drill)\n        keepout = Keepout(silk)\n\n        if Keepout.DEBUG:\n            kicad_mod.setSolderMaskMargin(silk.getSoldermaskMargin())\n\n        rmh = param.pin_pitch / 2.0\n        r_dist = rowdist * (param.num_pin_rows - 1)\n\n        h_fab = (param.num_pins - 1) * param.pin_pitch + param.pin_pitch\n        w_fab = -param.body_width\n        l_fab = -(r_dist + param.body_offset)\n        t_fab = -rmh\n\n        h_slk = h_fab + silk.offset * 2.0\n        w_slk = w_fab - silk.offset * 2.0\n        l_slk = l_fab + silk.offset\n        t_slk = t_fab - silk.offset\n\n        w_crt = -(rmh + r_dist + param.body_offset + param.body_width + crt.offset * 2.0)\n        h_crt = h_fab + crt.offset * 2.0\n        l_crt = rmh + crt.offset\n        t_crt = -rmh - crt.offset\n\n        # create pads\n        y = 0.0\n        for r in range(1, param.num_pins + 1):\n            x = 0.0\n            for c in range(1, param.num_pin_rows + 1):\n                pads.add(x, y)\n                x -= rowdist\n            y += param.pin_pitch\n\n        # add pads to silk keepout\n        keepout.addPads()\n        keepout.debug_draw()\n\n        # add text to silk\n        silk.goto(l_crt + w_crt / 2.0, t_crt - silk.txt_offset)\\\n            .text('reference', 'REF**')\n\n        # create FAB-layer\n        bevel = min(Layer.getBevel(h_fab, abs(w_fab)), -t_fab - param.pin_width / 2.0)\n\n        fab.goto(l_fab + w_fab / 2.0, (h_fab - param.pin_pitch) / 2.0)\\\n           .text('user', '%R', rotation=(90 if h_fab >= -w_fab else 0))\\\n           .rect(-w_fab, h_fab, bevel=(0.0, bevel, 0.0, 0.0))\\\n           .goto(l_crt + w_crt / 2.0, h_crt + t_crt + fab.txt_offset)\\\n           .text('value', footprint_name)\n\n        # add pin markers\n        fab.goto(l_fab / 2.0, 0.0)\n        for r in range(1, param.num_pins + 1):\n            fab.rect(l_fab, param.pin_width, draw=(True, False, True, True))\\\n               .down(param.pin_pitch, False)\n\n        # continue silk layer, set origin and fill pin1 rectangle\n        silk.setOrigin(l_fab + w_slk + silk.offset, t_slk)\\\n            .jump(0.0, -t_slk - rmh)\\\n            .fillrect(-w_slk, param.pin_pitch + silk.offset + (silk.offset if param.num_pins == 1 else 0.0))\\\n\n        pw = param.pin_width + silk.offset * 2.0\n\n        # add pin markers\n        silk.goto(l_slk / 2.0, 0.0)\n        for r in range(1, param.num_pins + 1):\n            silk.rect(l_slk, pw, draw=(True, False, True, False))\\\n               .down(param.pin_pitch, False)\n\n        #add separation lines\n        silk.goHome()\\\n            .jump(0.0, silk.line_width / 2.0)\n        for r in range(1, param.num_pins + 1):\n            silk.right(-w_slk, r != 1)\\\n                .jump(w_slk, param.pin_pitch)\n\n        # add outline\n        silk.goHome()\\\n            .rect(-w_slk, h_slk, origin='topLeft')\n\n        pin1 = keepout.getPadBB(1)\n\n        # add pin1 marker\n        silk.goto(pin1.x + pin1.width / 2.0, pin1.y)\\\n            .up(max(-t_slk, pin1.height / 2.0))\\\n            .left(silk.x - pin1.x)\n\n        # create courtyard\n        crt.setOrigin(l_crt + w_crt / 2.0, t_crt + h_crt / 2.0)\\\n           .rect(w_crt, h_crt)\n\n        # add model\n        kicad_modg.append(Model(filename=\"${KISYS3DMOD}/\" + lib_name + \".3dshapes/\" + footprint_name + \".wrl\"))\n\n        # write file\n        file_handler = KicadFileHandler(kicad_mod)\n        file_handler.writeFile(root_dir.saveTo(lib_name) + footprint_name + '.kicad_mod')\n\n\n\nclass pinSocketVerticalSMD (object):\n    def __init__(self, params):\n        self.make_me = params.type == 'SMD' and params.pad_width > 0\n        self.params = params\n\n    def makeModelName(self, genericName):\n        genericName = \"PinSocket_{0}x{1:02}_P{2:03.2f}mm_Vertical_SMD\".format(self.params.num_pin_rows, self.params.num_pins, self.params.pin_pitch)\n        return genericName + ((\"_Pin1Right\" if self.params.pin1start_right else \"_Pin1Left\") if self.params.num_pin_rows == 1 else \"\" )\n\n    def make(self, tags_additional=[], isSocket=True):\n\n        param = self.params\n\n        lib_name =\"Connector_PinSocket_{0:03.2f}mm\".format(param.pin_pitch)\n        footprint_name = self.makeModelName(\"\")\n        description = \"surface-mounted straight socket strip, {0}x{1:02}, {2:03.2f}mm pitch\".format(param.num_pin_rows, param.num_pins, param.pin_pitch)\n        tags = \"Surface mounted socket strip SMD {0}x{1:02} {2:03.2f}mm\".format(param.num_pin_rows, param.num_pins, param.pin_pitch)\n\n        tags += txt_tag[param.num_pin_rows]\n        description += txt_descr[param.num_pin_rows]\n\n        pad = [param.pad_length, param.pad_width]\n        rowdist = param.pin_pitch\n\n        rmx_pad_offset = getPadOffsets(param.pads_lp_width, pad)\n        rmx_pin_length = getPinLength(param.pin_length, param.body_width)\n\n        if (param.num_pin_rows == 1):\n            if param.pin1start_right:\n                description += \", style 2 (pin 1 right)\"\n                tags += \" style2 pin1 right\"\n            else:\n                description += \", style 1 (pin 1 left)\"\n                tags += \" style1 pin1 left\"\n\n        if len(tags_additional) > 0:\n            for t in tags_additional:\n                footprint_name = footprint_name + \"_\" + t\n                description = description + \", \" + t\n                tags = tags + \" \" + t\n\n        if len(param.datasheet) > 0:\n            description += \" (\" + param.datasheet + \")\"\n\n        description += \", script generated\"\n\n        print(\"###################\")\n        print(footprint_name, \"in\", lib_name)\n\n        # init kicad footprint\n        kicad_mod = Footprint(footprint_name)\n        kicad_mod.setDescription(description)\n        kicad_mod.setTags(tags)\n        kicad_mod.setAttribute('smd')\n\n        # anchor for SMD-symbols is in the center\n        kicad_modg = Translation(0.0, 0.0)\n        kicad_mod.append(kicad_modg)\n\n        rmh = param.pin_pitch / 2.0\n\n        # create layer canvases\n        silk    = Layer(kicad_modg, 'F.SilkS')\n        fab     = Layer(kicad_modg, 'F.Fab')\n        crt     = Layer(kicad_modg, 'F.CrtYd', offset=0.5) # offset 0.5 for connectors\n        pads    = PadLayer(kicad_modg, pad, Pad.TYPE_SMT, Pad.SHAPE_RECT, y_offset=(param.num_pins - 1) * -rmh)\n        keepout = Keepout(silk)\n\n        if Keepout.DEBUG:\n            kicad_mod.setSolderMaskMargin(silk.getSoldermaskMargin())\n\n        r_dist = rowdist * (param.num_pin_rows - 1)\n\n        h_fab = param.num_pins * param.pin_pitch + param.body_overlength\n        w_fab = param.body_width\n        t_fab = -param.body_overlength / 2.0\n\n        h_slk = h_fab + silk.offset * 2.0\n        w_slk = max(w_fab + silk.offset * 2.0, r_dist - pad[0] - silk.offset * 4.0)\n    #    l_slk = (r_dist - w_slk) / 2.0\n    #    t_slk = -param.body_overlength - silk.offset\n\n        h_crt = max(h_fab, (param.num_pins - 1) * param.pin_pitch + pad[1]) + crt.offset * 2.0\n        w_crt = max(param.body_width, rmx_pad_offset * 2.0 + pad[0]) + crt.offset * 2.0\n\n        cleft = range(1, param.num_pins, 2) if param.pin1start_right else range(0, param.num_pins, 2)\n        cright = range(0, param.num_pins, 2) if param.pin1start_right else range(1, param.num_pins, 2)\n        even_pins = param.num_pins % 2.0 == 0.0\n\n        # create pads\n        if param.num_pin_rows == 1:\n            for y in cleft:\n                pads.add(-rmx_pad_offset, y * param.pin_pitch, number=y + 1)\n            for y in cright:\n                pads.add(rmx_pad_offset, y * param.pin_pitch, number=y + 1)\n        elif param.num_pin_rows == 2:\n            f = 1.0 if isSocket else -1.0\n            for y in range(0,param.num_pins):\n                pads.add(f * rmx_pad_offset, y * param.pin_pitch)\\\n                    .add(f * -rmx_pad_offset, y * param.pin_pitch)\n\n        # add pads to silk keepout\n        keepout.addPads()\n        keepout.debug_draw()\n\n        # add text and outline to silk layer\n        silk.goto(0.0, -(h_crt / 2.0) - silk.txt_offset)\\\n            .text('reference', 'REF**')\\\n            .setOrigin(-w_slk / 2.0, -h_slk / 2.0)\\\n            .rect(w_slk, h_slk, origin = \"topLeft\")\n\n        # pin1 marker\n        pad1 = keepout.getPadBB(1)\n        f = 1 if isSocket ^ (not param.pin1start_right) else -1\n\n        silk.gotoY(pad1.y)\\\n            .jump(w_slk if f == 1 else 0.0, -pad1.height / 2.0)\\\n            .right(f * (pad[0] - silk.line_width) / 2.0 - (silk.x - pad1.x))\n\n        # add text and outline to fab layer\n        bevel = min(Layer.getBevel(h_fab, w_fab), -t_fab + rmh + param.pin_width / 2.0)\n\n        fab.down((h_crt) / 2.0 + fab.txt_offset, draw=False)\\\n           .text('value', footprint_name)\\\n           .goHome()\\\n           .setTextDefaults(max_size=1.0)\\\n           .setTextSize(0.6 * (h_fab if param.num_pins == 1 and param.num_pin_rows <= 2 else w_fab))\\\n           .text('user', '%R', rotation=(90 if h_fab >= w_fab else 0))\\\n           .rect(w_fab, h_fab, bevel=(0.0 if param.pin1start_right else bevel, bevel if param.pin1start_right else 0.0, 0.0, 0.0))\\\n           .setOrigin(-w_fab / 2.0, -h_fab / 2.0)\n\n        # add pin markers to fab layer\n        trl = w_fab + rmx_pin_length\n        if param.num_pin_rows == 2:\n            fab.jump(-rmx_pin_length / 2.0, -t_fab + rmh)\n            for r in range(1, param.num_pins + 1):\n                fab.rect(rmx_pin_length, param.pin_width, draw=(True, False, True, True))\\\n                   .right(trl, draw=False)\\\n                   .rect(rmx_pin_length, param.pin_width, draw=(True, True, True, False))\\\n                   .left(trl, draw=False)\\\n                   .down(param.pin_pitch, draw=False)\n        elif param.pin1start_right:\n            trl = -trl\n            fab.jump(w_fab + rmx_pin_length / 2.0, -t_fab + rmh)\n            for c in cright:\n                fab.rect(rmx_pin_length, param.pin_width, draw=(True, True, True, False))\\\n                   .jump(trl, param.pin_pitch)\n                if even_pins or c != cright[-1]:\n                    fab.rect(rmx_pin_length, param.pin_width, draw=(True, False, True, True))\\\n                       .jump(-trl, param.pin_pitch)\n        else:\n            fab.jump(-rmx_pin_length / 2.0, -t_fab + rmh)\n            for c in cleft:\n                fab.rect(rmx_pin_length, param.pin_width, draw=(True, False, True, True))\\\n                   .jump(trl, param.pin_pitch)\n                if even_pins or c != cleft[-1]:\n                    fab.rect(rmx_pin_length, param.pin_width, draw=(True, True, True, False))\\\n                       .jump(-trl, param.pin_pitch)\n\n        # add courtyard\n        crt.rect(w_crt, h_crt)\n\n        # add model\n        kicad_modg.append(Model(filename=\"${KISYS3DMOD}/\" + lib_name + \".3dshapes/\" + footprint_name + \".wrl\"))\n\n        # write file\n        file_handler = KicadFileHandler(kicad_mod)\n        file_handler.writeFile(root_dir.saveTo(lib_name) + footprint_name + '.kicad_mod')\n\n### EOF ###\n"
  },
  {
    "path": "scripts/Connectors_DSub/make_dsubs.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_dsub import *  # NOQA\n\n\n\n\nif __name__ == '__main__':\n\n    HighDensity=False\n    rmx=2.77\n    rmy=2.84\n    rmy_unboxed2=2.54\n    pindrill=1.0\n    pad=1.6\n    mountingdrill=3.2\n    mountingpad=4\n    side_angle_degree=10\n    conn_cornerradius=1.6\n    outline_cornerradius=1\n    can_height_male=6\n    can_height_female=6.17\n    shieldthickness=0.4\n    backcan_height=4.5\n    smaller_backcan_height=2.8\n    soldercup_length=2.9\n    soldercup_diameter=1.2\n    soldercup_padsize=[2*rmx/3,soldercup_length*1.2]\n    soldercup_pad_edge_offset=0.25\n    smaller_backcan_offset=1\n    nut_diameter=5\n    nut_length=5\n    tags_additional=[]\n    lib_name=\"${KISYS3DMOD}/Connectors_DSub\"\n    classname=\"DSUB\"\n    classname_description=\"D-Sub connector\"\n    webpage=\"https://disti-assets.s3.amazonaws.com/tonar/files/datasheets/16730.pdf\"\n    #                  0,             1,             2,             3,         4,                5,                  6\n    #               pins, mounting_dist, outline_sizex, outlinesize_y, connwidth,  connheight_male,  connheight_female\n    sizes_table=[\n                [      9,            25,         30.85,         12.50,      16.3,              8.3,              7.9 ],\n                [     15,         33.30,         39.20,         12.50,      24.6,              8.3,              7.9 ],\n                [     25,         47.10,         53.10,         12.50,      38.3,              8.3,              7.9 ],\n                [     37,         63.50,         69.40,         12.50,      54.8,              8.3,              7.9 ],\n                ]\n    for data in sizes_table:\n        makeDSubStraight(pins=data[0], isMale=True, HighDensity=HighDensity, rmx=rmx, rmy=rmy, pindrill=pindrill, pad=pad, mountingdrill=mountingdrill, mountingpad=mountingpad, mountingdistance=data[1], outline_size=[data[2],data[3]], outline_cornerradius=outline_cornerradius, connwidth=data[4], side_angle_degree=side_angle_degree, connheight=data[5], conn_cornerradius=conn_cornerradius, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage)\n        makeDSubStraight(pins=data[0], isMale=False, HighDensity=HighDensity, rmx=rmx, rmy=rmy, pindrill=pindrill, pad=pad, mountingdrill=mountingdrill, mountingpad=mountingpad, mountingdistance=data[1], outline_size=[data[2],data[3]], outline_cornerradius=outline_cornerradius, connwidth=data[4], side_angle_degree=side_angle_degree, connheight=data[6], conn_cornerradius=conn_cornerradius, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage)\n        makeDSubStraight(pins=data[0], isMale=True, HighDensity=HighDensity, rmx=rmx, rmy=rmy, pindrill=pindrill, pad=pad, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], outline_size=[data[2],data[3]], outline_cornerradius=outline_cornerradius, connwidth=data[4], side_angle_degree=side_angle_degree, connheight=data[5], conn_cornerradius=conn_cornerradius, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage)\n        makeDSubStraight(pins=data[0], isMale=False, HighDensity=HighDensity, rmx=rmx, rmy=rmy, pindrill=pindrill, pad=pad, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], outline_size=[data[2],data[3]], outline_cornerradius=outline_cornerradius, connwidth=data[4], side_angle_degree=side_angle_degree, connheight=data[6], conn_cornerradius=conn_cornerradius, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage)\n        \n        makeDSubEdge(pins=data[0], isMale=True, rmx=rmx, pad=soldercup_padsize, mountingdrill=mountingdrill, mountingdistance=data[1], shield_width=data[2], shieldthickness=shieldthickness, connwidth=data[4], can_height=can_height_male, backcan_width=data[4]+2*shieldthickness, backcan_height=backcan_height, smaller_backcan_offset=smaller_backcan_offset, smaller_backcan_height=smaller_backcan_height, soldercup_length=soldercup_length, soldercup_diameter=soldercup_diameter, soldercup_pad_edge_offset=soldercup_pad_edge_offset, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage)\n        makeDSubEdge(pins=data[0], isMale=False, rmx=rmx, pad=soldercup_padsize, mountingdrill=mountingdrill, mountingdistance=data[1], shield_width=data[2], shieldthickness=shieldthickness, connwidth=data[4], can_height=can_height_female, backcan_width=data[4]+2*shieldthickness, backcan_height=backcan_height, smaller_backcan_offset=smaller_backcan_offset, smaller_backcan_height=smaller_backcan_height, soldercup_length=soldercup_length, soldercup_diameter=soldercup_diameter, soldercup_pad_edge_offset=soldercup_pad_edge_offset, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage)\n        \n\n\n    # boxed angled\n    #                   mounting_pcb_distance,   pin_pcb_distance\n    angled_distances=[\n                        [                7.88,               5.34 ],\n                        [                9.52,               8.10 ],\n                        [               11.72,              10.30 ],\n                        [               16.38,              14.96 ],\n                        [                8.60,              14.96 ],\n                    ]\n    for data in sizes_table:\n        for angled_distance in angled_distances:\n            mounting_pcb_distance=angled_distance[0]-shieldthickness\n            pin_pcb_distance=angled_distance[1]-shieldthickness\n            backbox_height=max(pin_pcb_distance+rmy+pad/2, mounting_pcb_distance+mountingpad/2)+1\n            makeDSubAngled(pins=data[0], isMale=True, HighDensity=HighDensity, rmx=rmx, rmy=rmy, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=mountingdrill, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=mounting_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, can_width=data[4], can_height=can_height_male, backbox_width=data[2], backbox_height=backbox_height, nut_diameter=nut_diameter, nut_length=nut_length, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage)\n            makeDSubAngled(pins=data[0], isMale=False, HighDensity=HighDensity, rmx=rmx, rmy=rmy, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=mountingdrill, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=mounting_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, can_width=data[4], can_height=can_height_female, backbox_width=data[2], backbox_height=backbox_height, nut_diameter=nut_diameter, nut_length=nut_length, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage)\n            #makeDSubAngled(pins=data[0], isMale=True, HighDensity=HighDensity, rmx=rmx, rmy=rmy, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=mounting_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, can_width=data[4], can_height=can_height_male, backbox_width=data[2], backbox_height=backbox_height, nut_diameter=nut_diameter, nut_length=nut_length, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage)\n            #makeDSubAngled(pins=data[0], isMale=False, HighDensity=HighDensity, rmx=rmx, rmy=rmy, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=mounting_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, can_width=data[4], can_height=can_height_female, backbox_width=data[2], backbox_height=backbox_height, nut_diameter=nut_diameter, nut_length=nut_length, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage)\n    \n    # unboxed angled\n    webpageunboxed='http://docs-europe.electrocomponents.com/webdocs/1585/0900766b81585df2.pdf'\n    backcan_height_unboxed=4.1\n    pin_pcb_distance=9.4\n    mounting_pcb_distance=0\n    for data in sizes_table:\n        makeDSubAngled(pins=data[0], isMale=True, HighDensity=HighDensity, rmx=rmx, rmy=rmy, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=pin_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, backbox_width=0, backbox_height=0, can_width=data[4], can_height=can_height_male, backcan_width=data[4]+2*shieldthickness, backcan_height=backcan_height_unboxed, nut_diameter=0, nut_length=0, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpageunboxed)\n        makeDSubAngled(pins=data[0], isMale=False, HighDensity=HighDensity, rmx=rmx, rmy=rmy, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=pin_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, backbox_width=0, backbox_height=0, can_width=data[4], can_height=can_height_female, backcan_width=data[4]+2*shieldthickness, backcan_height=backcan_height_unboxed, nut_diameter=0, nut_length=0, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpageunboxed)\n        # alternatice y-pin-pitch\n        makeDSubAngled(pins=data[0], isMale=True, HighDensity=HighDensity, rmx=rmx, rmy=rmy_unboxed2, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=pin_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, backbox_width=0, backbox_height=0, can_width=data[4], can_height=can_height_male, backcan_width=data[4]+2*shieldthickness, backcan_height=backcan_height_unboxed, nut_diameter=0, nut_length=0, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpageunboxed)\n        makeDSubAngled(pins=data[0], isMale=False, HighDensity=HighDensity, rmx=rmx, rmy=rmy_unboxed2, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=pin_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, backbox_width=0, backbox_height=0, can_width=data[4], can_height=can_height_female, backcan_width=data[4]+2*shieldthickness, backcan_height=backcan_height_unboxed, nut_diameter=0, nut_length=0, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpageunboxed)\n\n\n\n    HighDensity=True\n    rmy=1.98\n        #           pins, mounting_dist, outline_sizex, outlinesize_y, connwidth,  connheight_male,  connheight_female, rmx,  HighDensityOffsetMidLeft\n    sizes_table=[\n                [     15,            25,         30.85,         12.50,      16.3,              8.3,              7.9,    2.29, 7.04 ],\n                [     26,         33.30,         39.20,         12.50,      24.6,              8.3,              7.9,    2.29, 6.88 ],\n                [     44,         47.10,         53.10,         12.50,      38.3,              8.3,              7.9,    2.29, 6.88 ],\n                [     62,         63.50,         69.40,         12.50,      54.8,              8.3,              7.9,    2.41, 7.00 ],\n                ]\n    for data in sizes_table:\n        makeDSubStraight(pins=data[0], isMale=True, HighDensity=HighDensity, rmx=data[7], rmy=rmy, pindrill=pindrill, pad=pad, mountingdrill=mountingdrill, mountingpad=mountingpad, mountingdistance=data[1], outline_size=[data[2],data[3]], outline_cornerradius=outline_cornerradius, connwidth=data[4], side_angle_degree=side_angle_degree, connheight=data[5], conn_cornerradius=conn_cornerradius, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage, HighDensityOffsetMidLeft=data[8])\n        makeDSubStraight(pins=data[0], isMale=False, HighDensity=HighDensity, rmx=data[7], rmy=rmy, pindrill=pindrill, pad=pad, mountingdrill=mountingdrill, mountingpad=mountingpad, mountingdistance=data[1], outline_size=[data[2],data[3]], outline_cornerradius=outline_cornerradius, connwidth=data[4], side_angle_degree=side_angle_degree, connheight=data[6], conn_cornerradius=conn_cornerradius, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage, HighDensityOffsetMidLeft=data[8])\n        #makeDSubStraight(pins=data[0], isMale=True, HighDensity=HighDensity, rmx=data[7], rmy=rmy, pindrill=pindrill, pad=pad, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], outline_size=[data[2],data[3]], outline_cornerradius=outline_cornerradius, connwidth=data[4], side_angle_degree=side_angle_degree, connheight=data[5], conn_cornerradius=conn_cornerradius, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage, HighDensityOffsetMidLeft=data[8])\n        #makeDSubStraight(pins=data[0], isMale=False, HighDensity=HighDensity, rmx=data[7], rmy=rmy, pindrill=pindrill, pad=pad, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], outline_size=[data[2],data[3]], outline_cornerradius=outline_cornerradius, connwidth=data[4], side_angle_degree=side_angle_degree, connheight=data[6], conn_cornerradius=conn_cornerradius, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage, HighDensityOffsetMidLeft=data[8])\n        \n        \n    #                   mounting_pcb_distance,   pin_pcb_distance,  backbox_height\n    angled_distances=[\n                        [                5.34,               3.43,             8.6 ],\n                        [               11.29,               8.75,             0.0 ],\n                    ]\n    for data in sizes_table:\n        for angled_distance in angled_distances:\n            mounting_pcb_distance=angled_distance[0]-shieldthickness\n            pin_pcb_distance=angled_distance[1]-shieldthickness\n            if angled_distance[2]>0:\n                backbox_height=angled_distance[2]\n            else:\n                backbox_height=max(pin_pcb_distance+rmy+pad/2, mounting_pcb_distance+mountingpad/2)+1\n            makeDSubAngled(pins=data[0], isMale=True, HighDensity=HighDensity, rmx=data[7], rmy=rmy, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=mountingdrill, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=mounting_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, can_width=data[4], can_height=can_height_male, backbox_width=data[2], backbox_height=backbox_height, nut_diameter=nut_diameter, nut_length=nut_length, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage, HighDensityOffsetMidLeft=data[8])\n            makeDSubAngled(pins=data[0], isMale=False, HighDensity=HighDensity, rmx=data[7], rmy=rmy, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=mountingdrill, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=mounting_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, can_width=data[4], can_height=can_height_male, backbox_width=data[2], backbox_height=backbox_height, nut_diameter=nut_diameter, nut_length=nut_length, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpage, HighDensityOffsetMidLeft=data[8])\n\n    \n    # unboxed angled\n    webpageunboxed='http://docs-europe.electrocomponents.com/webdocs/1585/0900766b81585df2.pdf'\n    backcan_height_unboxed=4.1\n    pin_pcb_distance=9.4\n    mounting_pcb_distance=0\n    for data in sizes_table:\n        makeDSubAngled(pins=data[0], isMale=True, HighDensity=HighDensity, rmx=data[7], rmy=rmy, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=pin_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, backbox_width=0, backbox_height=0, can_width=data[4], can_height=can_height_male, backcan_width=data[4]+2*shieldthickness, backcan_height=backcan_height_unboxed, nut_diameter=0, nut_length=0, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpageunboxed, HighDensityOffsetMidLeft=data[8])\n        makeDSubAngled(pins=data[0], isMale=False, HighDensity=HighDensity, rmx=data[7], rmy=rmy, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=pin_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, backbox_width=0, backbox_height=0, can_width=data[4], can_height=can_height_female, backcan_width=data[4]+2*shieldthickness, backcan_height=backcan_height_unboxed, nut_diameter=0, nut_length=0, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpageunboxed, HighDensityOffsetMidLeft=data[8])\n        makeDSubAngled(pins=data[0], isMale=True, HighDensity=HighDensity, rmx=data[7], rmy=rmy_unboxed2, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=pin_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, backbox_width=0, backbox_height=0, can_width=data[4], can_height=can_height_male, backcan_width=data[4]+2*shieldthickness, backcan_height=backcan_height_unboxed, nut_diameter=0, nut_length=0, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpageunboxed, HighDensityOffsetMidLeft=data[8])\n        makeDSubAngled(pins=data[0], isMale=False, HighDensity=HighDensity, rmx=data[7], rmy=rmy_unboxed2, pindrill=pindrill, pad=pad, pin_pcb_distance=pin_pcb_distance, mountingdrill=0, mountingpad=mountingpad, mountingdistance=data[1], mounting_pcb_distance=pin_pcb_distance, shield_width=data[2], shield_thickness=shieldthickness, backbox_width=0, backbox_height=0, can_width=data[4], can_height=can_height_female, backcan_width=data[4]+2*shieldthickness, backcan_height=backcan_height_unboxed, nut_diameter=0, nut_length=0, tags_additional=tags_additional, lib_name=lib_name, classname=classname, classname_description=classname_description, webpage=webpageunboxed, HighDensityOffsetMidLeft=data[8])\n            "
  },
  {
    "path": "scripts/Converter_DCDC/Converter_DCDC.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nimport re\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))\n\n# load scripts\nsys.path.append(os.path.join(sys.path[0], \"..\"))\n\nfrom KicadModTree import *\nfrom general.StandardBox import *\n\ndef qfn(args):\n\n    extraffablines = []\n\n    footprint_name = args[\"name\"]\n    description = args[\"description\"]\n    datasheet = args[\"description\"]\n    fptag = args[\"tags\"]\n    SmdTht = args[\"smd_tht\"]\n    at = args[\"at\"]\n    size = args[\"size\"]\n    pins = args[\"pins\"]\n    extratexts = args[\"extratexts\"]\n\n    dir3D = 'Converter_DCDC.3dshapes'\n    f = Footprint(footprint_name)\n\n    file3Dname = \"${KISYS3DMOD}/\" + dir3D + \"/\" + footprint_name + \".wrl\"\n    words = footprint_name.split(\"_\")\n    if words[-1].lower().startswith('handsolder'):\n        words[-1] = ''\n        ff = '_'.join(words)\n        file3Dname = \"${KISYS3DMOD}/\" + dir3D + \"/\" + ff + \".wrl\"\n    f.append(StandardBox(footprint=f, description=description, datasheet=datasheet, at=at, size=size, tags=fptag, SmdTht=SmdTht, extratexts=extratexts, pins=pins, file3Dname=file3Dname ))\n    #\n    #\n    #\n    file_handler = KicadFileHandler(f)\n    file_handler.writeFile(footprint_name + \".kicad_mod\")\n\n\nif __name__ == '__main__':\n\tparser = ModArgparser(qfn)\n\t# the root node of .yml files is parsed as name\n\tparser.add_parameter(\"name\", type=str, required=True)\n\tparser.add_parameter(\"description\", type=str, required=True)\n\tparser.add_parameter(\"datasheet\", type=str, required=True)\n\tparser.add_parameter(\"tags\", type=str, required=True)\n\tparser.add_parameter(\"smd_tht\", type=str, required=False, default='tht')\n\tparser.add_parameter(\"at\", type=list, required=True)\n\tparser.add_parameter(\"size\", type=list, required=False)\n\tparser.add_parameter(\"pins\", type=list, required=True)\n\tparser.add_parameter(\"extratexts\", type=list, required=True)\n\n\n\t# now run our script which handles the whole part of parsing the files\n\tparser.run()\n"
  },
  {
    "path": "scripts/Converter_DCDC/Converter_DCDC.yml",
    "content": "Converter_DCDC_Murata_NCS1SxxxxSC_THT:\n  description: \"Murata NCS1SxxxxSC https://power.murata.com/data/power/ncl/kdc_ncs1.pdf\"\n  datasheet: \"https://power.murata.com/data/power/ncl/kdc_ncs1.pdf\"\n  tags: \"Murata NCS1SxxxxSC\"\n  extratexts: [[-3.0, 0, \"\", \"F.SilkS\", 1.0, 1.0]]\n  at: [-2.27, 3.195]\n  size: [21.87, 8.2]\n  pins: [[\"thtr\", \"1\", 0, 0, 1.70, 2.0, 1.0], [\"thtr\", \"2\", 2.54, 0, 1.70, 2.0, 1.0], [\"thtr\", \"3\", 5.12, 0, 1.70, 2.0, 1.0], [\"thtr\", \"6\", 12.7, 0, 1.70, 2.0, 1.0], [\"thtr\", \"7\", 15.24, 0, 1.70, 2.0, 1.0]]\n"
  },
  {
    "path": "scripts/Converter_DCDC/XP_Power_SF_THT.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom helpers import *\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nseries = \"SF\"\nmanufacturer = 'XP_POWER'\n#Designed to support SF_IA, SF_IH, SF_ITX, SF_ITQ series, and potentially more\n\nfab_pin1_marker_type = 1\npin1_marker_offset = 0.3\npin1_marker_linelen = 1.25\n\ndrill_size = 0.85#0.5 pin diameter, 0.35 pin pitch tolerance\npad_to_pad_clearance = 0.69\npad_copper_y_solder_length = 0.5 #How much copper should be in y direction?\nmin_annular_ring = 0.15\n\nxpitch = 7.62\nypitch = 2.54\n\ndef generate_one_footprint(fpid, rows, datasheet, configuration):\n    pins = []\n    if fpid == \"IAxxxxS\" and rows == \"SIP\" :\n        casetolerance = 0.5\n        casemaxwidth = 6.09\n        casemaxlength = 19.30\n        x_max = 1.40\n        x_min = x_max - (casemaxwidth - casetolerance)\n        y_min = -1.53\n        y_max = y_min + (casemaxlength - casetolerance)\n        pins = [1, 2, 4, 5, 6]\n        xpos = [1, 1, 1, 1, 1]\n        ypos = [1, 2, 4, 5, 6]\n    elif fpid == \"IA48xxS\" and rows == \"SIP\" :\n        casetolerance = 0.5\n        casemaxwidth = 7.20\n        casemaxlength = 19.30\n        x_max = 1.40\n        x_min = x_max - (casemaxwidth - casetolerance)\n        y_min = -1.53\n        y_max = y_min + (casemaxlength - casetolerance)\n        pins = [1, 2, 4, 5, 6]\n        xpos = [1, 1, 1, 1, 1]\n        ypos = [1, 2, 4, 5, 6]\n    elif fpid == \"IAxxxxD\" and rows == \"DIP\" :\n        casetolerance = 0.5\n        casemaxwidth = 10.16\n        casemaxlength = 20.32\n        x_min = -(casemaxwidth-casetolerance-xpitch)/2\n        x_max = x_min + (casemaxwidth - casetolerance)\n        y_min = -(casemaxlength-casetolerance-15.24)/2\n        y_max = y_min + (casemaxlength - casetolerance)\n        pins = [1, 2, 3, 4, 5, 6]\n        xpos = [1, 1, 2, 2, 2, 2]\n        ypos = [1, 7, 1, 4, 6, 7]\n    elif fpid == \"IA48xxD\" and rows == \"DIP\" :\n        casetolerance = 0.5\n        casemaxwidth = 10.16\n        casemaxlength = 20.32\n        x_min = -(casemaxwidth-casetolerance-xpitch)/2\n        x_max = x_min + (casemaxwidth - casetolerance)\n        y_min = -(casemaxlength-casetolerance-15.24)/2\n        y_max = y_min + (casemaxlength - casetolerance)\n        pins = [1, 2, 3, 4, 5, 6]\n        xpos = [1, 1, 2, 2, 2, 2]\n        ypos = [1, 7, 1, 4, 6, 7]\n    elif fpid == \"IHxxxxS\" and rows == \"SIP\" :\n        casetolerance = 0.5\n        casemaxwidth = 7.20\n        casemaxlength = 19.5\n        x_max = 1.25\n        x_min = x_max - (casemaxwidth - casetolerance)\n        y_min = -2.29\n        y_max = y_min + (casemaxlength - casetolerance)\n        pins = [1, 2, 4, 5, 6]\n        xpos = [1, 1, 1, 1, 1]\n        ypos = [1, 2, 4, 5, 6]\n    elif fpid == \"IHxxxxSH\" and rows == \"SIP\" :\n        casetolerance = 0.5\n        casemaxwidth = 7.62\n        casemaxlength = 19.5\n        x_max = 1.25\n        x_min = x_max - (casemaxwidth - casetolerance)\n        y_min = -2.29\n        y_max = y_min + (casemaxlength - casetolerance)\n        pins = [1, 2, 4, 5, 6]\n        xpos = [1, 1, 1, 1, 1]\n        ypos = [1, 2, 5, 6, 7]\n    elif fpid == \"IHxxxxD\" and rows == \"DIP\" :\n        casetolerance = 0.5\n        casemaxwidth = 10.16\n        casemaxlength = 20.32\n        x_min = -(casemaxwidth-casetolerance-xpitch)/2\n        x_max = x_min + (casemaxwidth - casetolerance)\n        y_min = -(casemaxlength-casetolerance-15.24)/2\n        y_max = y_min + (casemaxlength - casetolerance)\n        pins = [1, 2, 3, 4, 5, 6]\n        xpos = [1, 1, 2, 2, 2, 2]\n        ypos = [1, 7, 1, 4, 6, 7]\n    elif fpid == \"IHxxxxDH\" and rows == \"DIP\" :\n        casetolerance = 0.5\n        casemaxwidth = 10.16\n        casemaxlength = 20.32\n        x_min = -(casemaxwidth-casetolerance-xpitch)/2\n        x_max = x_min + (casemaxwidth - casetolerance)\n        y_min = -(casemaxlength-casetolerance-15.24)/2\n        y_max = y_min + (casemaxlength - casetolerance)\n        pins = [1, 2, 3, 4, 5, 6]\n        xpos = [1, 1, 2, 2, 2, 2]\n        ypos = [1, 7, 1, 5, 7, 6]\n    elif fpid == \"ITQxxxxS-H\" and rows == \"SIP\" :\n        casetolerance = 0.5\n        casewidth = 9.20\n        caselength = 21.85\n        x_max = 3.20\n        x_min = x_max - casewidth\n        y_min = -(caselength - 17.78)/2\n        y_max = y_min + caselength\n        pins = [1, 2, 3, 6, 7, 8]\n        xpos = [1, 1, 1, 1, 1, 1]\n        ypos = [1, 2, 3, 6, 7, 8]\n    elif fpid == \"ITxxxxxS\" and rows == \"SIP\" :\n        casetolerance = 0.5\n        casewidth = 9.20\n        caselength = 21.85\n        x_max = 3.20\n        x_min = x_max - casewidth\n        y_min = -(caselength - 17.78)/2\n        y_max = y_min + caselength\n        pins = [1, 2, 3, 6, 7]\n        xpos = [1, 1, 1, 1, 1]\n        ypos = [1, 2, 3, 6, 7]\n    elif fpid == \"ITXxxxxSA\" and rows == \"SIP\" :\n        casetolerance = 0.5\n        casewidth = 9.20\n        caselength = 21.85\n        x_max = 3.20\n        x_min = x_max - casewidth\n        y_min = -(caselength - 17.78)/2\n        y_max = y_min + caselength\n        pins = [1, 2, 6, 7, 8]\n        xpos = [1, 1, 1, 1, 1]\n        ypos = [1, 2, 6, 7, 8]\n\n    silk_x_min = x_min - configuration['silk_fab_offset']\n    silk_x_max = x_max + configuration['silk_fab_offset']\n    silk_y_min = y_min - configuration['silk_fab_offset']\n    silk_y_max = y_max + configuration['silk_fab_offset']\n\n    footprint_name = \"Converter_DCDC_XP_POWER-{:s}_THT\".format(fpid)\n    ser = \"\"\n    if fpid.startswith(\"IA_\"):\n        ser=\"SF_IA\"\n    elif fpid.startswith(\"IH_\"):\n        ser=\"SF_IH\"\n    elif fpid.startswith(\"ITX_\"):\n        ser=\"SF_ITX\"\n    elif fpid.startswith(\"ITQ_\"):\n        ser=\"SF_ITQ\"\n\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"XP_POWER {:s} {:s}, {:s}, ({:s}), generated with kicad-footprint-generator\".format(ser,fpid, rows, datasheet))\n    kicad_mod.setTags(\"XP_POWER {:s} {:s} {:s} DCDC-Converter\".format(ser,fpid,rows))\n\n    # create Silkscreen\n    kicad_mod.append(RectLine(start=[silk_x_min,silk_y_min], end=[silk_x_max,silk_y_max],\n        layer='F.SilkS', width=configuration['silk_line_width']))\n\n    ########################### Pin 1 marker ################################\n    poly_pin1_marker = [\n        {'x':silk_x_min-pin1_marker_offset+pin1_marker_linelen, 'y':silk_y_min-pin1_marker_offset},\n        {'x':silk_x_min-pin1_marker_offset, 'y':silk_y_min-pin1_marker_offset},\n        {'x':silk_x_min-pin1_marker_offset, 'y':silk_y_min-pin1_marker_offset+pin1_marker_linelen}\n    ]\n    kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.SilkS', width=configuration['silk_line_width']))\n    if fab_pin1_marker_type == 1:\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker, layer='F.Fab', width=configuration['fab_line_width']))\n\n    if fab_pin1_marker_type == 2:\n        poly_pin1_marker_type2 = [\n            {'x':-1, 'y':y_min},\n            {'x':0, 'y':y_min+1},\n            {'x':1, 'y':y_min}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=poly_pin1_marker_type2, layer='F.Fab', width=configuration['fab_line_width']))\n\n    ########################## Fab Outline ###############################\n    kicad_mod.append(RectLine(start=[x_min,y_min], end=[x_max,y_max],\n        layer='F.Fab', width=configuration['fab_line_width']))\n    ############################# CrtYd ##################################\n    part_x_min = x_min\n    part_x_max = x_max\n    part_y_min = y_min\n    part_y_max = y_max\n\n    #Note, we use the connector courtyard clearance of 0.5 mm because the unusually large case tolerance of 0.5mm of XP Powers DC DC converters\n    cx1 = roundToBase(part_x_min-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy1 = roundToBase(part_y_min-configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    cx2 = roundToBase(part_x_max+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n    cy2 = roundToBase(part_y_max+configuration['courtyard_offset']['connector'], configuration['courtyard_grid'])\n\n    kicad_mod.append(RectLine(\n        start=[cx1, cy1], end=[cx2, cy2],\n        layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n\n    ############################# Pads ##################################\n    pad_size = [ypitch - pad_to_pad_clearance, drill_size + 2*pad_copper_y_solder_length]\n\n    if pad_size[0] - drill_size < 2*min_annular_ring:\n        pad_size[0] = drill_size + 2*min_annular_ring\n\n    optional_pad_params = {}\n    if configuration['kicad4_compatible']:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_RECT\n    else:\n        optional_pad_params['tht_pad1_shape'] = Pad.SHAPE_ROUNDRECT\n\n    for i in range(len(pins)):\n        pshape = Pad.SHAPE_OVAL\n        if pins[i] == 1:\n            pshape = Pad.SHAPE_RECT\n        kicad_mod.append(Pad(number=pins[i], type=Pad.TYPE_THT, shape=pshape, at=[(xpos[i]-1)*xpitch, (ypos[i]-1)*ypitch], size=pad_size, drill=drill_size, layers=Pad.LAYERS_THT,\n        **optional_pad_params))\n\n    ######################### Text Fields ###############################\n    text_center_y = 1.5\n    body_edge={'left':part_x_min, 'right':part_x_max, 'top':part_y_min, 'bottom':part_y_max}\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':cy1, 'bottom':cy2}, fp_name=footprint_name, text_y_inside_position=text_center_y)\n\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = configuration['lib_name_format_string'].format(series=ser)\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=footprint_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n    print(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='conv_config_KLCv3.yaml')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    generate_one_footprint(\"IA48xxS\"   ,\"SIP\",\"https://www.xppower.com/pdfs/SF_IA.pdf\", configuration)\n    generate_one_footprint(\"IAxxxxS\"   ,\"SIP\",\"https://www.xppower.com/pdfs/SF_IA.pdf\", configuration)\n    generate_one_footprint(\"IA48xxD\"   ,\"DIP\",\"https://www.xppower.com/pdfs/SF_IA.pdf\", configuration)\n    generate_one_footprint(\"IAxxxxD\"   ,\"DIP\",\"https://www.xppower.com/pdfs/SF_IA.pdf\", configuration)\n    generate_one_footprint(\"IHxxxxS\"   ,\"SIP\",\"https://www.xppower.com/pdfs/SF_IH.pdf\", configuration)\n    generate_one_footprint(\"IHxxxxSH\"  ,\"SIP\",\"https://www.xppower.com/pdfs/SF_IH.pdf\", configuration)\n    generate_one_footprint(\"IHxxxxD\"   ,\"DIP\",\"https://www.xppower.com/pdfs/SF_IH.pdf\", configuration)\n    generate_one_footprint(\"IHxxxxDH\"  ,\"DIP\",\"https://www.xppower.com/pdfs/SF_IH.pdf\", configuration)\n    generate_one_footprint(\"ITQxxxxS-H\",\"SIP\",\"https://www.xppower.com/pdfs/SF_ITQ.pdf\", configuration)\n    generate_one_footprint(\"ITxxxxxS\"  ,\"SIP\",\"https://www.xppower.com/pdfs/SF_ITX.pdf https://www.xppower.com/pdfs/SF_ITQ.pdf\", configuration)\n    generate_one_footprint(\"ITXxxxxSA\", \"SIP\",\"https://www.xppower.com/pdfs/SF_ITX.pdf\", configuration)\n\n"
  },
  {
    "path": "scripts/Converter_DCDC/conv_config_KLCv3.yaml",
    "content": "lib_name_format_string_full: 'Converter_DCDC_{man:s}_{series:s}{suffix:s}'\nlib_name_format_string: 'Converter_DCDC'\nlib_name_specific_function_format_string: 'Converter_DCDC_{category:s}'\n"
  },
  {
    "path": "scripts/Crystals_Resonators_SMD/make_crystal_smd.py",
    "content": "#!/usr/bin/env python\r\n\r\nimport sys\r\nimport os\r\nimport math\r\n\r\n# ensure that the kicad-footprint-generator directory is available\r\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\r\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\r\n\r\nfrom KicadModTree import *  # NOQA\r\nfrom drawing_tools import *\r\nfrom footprint_scripts_crystals import *\r\n\r\n\r\n\r\n\r\nif __name__ == '__main__':\r\n    standardtags=\"SMD SMT crystal\"\r\n    standardtagsres=\"SMD SMT ceramic resonator filter\"\r\n    # common settings\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_Abracon_ABM3\", addSizeFootprintName=True, pins=2, pad_sep_x=2.2+1.9, pad_sep_y=0, pad=[1.9,2.4], pack_width=5, pack_height=3.2, pack_bevel=0.2,\r\n                   hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=1,\r\n                   description=\"Abracon Miniature Ceramic Smd Crystal ABM3 http://www.abracon.com/Resonators/abm3.pdf\", tags=standardtags+\"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystal(footprint_name=\"Crystal_SMD_Abracon_ABM3B\", addSizeFootprintName=True, pins=4, pad_sep_x=4, pad_sep_y=2.4, pad=[1.8,1.2], pack_width=5, pack_height=3.2, pack_bevel=0.2,\r\n                   hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=1,\r\n                   description=\"Abracon Miniature Ceramic Smd Crystal ABM3B http://www.abracon.com/Resonators/abm3b.pdf\", tags=standardtags+\"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystal(footprint_name=\"Crystal_SMD_Abracon_ABM3C\", addSizeFootprintName=True, pins=4, pad_sep_x=3.8, pad_sep_y=2.3, pad=[1.6,1.3], pack_width=5, pack_height=3.2, pack_bevel=0.2,\r\n                   hasAdhesive=False, adhesivePos=[0, 0], adhesiveSize=1,\r\n                   description=\"Abracon Miniature Ceramic Smd Crystal ABM3C http://www.abracon.com/Resonators/abm3c.pdf\", tags=standardtags+\"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystal(footprint_name=\"Crystal_SMD_Abracon_ABM8G\", addSizeFootprintName=True, pins=4, pad_sep_x=2.2, pad_sep_y=1.7, pad=[1.4,1.2], pack_width=3.2, pack_height=2.5, pack_bevel=0.2,\r\n                   hasAdhesive=False, adhesivePos=[0, 0], adhesiveSize=1,\r\n                   description=\"Abracon Miniature Ceramic Smd Crystal ABM8G http://www.abracon.com/Resonators/ABM8G.pdf\", tags=standardtags+\"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_SeikoEpson_FA238\", addSizeFootprintName=True, pins=4, pad_sep_x=2.2, pad_sep_y=1.6, pad=[1.4, 1.2], pack_width=3.2,\r\n                   pack_height=2.5, pack_bevel=0.1,\r\n                   description=\"crystal Epson Toyocom FA-238 series http://www.mouser.com/ds/2/137/1721499-465440.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[0.24,0.24,0.24], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_SeikoEpson_FA238V\", addSizeFootprintName=True, pins=4, pad_sep_x=2.4, pad_sep_y=1.9, pad=[1.4, 1.2], pack_width=3.2,\r\n                   pack_height=2.5, pack_bevel=0.1,\r\n                   description=\"crystal Epson Toyocom FA-238 series http://www.mouser.com/ds/2/137/1721499-465440.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_SeikoEpson_TSX3225\", addSizeFootprintName=True, pins=4, pad_sep_x=2.2, pad_sep_y=1.6, pad=[1.4, 1.15], pack_width=3.2,\r\n                   pack_height=2.5, pack_bevel=0.1,\r\n                   description=\"crystal Epson Toyocom TSX-3225 series http://www.mouser.com/ds/2/137/1721499-465440.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[0.24,0.24,0.24], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_FOX_FE\", addSizeFootprintName=True, pins=2, pad_sep_x=6.3, pad_sep_y=0, pad=[2.2, 2.4], pack_width=7.5,\r\n                   pack_height=5, pack_bevel=0,hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=0.8,\r\n                   description=\"crystal Ceramic Resin Sealed SMD http://www.foxonline.com/pdfs/fe.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_0603\", addSizeFootprintName=True, pins=2, pad_sep_x=4.4, pad_sep_y=0,\r\n                   pad=[1.9,2.5], pack_width=6,\r\n                   pack_height=3.5, pack_bevel=0.1, hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=0.8,\r\n                   description=\"SMD Crystal SERIES SMD0603/2 http://www.petermann-technik.de/fileadmin/petermann/pdf/SMD0603-2.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_0603\", addSizeFootprintName=True, pins=4, pad_sep_x=4.4, pad_sep_y=2.4,\r\n                   pad=[1.8, 1.4], pack_width=6, pack_height=3.5, pack_bevel=0.1, hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=0.8,\r\n                   description=\"SMD Crystal SERIES SMD0603/4 http://www.petermann-technik.de/fileadmin/petermann/pdf/SMD0603-4.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_3225\", addSizeFootprintName=True, pins=4, pad_sep_x=2.2, pad_sep_y=1.7,\r\n                   pad=[1.4,1.2], pack_width=3.2, pack_height=2.5, pack_bevel=0, hasAdhesive=False, adhesivePos=[0, 0],\r\n                   adhesiveSize=0.4,\r\n                  description=\"SMD Crystal SERIES SMD3225/4 http://www.txccrystal.com/images/pdf/7m-accuracy.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    \r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_2012\", addSizeFootprintName=True, pins=2, pad_sep_x=1.4, pad_sep_y=0,\r\n                   pad=[0.6,1.1], pack_width=2, pack_height=1.2, pack_bevel=0, hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=0.4,\r\n                   description=\"SMD Crystal 2012/2 http://txccrystal.com/images/pdf/9ht11.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_TXC_9HT11\", addSizeFootprintName=True, pins=2, pad_sep_x=1.4, pad_sep_y=0,\r\n                   pad=[0.6, 1.1], pack_width=2, pack_height=1.2, pack_bevel=0, hasAdhesive=True, adhesivePos=[0, 0],\r\n                   adhesiveSize=0.4,\r\n                   description=\"SMD Crystal TXC 9HT11 http://txccrystal.com/images/pdf/9ht11.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_TXC_7M\", addSizeFootprintName=True, pins=4, pad_sep_x=2.2, pad_sep_y=1.7,\r\n                   pad=[1.4,1.2], pack_width=3.2, pack_height=2.5, pack_bevel=0, hasAdhesive=False, adhesivePos=[0, 0],\r\n                   adhesiveSize=0.4,\r\n                   description=\"SMD Crystal TXC 7M http://www.txccrystal.com/images/pdf/7m-accuracy.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystal(footprint_name=\"Crystal_SMD_2016\", addSizeFootprintName=True, pins=4, pad_sep_x=1.4, pad_sep_y=1.1,\r\n                   pad=[0.9,0.8], pack_width=2, pack_height=1.6, pack_bevel=0.1, hasAdhesive=False, adhesivePos=[0, 0],\r\n                   adhesiveSize=0.8,\r\n                   description=\"SMD Crystal SERIES SMD2016/4 http://www.q-crystal.com/upload/5/2015552223166229.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystal(footprint_name=\"Crystal_SMD_2520\", addSizeFootprintName=True, pins=4, pad_sep_x=1.75, pad_sep_y=1.4,\r\n                   pad=[1.15,1], pack_width=2.5, pack_height=2, pack_bevel=0.1, hasAdhesive=False, adhesivePos=[0, 0],\r\n                   adhesiveSize=0.8,\r\n                   description=\"SMD Crystal SERIES SMD2520/4 http://www.newxtal.com/UploadFiles/Images/2012-11-12-09-29-09-776.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystal(footprint_name=\"Crystal_SMD_2520\", addSizeFootprintName=True, pins=4, pad_sep_x=1.75, pad_sep_y=1.4,\r\n                   pad=[1.15, 1], pack_width=2.5, pack_height=2, pack_bevel=0.1, hasAdhesive=False, adhesivePos=[0, 0],\r\n                   adhesiveSize=0.8,\r\n                   description=\"SMD Crystal SERIES SMD2520/4 http://www.newxtal.com/UploadFiles/Images/2012-11-12-09-29-09-776.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystal(footprint_name=\"Crystal_SMD_5032\", addSizeFootprintName=True, pins=4, pad_sep_x=3.3, pad_sep_y=2.0,\r\n                   pad=[1.6, 1.3], pack_width=5, pack_height=3.2, pack_bevel=0.2, hasAdhesive=False, adhesivePos=[0, 0],\r\n                   adhesiveSize=0.8,\r\n                   description=\"SMD Crystal SERIES SMD2520/4 http://www.icbase.com/File/PDF/HKC/HKC00061008.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_5032\", addSizeFootprintName=True, pins=2, pad_sep_x=3.7, pad_sep_y=0,\r\n                   pad=[2, 2.4], pack_width=5, pack_height=3.2, pack_bevel=0.2, hasAdhesive=True, adhesivePos=[0, 0],\r\n                   adhesiveSize=0.8,\r\n                   description=\"SMD Crystal SERIES SMD2520/2 http://www.icbase.com/File/PDF/HKC/HKC00061008.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeSMDCrystal(footprint_name=\"Crystal_SMD_7050\", addSizeFootprintName=True, pins=4, pad_sep_x=5.9, pad_sep_y=2.7,\r\n                   pad=[2.1,1.7], pack_width=7, pack_height=5, pack_bevel=0.2, hasAdhesive=False, adhesivePos=[0, 0],\r\n                   adhesiveSize=0.8,\r\n                   description=\"SMD Crystal SERIES SMD7050/4 https://www.foxonline.com/pdfs/FQ7050.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_7050\", addSizeFootprintName=True, pins=2, pad_sep_x=5.2,\r\n                   pad_sep_y=0,\r\n                   pad=[2.8, 3], pack_width=7, pack_height=5, pack_bevel=0.2, hasAdhesive=True, adhesivePos=[0, 0],\r\n                   adhesiveSize=0.8,\r\n                   description=\"SMD Crystal SERIES SMD7050/4 https://www.foxonline.com/pdfs/FQ7050.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystal(footprint_name=\"Crystal_SMD_FOX_FQ7050\", addSizeFootprintName=True, pins=4, pad_sep_x=5.9,\r\n                   pad_sep_y=2.7,\r\n                   pad=[2.1, 1.7], pack_width=7, pack_height=5, pack_bevel=0.2, hasAdhesive=False, adhesivePos=[0, 0],\r\n                   adhesiveSize=0.8,\r\n                   description=\"FOX SMD Crystal SERIES SMD7050/4 https://www.foxonline.com/pdfs/FQ7050.pdf\",\r\n                   tags=standardtags + \"\",\r\n                   lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_FOX_FQ7050\", addSizeFootprintName=True, pins=2, pad_sep_x=5.2,\r\n                          pad_sep_y=0,\r\n                          pad=[2.8, 3], pack_width=7, pack_height=5, pack_bevel=0.2, hasAdhesive=True, adhesivePos=[0, 0],\r\n                          adhesiveSize=0.8,\r\n                          description=\"FOX SMD Crystal SERIES SMD7050/4 https://www.foxonline.com/pdfs/FQ7050.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_G8\", addSizeFootprintName=True, pins=2, pad_sep_x=2.5,\r\n                      pad_sep_y=0,\r\n                      pad=[1,1.8], pack_width=3.2, pack_height=1.5, pack_bevel=0, hasAdhesive=True, adhesivePos=[0, 0],\r\n                      adhesiveSize=0.5,\r\n                      description=\"SMD Crystal G8\",\r\n                      tags=standardtags + \"\",\r\n                      lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_HC49-SD\", addSizeFootprintName=False, pins=2, style=\"hc49\",\r\n                          pad_sep_x=8.5, pad_sep_y=0,\r\n                          pad=[4.5,2], pack_width=11.4, pack_height=4.7, pack_bevel=0, hasAdhesive=False, adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal HC-49-SD http://cdn-reichelt.de/documents/datenblatt/B400/xxx-HC49-SMD.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_SeikoEpson_MC156\", addSizeFootprintName=True, pins=4, style=\"dip\",\r\n                          pad_sep_x=5.08, pad_sep_y=2.5,\r\n                          pad=[1.2,1.5], pack_width=7.1, pack_height=2.5, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal Seiko Epson MC-156 https://support.epson.biz/td/api/doc_check.php?dl=brief_MC-156_en.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_SeikoEpson_MC146\", addSizeFootprintName=True, pins=4,\r\n                          style=\"rect\",\r\n                          pad_sep_x=6.3, pad_sep_y=0.9,\r\n                          pad=[1.2,0.6], pack_width=6.7, pack_height=1.5, pack_bevel=0.4, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal Seiko Epson MC-146 https://support.epson.biz/td/api/doc_check.php?dl=brief_MC-156_en.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_SeikoEpson_MC306\", addSizeFootprintName=True, pins=4,\r\n                          style=\"dip\",\r\n                          pad_sep_x=5.5, pad_sep_y=3.2,\r\n                          pad=[1.3,1.9], pack_width=8, pack_height=3.2, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal Seiko Epson MC-306 https://support.epson.biz/td/api/doc_check.php?dl=brief_MC-306_en.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_SeikoEpson_MC405\", addSizeFootprintName=True, pins=2,\r\n                          style=\"rect\",\r\n                          pad_sep_x=8, pad_sep_y=0,\r\n                          pad=[4.1,4.1], pack_width=9.6, pack_height=4.06, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal Seiko Epson MC-405 https://support.epson.biz/td/api/doc_check.php?dl=brief_MC-306_en.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_SeikoEpson_MC406\", addSizeFootprintName=True, pins=4,\r\n                          style=\"rect\",\r\n                          pad_sep_x=8, pad_sep_y=2.32,\r\n                          pad=[4.1, 1.52], pack_width=9.6, pack_height=4.06, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal Seiko Epson MC-406 https://support.epson.biz/td/api/doc_check.php?dl=brief_MC-306_en.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_SeikoEpson_MA505\", addSizeFootprintName=True, pins=2,\r\n                          style=\"rect\",\r\n                          pad_sep_x=11.1, pad_sep_y=0,\r\n                          pad=[4.1, 5.6], pack_width=12.7, pack_height=5.08, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal Seiko Epson MC-505 http://media.digikey.com/pdf/Data%20Sheets/Epson%20PDFs/MA-505,506.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_SeikoEpson_MA506\", addSizeFootprintName=True, pins=4,\r\n                          style=\"rect\",\r\n                          pad_sep_x=11.1, pad_sep_y=3.55,\r\n                          pad=[4.1, 2.05], pack_width=12.7, pack_height=5.08, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal Seiko Epson MC-506 http://media.digikey.com/pdf/Data%20Sheets/Epson%20PDFs/MA-505,506.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_SeikoEpson_MA406\", addSizeFootprintName=True, pins=4,\r\n                          style=\"dip\",\r\n                          pad_sep_x=9.6, pad_sep_y=3.6,\r\n                          pad=[1.8,1.9], pack_width=11.7, pack_height=4, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal Seiko Epson MC-506 http://media.digikey.com/pdf/Data%20Sheets/Epson%20PDFs/MA-505,506.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_EuroQuartz_MT\", addSizeFootprintName=True, pins=4,\r\n                          style=\"rect\",\r\n                          pad_sep_x=2.2, pad_sep_y=1.8,\r\n                          pad=[1.3,1], pack_width=3.2, pack_height=2.5, pack_bevel=0.1, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal EuroQuartz MT series http://cdn-reichelt.de/documents/datenblatt/B400/MT.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_EuroQuartz_X22\", addSizeFootprintName=True, pins=4,\r\n                      style=\"rect\",\r\n                      pad_sep_x=1.6, pad_sep_y=1.2,\r\n                      pad=[1.2,1], pack_width=2.5, pack_height=2, pack_bevel=0.1, hasAdhesive=False,\r\n                      adhesivePos=[0, 0],\r\n                      adhesiveSize=0.5,\r\n                      description=\"SMD Crystal EuroQuartz X22 series http://cdn-reichelt.de/documents/datenblatt/B400/DS_X22.pdf\",\r\n                      tags=standardtags + \"\",\r\n                      lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_EuroQuartz_MJ\", addSizeFootprintName=True, pins=4,\r\n                          style=\"rect\",\r\n                          pad_sep_x=3.7, pad_sep_y=2.3,\r\n                          pad=[1.9, 1.1], pack_width=5, pack_height=3.2, pack_bevel=0.1, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal EuroQuartz MJ series http://cdn-reichelt.de/documents/datenblatt/B400/MJ.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_EuroQuartz_MQ\", addSizeFootprintName=True, pins=4,\r\n                          style=\"rect\",\r\n                          pad_sep_x=6.3, pad_sep_y=2.5,\r\n                          pad=[2.2,1.4], pack_width=7, pack_height=5, pack_bevel=0.1, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal EuroQuartz MQ series http://cdn-reichelt.de/documents/datenblatt/B400/MQ.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_EuroQuartz_MQ2\", addSizeFootprintName=True, pins=2,\r\n                          style=\"rect\",\r\n                          pad_sep_x=6.3, pad_sep_y=0,\r\n                          pad=[2.2,2.4], pack_width=7, pack_height=5, pack_bevel=0.1, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal EuroQuartz MQ2 series http://cdn-reichelt.de/documents/datenblatt/B400/MQ.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_EuroQuartz_EQ161\", addSizeFootprintName=True, pins=2,\r\n                          style=\"rect\",\r\n                          pad_sep_x=2.5, pad_sep_y=0,\r\n                          pad=[1,1.8], pack_width=3.2, pack_height=1.5, pack_bevel=0.1, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal EuroQuartz EQ161 series http://cdn-reichelt.de/documents/datenblatt/B400/PG32768C.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_MicroCrystal_CC1V-T1A\", addSizeFootprintName=True, pins=2,\r\n                          style=\"rect\",\r\n                          pad_sep_x=6.3, pad_sep_y=0,\r\n                          pad=[2.3, 4.2], pack_width=8, pack_height=3.7, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal MicroCrystal CC1V-T1A series http://www.microcrystal.com/images/_Product-Documentation/01_TF_ceramic_Packages/01_Datasheet/CC1V-T1A.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_MicroCrystal_CC4V-T1A\", addSizeFootprintName=True, pins=2,\r\n                          style=\"rect\",\r\n                          pad_sep_x=4.2, pad_sep_y=0,\r\n                          pad=[1.3, 2.2], pack_width=5, pack_height=1.9, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal MicroCrystal CC4V-T1A series http://cdn-reichelt.de/documents/datenblatt/B400/CC4V-T1A.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_MicroCrystal_CC5V-T1A\", addSizeFootprintName=True, pins=2,\r\n                          style=\"rect\",\r\n                          pad_sep_x=3.4, pad_sep_y=0,\r\n                          pad=[1.1, 1.9], pack_width=4.1, pack_height=1.5, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal MicroCrystal CC5V-T1A series http://cdn-reichelt.de/documents/datenblatt/B400/CC5V-T1A.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_MicroCrystal_CC7V-T1A\", addSizeFootprintName=True, pins=2,\r\n                          style=\"rect\",\r\n                          pad_sep_x=2.5, pad_sep_y=0,\r\n                          pad=[1,1.8], pack_width=3.2, pack_height=1.5, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal MicroCrystal CC7V-T1A/CM7V-T1A series http://www.microcrystal.com/images/_Product-Documentation/01_TF_ceramic_Packages/01_Datasheet/CC1V-T1A.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_MicroCrystal_CC8V-T1A\", addSizeFootprintName=True, pins=2,\r\n                          style=\"rect\",\r\n                          pad_sep_x=1.5, pad_sep_y=0,\r\n                          pad=[0.8,1.5], pack_width=2, pack_height=1.2, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal MicroCrystal CC8V-T1A/CM8V-T1A series http://www.microcrystal.com/images/_Product-Documentation/01_TF_ceramic_Packages/01_Datasheet/CC8V-T1A.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Crystal_SMD_MicroCrystal_CM9V-T1A\", addSizeFootprintName=True, pins=2,\r\n                          style=\"rect\",\r\n                          pad_sep_x=1.2, pad_sep_y=0,\r\n                          pad=[0.6,1.2], pack_width=1.6, pack_height=1.0, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal MicroCrystal CM9V-T1A series http://www.microcrystal.com/images/_Product-Documentation/01_TF_ceramic_Packages/01_Datasheet/CM9V-T1A.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeCrystal(footprint_name=\"Crystal_SMD_MicroCrystal_MS3V-T1R\",\r\n                rm=1, pad_size=[1.1,0.6], ddrill=1, pack_width=5.2, pack_height=1.4, pack_rm=0.7, pack_offset=1.2,\r\n                package_pad=True, package_pad_offset=4.4, package_pad_size=[2.4,1.5],\r\n                package_pad_add_holes=False, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                style=\"flat\", pad_style=\"smd\",\r\n                description=\"SMD Watch Crystal MicroCrystal MS3V-T1R 5.2mm length 1.4mm diameter http://www.microcrystal.com/images/_Product-Documentation/03_TF_metal_Packages/01_Datasheet/MS3V-T1R.pdf\",\r\n                tags=[\"MS3V-T1R\"], lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeCrystal(footprint_name=\"Crystal_SMD_MicroCrystal_MS1V-T1K\",\r\n                rm=2.54, pad_size=[1.6,1], ddrill=1, pack_width=6.1, pack_height=2, pack_rm=1, pack_offset=1.6,\r\n                package_pad=True, package_pad_offset=5.3, package_pad_size=[2.5, 3],\r\n                package_pad_add_holes=False, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                style=\"flat\", pad_style=\"smd\",\r\n                description=\"SMD Watch Crystal MicroCrystal MS1V-T1K 6.1mm length 2.0mm diameter http://www.microcrystal.com/images/_Product-Documentation/03_TF_metal_Packages/01_Datasheet/MS1V-T1K.pdf\",\r\n                tags=[\"MS1V-T1K\"], lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeCrystal(footprint_name=\"Crystal_SMD_FrontierElectronics_FM206\",\r\n                rm=2.54, pad_size=[1.6,1], ddrill=1, pack_width=6.0, pack_height=1.9, pack_rm=1, pack_offset=1.6,\r\n                package_pad=True, package_pad_offset=5.3, package_pad_size=[2.5, 3],\r\n                package_pad_add_holes=False, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                style=\"flat\", pad_style=\"smd\",\r\n                description=\"SMD Watch Crystal FrontierElectronics FM206 6.0mm length 1.9mm diameter http://www.chinafronter.com/wp-content/uploads/2013/12/FM206.pdf\",\r\n                tags=[\"FM206\"], lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Resonator_SMD\", addSizeFootprintName=True, pins=3,\r\n                          style=\"rect\",\r\n                          pad_sep_x=2.5, pad_sep_y=0,\r\n                          pad=[1.4, 3.8], pack_width=7.2, pack_height=3, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Resomator/Filter 7.2x3.0mm, Murata CSTCC8M00G53-R0; 8MHz resonator, SMD, Farnell (Element 14) #1170435, http://www.farnell.com/datasheets/19296.pdf?_ga=1.247244932.122297557.1475167906\",\r\n                          tags=standardtagsres + \" filter\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Resonator_SMD_Murata_SFECV\", addSizeFootprintName=True, pins=3,\r\n                          style=\"rect\",\r\n                          pad_sep_x=2.85, pad_sep_y=0,\r\n                          pad=[1.2, 4], pack_width=6.9, pack_height=2.9, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Resomator/Filter Murata SFECV, http://cdn-reichelt.de/documents/datenblatt/B400/SFECV-107.pdf\",\r\n                          tags=standardtagsres + \" filter\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Resonator_SMD_Murata_SFSKA\", addSizeFootprintName=True, pins=3,\r\n                          style=\"rect\",\r\n                          pad_sep_x=2.5, pad_sep_y=0,\r\n                          pad=[1, 4.8], pack_width=7.9, pack_height=3.8, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Resomator/Filter Murata SFSKA, http://cdn-reichelt.de/documents/datenblatt/B400/SFECV-107.pdf\",\r\n                          tags=standardtagsres + \" filter\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Resonator_SMD_Murata_TPSKA\", addSizeFootprintName=True, pins=3,\r\n                          style=\"rect\",\r\n                          pad_sep_x=2.5, pad_sep_y=0,\r\n                          pad=[1, 4.8], pack_width=7.9, pack_height=3.8, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Resomator/Filter Murata TPSKA, http://cdn-reichelt.de/documents/datenblatt/B400/SFECV-107.pdf\",\r\n                          tags=standardtagsres + \" filter\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Resonator_SMD_Murata_CDSCB\", addSizeFootprintName=True, pins=2,\r\n                              style=\"rect\",\r\n                              pad_sep_x=3, pad_sep_y=0,\r\n                              pad=[1, 2.6], pack_width=4.5, pack_height=2, pack_bevel=0, hasAdhesive=False,\r\n                              adhesivePos=[0, 0],\r\n                              adhesiveSize=0.5,\r\n                              description=\"SMD Resomator/Filter Murata CDSCB, http://cdn-reichelt.de/documents/datenblatt/B400/SFECV-107.pdf\",\r\n                              tags=standardtagsres + \" filter\",\r\n                              lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "scripts/Crystals_Resonators_THT/make_crystal.py",
    "content": "#!/usr/bin/env python\r\n\r\nimport sys\r\nimport os\r\nimport math\r\n\r\n# ensure that the kicad-footprint-generator directory is available\r\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\r\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\r\n\r\nfrom KicadModTree import *  # NOQA\r\nfrom drawing_tools import *\r\nfrom footprint_scripts_crystals import *\r\n\r\n\r\nif __name__ == '__main__':\r\n    standardtags=\"THT crystal\"\r\n    standardtagsres=\"THT ceramic resonator filter\"\r\n    \r\n    script3dhc49=\"crystal_hc49_2pin.py\"\r\n    with open(script3dhc49, \"w\") as myfile:\r\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\r\n    script3dhc493p=\"crystal_hc49_3pin.py\"\r\n    with open(script3dhc493p, \"w\") as myfile:\r\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\r\n    script3dres3=\"resonator_3pin.py\"\r\n    with open(script3dres3, \"w\") as myfile:\r\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\r\n    script3dres2=\"resonator_2pin.py\"\r\n    with open(script3dres2, \"w\") as myfile:\r\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\r\n    script3dhc49h=\"crystal_hc49_2pin_hor.py\"\r\n    with open(script3dhc49h, \"w\") as myfile:\r\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\r\n\r\n    \r\n    # common settings\r\n    makeCrystalAll(footprint_name=\"Crystal_AT310_d3.0mm_l10.0mm_Horizontal\",\r\n                rm=2.54, pad_size=1, ddrill=0.5, pack_width=10.5, pack_height=3, pack_rm=1.2, pack_offset=3,\r\n                package_pad=True, package_pad_offset=3.5, package_pad_size=[10.5,3.2],\r\n                package_pad_add_holes=True, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                style=\"flat\", description=\"Crystal THT AT310 10.0mm-10.5mm length 3.0mm diameter\", lib_name=\"Crystals\", tags=[\"AT310\"],\r\n                offset3d=[1.27/25.4, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeCrystalRoundVert(footprint_name=\"Crystal_AT310_d3.0mm_l10.0mm_Vertical\",\r\n                rm=2.54, pad_size=1, ddrill=0.5, pack_diameter=3,\r\n                description=\"Crystal THT AT310 10.0mm-10.5mm length 3.0mm diameter\", lib_name=\"Crystals\", tags=[\"AT310\"],\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalAll(footprint_name=\"Crystal_C26-LF_d2.1mm_l6.5mm_Horizontal\",\r\n                rm=1.9, pad_size=1, ddrill=0.5, pack_width=6.5, pack_height=2.06, pack_rm=0.7, pack_offset=2,\r\n                package_pad=True, package_pad_offset=2.5, package_pad_size=[6.5,2.2],\r\n                package_pad_add_holes=True, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                style=\"flat\", description=\"Crystal THT C26-LF 6.5mm length 2.06mm diameter\", tags=[\"C26-LF\"], lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalRoundVert(footprint_name=\"Crystal_C26-LF_d2.1mm_l6.5mm_Vertical\",\r\n                rm=1.9, pad_size=1, ddrill=0.5, pack_diameter=2.06,\r\n                description=\"Crystal THT C26-LF 6.5mm length 2.06mm diameter\", tags=[\"C26-LF\"], lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalAll(footprint_name=\"Crystal_C38-LF_d3.0mm_l8.0mm_Horizontal\",\r\n                rm=1.9, pad_size=1, ddrill=0.5, pack_width=8, pack_height=3, pack_rm=1.09, pack_offset=2.5,\r\n                package_pad=True, package_pad_offset=3, package_pad_size=[8,3],\r\n                package_pad_add_holes=True, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                style=\"flat\", description=\"Crystal THT C38-LF 8.0mm length 3.0mm diameter\", tags=[\"C38-LF\"],\r\n                lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalRoundVert(footprint_name=\"Crystal_C38-LF_d3.0mm_l8.0mm_Vertical\",\r\n                rm=1.9, pad_size=1, ddrill=0.5, pack_diameter=3,\r\n                description=\"Crystal THT C38-LF 8.0mm length 3.0mm diameter\", tags=[\"C38-LF\"],\r\n                lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalRoundVert(footprint_name=\"Crystal_Round_d3.0mm_Vertical\",\r\n                rm=1.9, pad_size=1, ddrill=0.5, pack_diameter=3,\r\n                description=\"Crystal THT C38-LF 8.0mm length 3.0mm diameter\", tags=[\"C38-LF\"],\r\n                lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalAll(footprint_name=\"Crystal_DS26_d2.0mm_l6.0mm_Horizontal\",\r\n                rm=1.9, pad_size=1, ddrill=0.5, pack_width=6, pack_height=2, pack_rm=0.7, pack_offset=2,\r\n                package_pad=True, package_pad_offset=2.5, package_pad_size=[6,2.5],\r\n                package_pad_add_holes=True, package_pad_drill_size=[1, 1], package_pad_ddrill=0.5,\r\n                style=\"flat\", description=\"Crystal THT DS26 6.0mm length 2.0mm diameter http://www.microcrystal.com/images/_Product-Documentation/03_TF_metal_Packages/01_Datasheet/DS-Series.pdf\",\r\n                tags=[\"DS26\"],lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalRoundVert(footprint_name=\"Crystal_DS26_d2.0mm_l6.0mm_Vertical\",\r\n                rm=1.9, pad_size=1, ddrill=0.5, pack_diameter=2,\r\n                description=\"Crystal THT DS26 6.0mm length 2.0mm diameter http://www.microcrystal.com/images/_Product-Documentation/03_TF_metal_Packages/01_Datasheet/DS-Series.pdf\",\r\n                tags=[\"DS26\"],lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalRoundVert(footprint_name=\"Crystal_Round_d2.0mm_Vertical\",\r\n                rm=1.9, pad_size=1, ddrill=0.5, pack_diameter=2,\r\n                description=\"Crystal THT DS26 6.0mm length 2.0mm diameter http://www.microcrystal.com/images/_Product-Documentation/03_TF_metal_Packages/01_Datasheet/DS-Series.pdf\",\r\n                tags=[\"DS26\"],lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalAll(footprint_name=\"Crystal_DS15_d1.5mm_l5.0mm_Horizontal\",\r\n                rm=1.7, pad_size=1, ddrill=0.5, pack_width=5, pack_height=1.5, pack_rm=0.5, pack_offset=1.5,\r\n                package_pad=True, package_pad_offset=2, package_pad_size=[5,2],\r\n                package_pad_add_holes=True, package_pad_drill_size=[1, 1], package_pad_ddrill=0.5,\r\n                style=\"flat\",\r\n                description=\"Crystal THT DS15 5.0mm length 1.5mm diameter http://www.microcrystal.com/images/_Product-Documentation/03_TF_metal_Packages/01_Datasheet/DS-Series.pdf\",\r\n                tags=[\"DS15\"], lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalRoundVert(footprint_name=\"Crystal_DS15_d1.5mm_l5.0mm_Vertical\",\r\n                rm=1.7, pad_size=1, ddrill=0.5, pack_diameter=1.5,\r\n                description=\"Crystal THT DS15 5.0mm length 1.5mm diameter http://www.microcrystal.com/images/_Product-Documentation/03_TF_metal_Packages/01_Datasheet/DS-Series.pdf\",\r\n                tags=[\"DS15\"], lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalRoundVert(footprint_name=\"Crystal_Round_d1.5mm_Vertical\",\r\n                rm=1.7, pad_size=1, ddrill=0.5, pack_diameter=1.5,\r\n                description=\"Crystal THT DS15 5.0mm length 1.5mm diameter http://www.microcrystal.com/images/_Product-Documentation/03_TF_metal_Packages/01_Datasheet/DS-Series.pdf\",\r\n                tags=[\"DS15\"], lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalAll(footprint_name=\"Crystal_DS10_d1.0mm_l4.3mm_Horizontal\",\r\n                rm=1.5, pad_size=1, ddrill=0.5, pack_width=4.3, pack_height=1, pack_rm=0.3, pack_offset=1.5,\r\n                package_pad=True, package_pad_offset=2, package_pad_size=[4.3, 1.5],\r\n                package_pad_add_holes=True, package_pad_drill_size=[1, 1], package_pad_ddrill=0.5,\r\n                style=\"flat\",\r\n                description=\"Crystal THT DS10 4.3mm length 1.0mm diameter http://www.microcrystal.com/images/_Product-Documentation/03_TF_metal_Packages/01_Datasheet/DS-Series.pdf\",\r\n                tags=[\"DS10\"], lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalRoundVert(footprint_name=\"Crystal_DS10_d1.0mm_l4.3mm_Vertical\",\r\n                rm=1.5, pad_size=1, ddrill=0.5, pack_diameter=1,\r\n                description=\"Crystal THT DS10 4.3mm length 1.0mm diameter http://www.microcrystal.com/images/_Product-Documentation/03_TF_metal_Packages/01_Datasheet/DS-Series.pdf\",\r\n                tags=[\"DS10\"], lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalRoundVert(footprint_name=\"Crystal_Round_d1.0mm_Vertical\",\r\n                rm=1.5, pad_size=1, ddrill=0.5, pack_diameter=1,\r\n                description=\"Crystal THT DS10 1.0mm diameter http://www.microcrystal.com/images/_Product-Documentation/03_TF_metal_Packages/01_Datasheet/DS-Series.pdf\",\r\n                tags=[\"DS10\"], lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54,1/2.54,1/2.54], rotate3d=[0, 0, 0])\r\n    makeCrystalAll(footprint_name=\"Crystal_HC49-U_Horizontal\",\r\n                rm=4.9, pad_size=1.5, ddrill=0.8, pack_width=13.0, pack_height=10.9, pack_rm=4.9, pack_offset=2,\r\n                package_pad=True, package_pad_offset=2.5, package_pad_size=[13.5, 11],\r\n                package_pad_add_holes=True, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                style=\"hc49\",\r\n                description=\"Crystal THT HC-49/U http://5hertz.com/pdfs/04404_D.pdf\",\r\n                lib_name=\"Crystals\",\r\n                offset3d=[0, 0, 0], scale3d=[1/2.54, 1/2.54, 1/2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dhc49h, height3d=4.65, iheight3d=4)\r\n    makeCrystalHC49Vert(footprint_name = \"Crystal_HC49-U_Vertical\", pins=2,\r\n                        rm=4.88, pad_size=1.5, ddrill=0.8, pack_width=10.9, pack_height=4.65,\r\n                        innerpack_width=10, innerpack_height=4,\r\n                        tags=standardtags+\"HC-49/U\", description=\"Crystal THT HC-49/U http://5hertz.com/pdfs/04404_D.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1/2.54, 1/2.54, 1/2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dhc49, height3d=13)\r\n    makeCrystalHC49Vert(footprint_name=\"Crystal_HC49-U-3pin_Vertical\", pins=3,\r\n                        rm=4.88, pad_size=1.5, ddrill=0.8, pack_width=10.9, pack_height=4.65,\r\n                        innerpack_width=10, innerpack_height=4,\r\n                        tags=standardtags+\"HC-49/U\", description=\"Crystal THT HC-49/U, 3pin-version, http://www.raltron.com/products/pdfspecs/crystal_hc_49_45_51.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dhc493p, height3d=13)\r\n    makeCrystalHC49Vert(footprint_name = \"Crystal_HC49-4H_Vertical\", pins=2,\r\n                        rm=4.88, pad_size=1.5, ddrill=0.8, pack_width=11.05, pack_height=4.65,\r\n                        innerpack_width=10, innerpack_height=4,\r\n                        tags=standardtags+\"HC-49-4H\", description=\"Crystal THT HC-49-4H http://5hertz.com/pdfs/04404_D.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1/2.54, 1/2.54, 1/2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dhc49, height3d=4)\r\n    makeCrystalAll(footprint_name=\"Crystal_HC18-U_Horizontal\",\r\n                rm=4.9, pad_size=1.5, ddrill=0.8, pack_width=13.0, pack_height=10.9, pack_rm=4.9, pack_offset=2,\r\n                package_pad=True, package_pad_offset=2.5, package_pad_size=[13.5, 11],\r\n                package_pad_add_holes=True, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                style=\"hc49\",\r\n                description=\"Crystal THT HC-18/U http://5hertz.com/pdfs/04404_D.pdf\",\r\n                lib_name=\"Crystals\",\r\n                   offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                   script3d=script3dhc49h, height3d=4.65, iheight3d=4)\r\n    makeCrystalHC49Vert(footprint_name=\"Crystal_HC18-U_Vertical\", pins=2,\r\n                        rm=4.9, pad_size=1.5, ddrill=0.8, pack_width=10.9, pack_height=4.65,\r\n                        innerpack_width=10, innerpack_height=4,\r\n                        tags=standardtags+\"HC-18/U\",\r\n                        description=\"Crystal THT HC-18/U, http://5hertz.com/pdfs/04404_D.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dhc49, height3d=13)\r\n    makeCrystalAll(footprint_name=\"Crystal_HC33-U_Horizontal\",\r\n                rm=12.34, pad_size=2.7, ddrill=1.7, pack_width=19.7, pack_height=19.23, pack_rm=12.34, pack_offset=2.5,\r\n                package_pad=True, package_pad_offset=2.5, package_pad_size=[20.5, 20],\r\n                package_pad_add_holes=True, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                style=\"hc49\",\r\n                description=\"Crystal THT HC-33/U http://pdi.bentech-taiwan.com/PDI/GEN20SPEV20HC3320U.pdf\",\r\n                lib_name=\"Crystals\",\r\n                   offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                   script3d=script3dhc49h, height3d=8.94, iheight3d=8.05)\r\n    makeCrystalHC49Vert(footprint_name=\"Crystal_HC33-U_Vertical\", pins=2,\r\n                        rm=12.34, pad_size=2.7, ddrill=1.7, pack_width=19.23, pack_height=8.94,\r\n                        innerpack_width=18.42, innerpack_height=8.05,\r\n                        tags=standardtags+\"HC-33/U\",\r\n                        description=\"Crystal THT HC-33/U, http://pdi.bentech-taiwan.com/PDI/GEN20SPEV20HC3320U.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dhc49, height3d=19.7)\r\n    makeCrystalAll(footprint_name=\"Crystal_HC50_Horizontal\",\r\n                   rm=4.9, pad_size=2.3, ddrill=1.5, pack_width=13.36, pack_height=11.05, pack_rm=4.9, pack_offset=2.5,\r\n                   package_pad=True, package_pad_offset=2.5, package_pad_size=[14, 11.5],\r\n                   package_pad_add_holes=True, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                   style=\"hc49\",\r\n                   description=\"Crystal THT HC-50 http://www.crovencrystals.com/croven_pdf/HC-50_Crystal_Holder_Rev_00.pdf\",\r\n                   lib_name=\"Crystals\",\r\n                   offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                   script3d=script3dhc49h, height3d=4.65, iheight3d=3.8)\r\n    makeCrystalHC49Vert(footprint_name=\"Crystal_HC50_Vertical\", pins=2,\r\n                        rm=4.9, pad_size=2.3, ddrill=1.5, pack_width=11.05, pack_height=4.65,\r\n                        innerpack_width=10.2, innerpack_height=3.8,\r\n                        tags=standardtags+\"HC-50\",\r\n                        description=\"Crystal THT HC-50, http://www.crovencrystals.com/croven_pdf/HC-50_Crystal_Holder_Rev_00.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dhc49, height3d=13.36)\r\n    makeCrystalAll(footprint_name=\"Crystal_HC51_Horizontal\",\r\n                   rm=12.35, pad_size=2.3, ddrill=1.2, pack_width=19.7, pack_height=19.3, pack_rm=12.35, pack_offset=2.5,\r\n                   package_pad=True, package_pad_offset=2.5, package_pad_size=[20.5, 20],\r\n                   package_pad_add_holes=True, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                   style=\"hc49\",\r\n                   description=\"Crystal THT HC-51 http://www.crovencrystals.com/croven_pdf/HC-51_Crystal_Holder_Rev_00.pdf\",\r\n                   lib_name=\"Crystals\",\r\n                   offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                   script3d=script3dhc49h, height3d=8.9, iheight3d=7.6)\r\n    makeCrystalHC49Vert(footprint_name=\"Crystal_HC51-U_Vertical\", pins=2,\r\n                        rm=12.35, pad_size=2.3, ddrill=1.2, pack_width=19.3, pack_height=8.9,\r\n                        innerpack_width=18, innerpack_height=7.6,\r\n                        tags=standardtags+\"HC-51/U\",\r\n                        description=\"Crystal THT HC-51/U, http://www.crovencrystals.com/croven_pdf/HC-51_Crystal_Holder_Rev_00.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dhc49, height3d=19.7)\r\n    makeCrystalAll(footprint_name=\"Crystal_HC52-U_Horizontal\",\r\n                   rm=3.8, pad_size=1.5, ddrill=0.8, pack_width=8.8, pack_height=8, pack_rm=3.8, pack_offset=1.5,\r\n                   package_pad=True, package_pad_offset=1.5, package_pad_size=[9.5, 8.5],\r\n                   package_pad_add_holes=True, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                   style=\"hc49\",\r\n                   description=\"Crystal THT HC-51/U http://www.kvg-gmbh.de/assets/uploads/files/product_pdfs/XS71xx.pdf\",\r\n                   lib_name=\"Crystals\",\r\n                   offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                   script3d=script3dhc49h, height3d=3.3, iheight3d=2.3)\r\n    makeCrystalHC49Vert(footprint_name=\"Crystal_HC52-U_Vertical\", pins=2,\r\n                        rm=3.8, pad_size=1.5, ddrill=0.8, pack_width=8, pack_height=3.3,\r\n                        innerpack_width=7, innerpack_height=2.3,\r\n                        tags=standardtags+\"HC-52/U\",\r\n                        description=\"Crystal THT HC-52/U, http://www.kvg-gmbh.de/assets/uploads/files/product_pdfs/XS71xx.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dhc49, height3d=8.8)\r\n    makeCrystalHC49Vert(footprint_name=\"Crystal_HC52-U-3pin_Vertical\", pins=3,\r\n                        rm=3.8, pad_size=1.5, ddrill=0.8, pack_width=8, pack_height=3.3,\r\n                        innerpack_width=7, innerpack_height=2.3,\r\n                        tags=standardtags+\"HC-52/U\",\r\n                        description=\"Crystal THT HC-52/U, http://www.kvg-gmbh.de/assets/uploads/files/product_pdfs/XS71xx.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dhc493p, height3d=8.8)\r\n    makeCrystalAll(footprint_name=\"Crystal_HC52-8mm_Horizontal\",\r\n                   rm=3.8, pad_size=1.5, ddrill=0.8, pack_width=8, pack_height=8, pack_rm=3.8, pack_offset=1.5,\r\n                   package_pad=True, package_pad_offset=1.5, package_pad_size=[8.5, 8.5],\r\n                   package_pad_add_holes=True, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                   style=\"hc49\",\r\n                   description=\"Crystal THT HC-51/8mm http://www.kvg-gmbh.de/assets/uploads/files/product_pdfs/XS71xx.pdf\",\r\n                   lib_name=\"Crystals\",\r\n                   offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                   script3d=script3dhc49h, height3d=3.3, iheight3d=2.3)\r\n    makeCrystalHC49Vert(footprint_name=\"Crystal_HC52-8mm_Vertical\", pins=2,\r\n                        rm=3.8, pad_size=1.5, ddrill=0.8, pack_width=8, pack_height=3.3,\r\n                        innerpack_width=7, innerpack_height=2.3,\r\n                        tags=standardtags+\"HC-49/U\",\r\n                        description=\"Crystal THT HC-52/8mm, http://www.kvg-gmbh.de/assets/uploads/files/product_pdfs/XS71xx.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dhc49, height3d=8)\r\n    makeCrystalAll(footprint_name=\"Crystal_HC52-6mm_Horizontal\",\r\n                   rm=3.8, pad_size=1.5, ddrill=0.8, pack_width=6, pack_height=8, pack_rm=3.8, pack_offset=1.5,\r\n                   package_pad=True, package_pad_offset=1.5, package_pad_size=[6.5, 8.5],\r\n                   package_pad_add_holes=True, package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8,\r\n                   style=\"hc49\",\r\n                   description=\"Crystal THT HC-51/6mm http://www.kvg-gmbh.de/assets/uploads/files/product_pdfs/XS71xx.pdf\",\r\n                   lib_name=\"Crystals\",\r\n                   offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                   script3d=script3dhc49h, height3d=3.3, iheight3d=2.3)\r\n    makeCrystalHC49Vert(footprint_name=\"Crystal_HC52-6mm_Vertical\", pins=2,\r\n                        rm=3.8, pad_size=1.5, ddrill=0.8, pack_width=8, pack_height=3.3,\r\n                        innerpack_width=7, innerpack_height=2.3,\r\n                        tags=standardtags+\"HC-49/U\",\r\n                        description=\"Crystal THT HC-52/6mm, http://www.kvg-gmbh.de/assets/uploads/files/product_pdfs/XS71xx.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dhc49, height3d=6)\r\n    makeCrystalHC49Vert(footprint_name=\"Resonator_Murata_DSN6\", pins=3, addSizeFootprintName=True,\r\n                        rm=5, pad_size=1.7, ddrill=1, pack_width=7, pack_height=2.54,\r\n                        innerpack_width=7, innerpack_height=2.54,\r\n                        tags=standardtagsres+\" DSN6\",\r\n                        description=\"Ceramic Resomator/Filter Murata DSN6, http://cdn-reichelt.de/documents/datenblatt/B400/DSN6NC51H.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dres3, height3d=8)\r\n    makeCrystalHC49Vert(footprint_name=\"Resonator_Murata_DSS6\", pins=3, addSizeFootprintName=True,\r\n                        rm=5, pad_size=1.7, ddrill=1, pack_width=7, pack_height=2.54,\r\n                        innerpack_width=7, innerpack_height=2.54,\r\n                        tags=standardtagsres + \" DSS6\",\r\n                        description=\"Ceramic Resomator/Filter Murata DSS6, http://cdn-reichelt.de/documents/datenblatt/B400/DSN6NC51H.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dres3, height3d=7)\r\n    makeCrystalHC49Vert(footprint_name=\"Resonator_Murata_CSTLSxxxG\", pins=3, addSizeFootprintName=True,\r\n                        rm=5, pad_size=1.7, ddrill=1, pack_width=8, pack_height=3,\r\n                        innerpack_width=8, innerpack_height=3,\r\n                        tags=standardtagsres + \" CSTLSxxxG\",\r\n                        description=\"Ceramic Resomator/Filter Murata CSTLSxxxG, http://www.murata.com/~/media/webrenewal/support/library/catalog/products/timingdevice/ceralock/p17e.ashx\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dres3, height3d=5.5)\r\n    makeCrystalHC49Vert(footprint_name=\"Resonator_Murata_CSTLSxxxX\", pins=3, addSizeFootprintName=True,\r\n                        rm=5, pad_size=1.7, ddrill=1, pack_width=5.5, pack_height=3,\r\n                        innerpack_width=5.5, innerpack_height=3,\r\n                        tags=standardtagsres + \" CSTLSxxxX\",\r\n                        description=\"Ceramic Resomator/Filter Murata CSTLSxxxX, http://www.murata.com/~/media/webrenewal/support/library/catalog/products/timingdevice/ceralock/p17e.ashx\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dres3, height3d=5.5)\r\n    makeCrystalHC49Vert(footprint_name=\"Resonator\", pins=2, addSizeFootprintName=True,\r\n                        rm=5, pad_size=1.5, ddrill=0.8, pack_width=10, pack_height=5,\r\n                        innerpack_width=10, innerpack_height=5,\r\n                        tags=standardtagsres + \"\",\r\n                        description=\"Ceramic Resomator/Filter 10.0x5.0 RedFrequency MG/MT/MX series, http://www.red-frequency.com/download/datenblatt/redfrequency-datenblatt-ir-zta.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dres2, height3d=10)\r\n    makeCrystalHC49Vert(footprint_name=\"Resonator\", pins=3, addSizeFootprintName=True,\r\n                        rm=5, pad_size=1.5, ddrill=0.8, pack_width=10, pack_height=5,\r\n                        innerpack_width=10, innerpack_height=5,\r\n                        tags=standardtagsres + \"\",\r\n                        description=\"Ceramic Resomator/Filter 10.0x5.0mm^2 RedFrequency MG/MT/MX series, http://www.red-frequency.com/download/datenblatt/redfrequency-datenblatt-ir-zta.pdf\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1/2.54, 1/2.54, 1/2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dres3, height3d=10)\r\n    makeCrystalHC49Vert(footprint_name=\"Resonator\", pins=3, addSizeFootprintName=True,\r\n                        rm=5, pad_size=1.7, ddrill=1, pack_width=7, pack_height=2.5,\r\n                        innerpack_width=7, innerpack_height=2.5,\r\n                        tags=standardtagsres + \"\",\r\n                        description=\"Ceramic Resomator/Filter 7.0x2.5mm^2\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1/2.54, 1/2.54, 1/2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dres3, height3d=5.5)\r\n    makeCrystalHC49Vert(footprint_name=\"Resonator\", pins=2, addSizeFootprintName=True,\r\n                        rm=5, pad_size=1.7, ddrill=1, pack_width=7, pack_height=2.5,\r\n                        innerpack_width=7, innerpack_height=2.5,\r\n                        tags=standardtagsres + \"\",\r\n                        description=\"Ceramic Resomator/Filter 7.0x2.5mm^2\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1/2.54, 1/2.54, 1/2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dres2, height3d=5.5)\r\n    makeCrystalHC49Vert(footprint_name=\"Resonator\", pins=3, addSizeFootprintName=True,\r\n                        rm=5, pad_size=1.7, ddrill=1, pack_width=8, pack_height=3.5,\r\n                        innerpack_width=8, innerpack_height=3.5,\r\n                        tags=standardtagsres + \"\",\r\n                        description=\"Ceramic Resomator/Filter 8.0x3.5mm^2\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1/2.54, 1/2.54, 1/2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dres3, height3d=6.5)\r\n    makeCrystalHC49Vert(footprint_name=\"Resonator\", pins=2, addSizeFootprintName=True,\r\n                        rm=5, pad_size=1.7, ddrill=1, pack_width=8, pack_height=3.5,\r\n                        innerpack_width=8, innerpack_height=3.5,\r\n                        tags=standardtagsres + \"\",\r\n                        description=\"Ceramic Resomator/Filter 8.0x3.5mm^2\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1/2.54, 1/2.54, 1/2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dres2, height3d=6.5)\r\n    makeCrystalHC49Vert(footprint_name=\"Resonator\", pins=3, addSizeFootprintName=True,\r\n                        rm=5, pad_size=1.7, ddrill=1, pack_width=6, pack_height=3.0,\r\n                        innerpack_width=6, innerpack_height=3.0,\r\n                        tags=standardtagsres + \"\",\r\n                        description=\"Ceramic Resomator/Filter 6.0x3.0mm^2\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1/2.54, 1/2.54, 1/2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dres3, height3d=6.5)\r\n    makeCrystalHC49Vert(footprint_name=\"Resonator\", pins=2, addSizeFootprintName=True,\r\n                        rm=5, pad_size=1.7, ddrill=1, pack_width=6, pack_height=3.0,\r\n                        innerpack_width=6, innerpack_height=3.0,\r\n                        tags=standardtagsres + \"\",\r\n                        description=\"Ceramic Resomator/Filter 6.0x3.0mm^2\",\r\n                        lib_name=\"Crystals\",\r\n                        offset3d=[0, 0, 0], scale3d=[1/2.54, 1/2.54, 1/2.54], rotate3d=[0, 0, 0],\r\n                        script3d=script3dres2, height3d=6.5)\r\n"
  },
  {
    "path": "scripts/Diodes_SMD/generator found under SMD_chip_package_rlc-etc",
    "content": ""
  },
  {
    "path": "scripts/Diodes_THT/make_Diodes_THT.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom drawing_tools import *\nfrom footprint_scripts_resistorlike import *\n\n\nif __name__ == '__main__':\n    # standard resistors: http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf\n    type = \"cyl\"\n    script3d=\"d_hor.py\"\n    with open(script3d, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3dv=\"d_ver.py\"\n    with open(script3dv, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3dvkup=\"d_ver_kup.py\"\n    with open(script3dvkup, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n\n    script3dglass=\"d_hor_glass.py\"\n    with open(script3dglass, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3dvglass=\"d_ver_glass.py\"\n    with open(script3dvglass, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3dvkupglass=\"d_ver_kup_glass.py\"\n    with open(script3dvkupglass, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n\n    d2=0\n    R_POW = 0\n    clname=\"D\"\n    lbname=\"${KISYS3DMOD}/Diode_THT\"\n    deco=\"diode\"\n    deco_kup=\"diode_KUP\"\n\n\n    seriesname = \"DO-27\"; w=9.52; d=5.33; ddrill=1.2; add_description=\", http://www.slottechforum.com/slotinfo/Techstuff/CD2%20Diodes%20and%20Transistors/Cases/Diode%20DO-27.jpg\"; name_additions=[]\n    for rm in [12.7, 15.24]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3d)\n    for rm in [5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkup)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dv)\n\n    seriesname = \"DO-41_SOD81\"; w=5.2; d=2.7; ddrill=1.1; add_description=\", https://www.diodes.com/assets/Package-Files/DO-41-Plastic.pdf\"; name_additions=[]\n    for rm in [7.62, 10.16, 12.7]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3d)\n    for rm in [2.54, 3.81, 5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkup)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dv)\n\n    seriesname = \"DO-34_SOD68\"; w=3.04; d=1.6; ddrill=0.75; add_description=\", https://www.nxp.com/docs/en/data-sheet/KTY83_SER.pdf\"; name_additions=[]\n    for rm in [7.62, 10.16, 12.7]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3d)\n    for rm in [2.54, 5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkup)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dv)\n\n    seriesname = \"DO-35_SOD27\"; w=4; d=2; ddrill=0.8; add_description=\", http://www.diodes.com/_files/packages/DO-35.pdf\"; name_additions=[]\n    for rm in [7.62, 10.16, 12.7]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dglass)\n    for rm in [2.54, 3.81, 5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkupglass)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvglass)\n    seriesname = \"A-405\"; w=5.2; d=2.7; ddrill=0.9; add_description=\", http://www.diodes.com/_files/packages/A-405.pdf\"; name_additions=[]\n    for rm in [7.62, 10.16, 12.7]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3d)\n    for rm in [2.54, 5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkup)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dv)\n    seriesname = \"DO-15\"; w=7.6; d=3.6; ddrill=1.2; add_description=\", http://www.diodes.com/_files/packages/DO-15.pdf\"; name_additions=[]\n    for rm in [10.16, 12.7, 15.24]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3d)\n    for rm in [2.54, 3.81, 5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkup)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dv)\n    seriesname = \"DO-201\"; w=9.53; d=5.21; ddrill=1.3; add_description=\", http://www.diodes.com/_files/packages/DO-201.pdf\"; name_additions=[]\n    for rm in [12.7, 15.24]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3d)\n    for rm in [3.81, 5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkup)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dv)\n    seriesname = \"DO-201AD\"; w=9.5; d=5.2; ddrill=1.6; add_description=\", http://www.diodes.com/_files/packages/DO-201AD.pdf\"; name_additions=[]\n    for rm in [12.7, 15.24]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3d)\n    for rm in [3.81, 5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkup)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dv)\n    seriesname = \"DO-201AE\"; w=9; d=5.3; ddrill=1.3; add_description=\", http://www.farnell.com/datasheets/529758.pdf\"; name_additions=[]\n    for rm in [12.7, 15.24]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3d)\n    for rm in [3.81, 5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkup)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dv)\n    seriesname = \"P600_R-6\"; w=9.1; d=9.1; ddrill=1.6; add_description=\", http://www.vishay.com/docs/88692/p600a.pdf, http://www.diodes.com/_files/packages/R-6.pdf\"; name_additions=[]\n    for rm in [12.7,20]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3d)\n    for rm in [7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkup)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dv)\n    seriesname = \"5W\"; w=8.9; d=3.7; ddrill=1.4; add_description=\", http://www.diodes.com/_files/packages/8686949.gif\"; name_additions=[]\n    for rm in [10.16, 12.7]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3d)\n    for rm in [5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkup)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dv)\n    seriesname = \"5KP\"; w=7.62; d=9.53; ddrill=1.4; add_description=\", http://www.diodes.com/_files/packages/8686949.gif\"; name_additions=[]\n    for rm in [10.16, 12.7]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3d)\n    for rm in [7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkup)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dv)\n    seriesname = \"5KPW\"; w=9; d=8; ddrill=1.6; add_description=\", http://www.diodes.com/_files/packages/8686949.gif\"; name_additions=[]\n    for rm in [12.7]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3d)\n    for rm in [7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkup)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dv)\n    seriesname = \"T-1\"; w=3.2; d=2.6; ddrill=1; add_description=\", http://www.diodes.com/_files/packages/T-1.pdf\"; name_additions=[]\n    for rm in [5.08, 10.16, 12.7]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dglass)\n    for rm in [2.54]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco_kup, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvkupglass)\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, deco=deco, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, classname=clname, lib_name=lbname, specialtags=[],script3d=script3dvglass)\n"
  },
  {
    "path": "scripts/Fuse/ptc-fuse-tht.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))\nsys.path.append(os.path.join(sys.path[0], \"..\", \"tools\"))\n\nfrom KicadModTree import *\nfrom drawing_tools import *\n\ndef ptc_fuse_tht(args):\n    footprint_name = args[\"name\"]\n    datasheet = args[\"datasheet\"]\n    ihold = args[\"ihold\"]\n    itrip = args[\"itrip\"]\n    drill = args[\"drill\"]\n    w = args[\"width\"]\n    h = args[\"height\"]\n    pitch = args[\"pitch\"]\n    offset = args[\"offset\"]\n\n    f = Footprint(footprint_name)\n    f.setDescription(\"PTC Resettable Fuse, Ihold = \" + ihold +\n                     \", Itrip=\" + itrip + \", \" + datasheet)\n    f.setTags(\"ptc resettable fuse polyfuse THT\")\n    f.append(Model(filename=\"${KISYS3DMOD}/Fuse.3dshapes/\" +\n                   footprint_name + \".wrl\",\n                   at=[0.0, 0.0, 0.0],\n                   scale=[1.0, 1.0, 1.0],\n                   rotate=[0.0, 0.0, 0.0]))\n\n    d = [drill, drill]\n    p = [drill + 1.0, drill + 1.0]\n\n    s = [1.0, 1.0]\n    t = 0.15\n\n    wCrtYd = 0.05\n    wFab = 0.1\n    wSilkS = 0.12\n\n    silk = 0.1\n    crtYd = 0.25\n\n    clearance = 0.3\n\n    xPin1 = 0.0\n    xPin2 = pitch\n    xCenter = pitch / 2\n    xLeft = xCenter - w / 2\n    xRight = xCenter + w / 2\n    xLeftSilk = xLeft - silk\n    xRightSilk = xRight + silk\n    xLeftCrtYd = xLeft - crtYd\n    xRightCrtYd = xRight + crtYd\n\n    yPin1 = 0.0\n    yPin2 = offset\n    yCenter = offset / 2\n    yTop = yCenter - h / 2\n    yBottom = yCenter + h / 2\n    yRef = yTop - 1.0\n    yValue = yBottom + 1.0\n    yTopSilk = yTop - silk\n    yBottomSilk = yBottom + silk\n    yTopCrtYd = yTop - crtYd\n    yBottomCrtYd = yBottom + crtYd\n\n    keepout = []\n    ko_diameter = p[0] + 2 * clearance\n\n    # Pads\n    pin = 1\n    for coord in [[xPin1, yPin1], [xPin2, yPin2]]:\n        f.append(Pad(number=str(pin), type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n                 at=coord, size=p, layers=Pad.LAYERS_THT, drill=d))\n        keepout = keepout + addKeepoutRound(coord[0], coord[1],\n                                            ko_diameter, ko_diameter)\n        pin = pin + 1\n\n    # Text\n    f.append(Text(type=\"reference\", text=\"REF**\", at=[xCenter, yRef],\n                  layer=\"F.SilkS\", size=s, thickness=t))\n    f.append(Text(type=\"value\", text=footprint_name, at=[xCenter, yValue],\n                  layer=\"F.Fab\", size=s, thickness=t))\n    f.append(Text(type=\"user\", text=\"%R\", at=[xCenter, yCenter],\n                  layer=\"F.Fab\", size=s, thickness=t))\n\n    # Fab outline\n    f.append(RectLine(start=[xLeft, yTop],\n                      end=[xRight, yBottom],\n                      layer=\"F.Fab\", width=wFab))\n\n    # Silk outline\n    addRectWithKeepout(f, xLeftSilk, yTopSilk,\n                       xRightSilk - xLeftSilk, yBottomSilk - yTopSilk,\n                       \"F.SilkS\", wSilkS, keepout)\n\n    # Courtyard\n    f.append(RectLine(start=[xLeftCrtYd, yTopCrtYd],\n                      end=[xRightCrtYd, yBottomCrtYd],\n                      layer=\"F.CrtYd\", width=wCrtYd))\n\n    file_handler = KicadFileHandler(f)\n    file_handler.writeFile(footprint_name + \".kicad_mod\")\n\n\nif __name__ == '__main__':\n    parser = ModArgparser(ptc_fuse_tht)\n    # the root node of .yml files is parsed as name\n    parser.add_parameter(\"name\", type=str, required=True)\n    parser.add_parameter(\"datasheet\", type=str, required=False,\n                         default=\"http://www.bourns.com/docs/Product-Datasheets/mfrg.pdf\")\n    parser.add_parameter(\"ihold\", type=str, required=True)\n    parser.add_parameter(\"itrip\", type=str, required=True)\n    parser.add_parameter(\"drill\", type=float, required=False, default=1.01)\n    parser.add_parameter(\"pitch\", type=float, required=False, default=5.1)\n    parser.add_parameter(\"height\", type=float, required=False, default=3.0)\n    parser.add_parameter(\"width\", type=float, required=True)\n    parser.add_parameter(\"offset\", type=float, required=False, default=1.2)\n\n    # now run our script which handles the whole part of parsing the files\n    parser.run()\n"
  },
  {
    "path": "scripts/Fuse/ptc-fuse-tht.yaml",
    "content": "Fuse_Bourns_MF-RG300:\n  ihold: 3.0A\n  itrip: 5.1A\n  width: 7.1\nFuse_Bourns_MF-RG400:\n  ihold: 4.0A\n  itrip: 6.8A\n  width: 9.9\nFuse_Bourns_MF-RG500:\n  ihold: 5.0A\n  itrip: 8.5A\n  width: 10.4\nFuse_Bourns_MF-RG600:\n  ihold: 6.0A\n  itrip: 10.2A\n  width: 10.7\nFuse_Bourns_MF-RG650:\n  ihold: 6.5A\n  itrip: 11.1A\n  width: 11.2\nFuse_Bourns_MF-RG700:\n  ihold: 7.0A\n  itrip: 11.9A\n  width: 11.2\nFuse_Bourns_MF-RG800:\n  ihold: 8.0A\n  itrip: 13.6A\n  width: 12.7\nFuse_Bourns_MF-RG900:\n  ihold: 9.0A\n  itrip: 15.3A\n  width: 14.0\nFuse_Bourns_MF-RG1000:\n  ihold: 10.0A\n  itrip: 17.0A\n  width: 16.5\nFuse_Bourns_MF-RG1100:\n  ihold: 11.0A\n  itrip: 18.7A\n  width: 17.5\nFuse_Bourns_MF-RHT050:\n  ihold: 0.5A\n  itrip: 0.92A\n  width: 7.4\n  drill: 0.71\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT070:\n  ihold: 0.7A\n  itrip: 1.4A\n  width: 6.86\n  drill: 0.71\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT100:\n  ihold: 1.0A\n  itrip: 1.8A\n  width: 9.7\n  drill: 0.71\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT200:\n  ihold: 2.0A\n  itrip: 3.8A\n  width: 9.4\n  drill: 0.71\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT300:\n  ihold: 3.0A\n  itrip: 6.0A\n  width: 8.8\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT400:\n  ihold: 4.0A\n  itrip: 7.5A\n  width: 10.0\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT500:\n  ihold: 5.0A\n  itrip: 9.0A\n  width: 11.2\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT550:\n  ihold: 5.5A\n  itrip: 10.0A\n  width: 11.2\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT600:\n  ihold: 6.0A\n  itrip: 10.8A\n  width: 11.2\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT650:\n  ihold: 6.5A\n  itrip: 12.0A\n  width: 12.7\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT700:\n  ihold: 7.0A\n  itrip: 13.0A\n  width: 14.0\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT750:\n  ihold: 7.5A\n  itrip: 13.1A\n  width: 14.0\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT800:\n  ihold: 8.0A\n  itrip: 15.0A\n  width: 16.5\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT900:\n  ihold: 9.0A\n  itrip: 16.5A\n  width: 16.5\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT1000:\n  ihold: 10.0A\n  itrip: 18.5A\n  width: 17.5\n  pitch: 10.2\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT1100:\n  ihold: 11.0A\n  itrip: 20.0A\n  width: 21.0\n  pitch: 10.2\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\nFuse_Bourns_MF-RHT1300:\n  ihold: 13.0A\n  itrip: 24.0A\n  width: 23.5\n  height: 3.6\n  pitch: 10.2\n  drill: 1.2\n  datasheet: http://www.bourns.com/docs/product-datasheets/mfrht.pdf\n"
  },
  {
    "path": "scripts/Inductor_SMD/Inductor_SMD.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nimport re\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))\n\n# load scripts\nsys.path.append(os.path.join(sys.path[0], \"..\"))\n\nfrom KicadModTree import *\nfrom general.StandardBox import *\n\ndef qfn(args):\n\n    extraffablines = []\n\n    footprint_name = args[\"name\"]\n    description = args[\"description\"]\n    datasheet = args[\"datasheet\"]\n    fptag = args[\"tags\"]\n    SmdTht = args[\"smd_tht\"]\n    at = args[\"at\"]\n    size = args[\"size\"]\n    pins = args[\"pins\"]\n    extratexts = args[\"extratexts\"]\n\n    dir3D = 'Inductor_SMD.3dshapes'\n    f = Footprint(footprint_name)\n\n    file3Dname = \"${KISYS3DMOD}/\" + dir3D + \"/\" + footprint_name + \".wrl\"\n    words = footprint_name.split(\"_\")\n    if words[-1].lower().startswith('handsolder'):\n        words[-1] = ''\n        ff = '_'.join(words)\n        file3Dname = \"${KISYS3DMOD}/\" + dir3D + \"/\" + ff + \".wrl\"\n    f.append(StandardBox(footprint=f, description=description, datasheet=datasheet, at=at, size=size, tags=fptag, SmdTht=SmdTht, extratexts=extratexts, pins=pins, file3Dname=file3Dname ))\n    #\n    #\n    #\n    file_handler = KicadFileHandler(f)\n    file_handler.writeFile(footprint_name + \".kicad_mod\")\n    \n\n\nif __name__ == '__main__':\n\tparser = ModArgparser(qfn)\n\t# the root node of .yml files is parsed as name\n\tparser.add_parameter(\"name\", type=str, required=True)\n\tparser.add_parameter(\"description\", type=str, required=True)\n\tparser.add_parameter(\"datasheet\", type=str, required=True)\n\tparser.add_parameter(\"tags\", type=str, required=True)\n\tparser.add_parameter(\"smd_tht\", type=str, required=False, default='tht')\n\tparser.add_parameter(\"at\", type=list, required=True)\n\tparser.add_parameter(\"size\", type=list, required=False)\n\tparser.add_parameter(\"pins\", type=list, required=True)\n\tparser.add_parameter(\"extratexts\", type=list, required=False)\n\n\n\t# now run our script which handles the whole part of parsing the files\n\tparser.run()\n"
  },
  {
    "path": "scripts/Inductor_SMD/Inductor_SMD.yml",
    "content": "#\n# extratexts: must be included even if the string is empty, it is a quirk in ModArgparser.py\n#\n# size: is normally 2 dimensional, creaing a box, in this case 6x6 mm\n#  size: [6.00, 6.00]\n#\n# But it is possible to define how the corners should look like with following optional paramters\n#\n# ULR : Upper left corner with arc\n# ULP: Upper left corner with rectangular cut\n#\n# URR : Upper right corner with arc\n# URP: Upper right corner with rectangular cut\n#\n# LRR : Lower right corner with arc\n# LRP: Lower right corner with rectangular cut\n#\n# LLR : Lower left corner with arc\n# LLP: Lower left corner with rectangular cut\n#\n#\n#   size: [6.00, 6.00, ['ULP', 0.9, 0.9]]\n# means a box of 6x6 mm but upper left corner is cut 0.9 mm both in x and y led\n#\n#   size: [6.00, 6.00, ['ULR', 0.2], ['LRP', 0.9, 0.9]]\n# means a box of 6x6 mm but upper left corner is cut by an arc with radius 0.2\n# and lower right corner is cut 0.9 in both x and y led\n#\n#\n\nL_TDK_SLF6025:\n  description: \"Inductor, TDK, SLF6025, 6.0mmx6.0mm\"\n  datasheet: \"https://product.tdk.com/info/en/document/catalog/smd/inductor_commercial_power_slf6025_en.pdf\"\n  tags: \"Inductor TDK_SLF6025\"\n  extratexts: [[-49.0, -0.05, \"\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-3.00, 3.00]\n  size: [6.00, 6.00]\n#  size: [6.00, 6.00]\n  smd_tht: \"smd\"\n  pins: [[\"smd\", \"1\", -2.75, 0, 1.5, 2.2, 0.0], [\"smd\", \"2\", 2.75, 0, 1.5, 2.2, 0.0]]\n\nL_TDK_SLF6028:\n  description: \"Inductor, TDK, SLF6028, 6.0mmx6.0mm\"\n  datasheet: \"https://product.tdk.com/info/en/document/catalog/smd/inductor_commercial_power_slf6028_en.pdf\"\n  tags: \"Inductor TDK_SLF6028\"\n  extratexts: [[-49.0, -0.05, \"\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-3.00, 3.00]\n  size: [6.00, 6.00]\n  smd_tht: \"smd\"\n  pins: [[\"smd\", \"1\", -2.75, 0, 1.5, 2.2, 0.0], [\"smd\", \"2\", 2.75, 0, 1.5, 2.2, 0.0]]\n\nL_TDK_SLF6045:\n  description: \"Inductor, TDK, SLF6045, 6.0mmx6.0mm\"\n  datasheet: \"https://product.tdk.com/info/en/document/catalog/smd/inductor_commercial_power_slf6045_en.pdf\"\n  tags: \"Inductor TDK_SLF6045\"\n  extratexts: [[-49.0, -0.05, \"\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-3.00, 3.00]\n  size: [6.00, 6.00]\n  smd_tht: \"smd\"\n  pins: [[\"smd\", \"1\", -2.75, 0, 1.5, 2.2, 0.0], [\"smd\", \"2\", 2.75, 0, 1.5, 2.2, 0.0]]\n\nL_TDK_SLF7032:\n  description: \"Inductor, TDK, SLF7032, 7.0mmx7.0mm\"\n  datasheet: \"https://product.tdk.com/info/en/document/catalog/smd/inductor_commercial_power_slf7032_en.pdf\"\n  tags: \"Inductor TDK_SLF7032\"\n  extratexts: [[-49.0, -0.05, \"\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-3.5, 3.5]\n  size: [7.00, 7.00]\n  smd_tht: \"smd\"\n  pins: [[\"smd\", \"1\", -3.15, 0, 1.5, 2.2, 0.0], [\"smd\", \"2\", 3.15, 0, 1.5, 2.2, 0.0]]\n\nL_TDK_SLF7045:\n  description: \"Inductor, TDK, SLF7045, 7.0mmx7.0mm\"\n  datasheet: \"https://product.tdk.com/info/en/document/catalog/smd/inductor_commercial_power_slf7045_en.pdf\"\n  tags: \"Inductor TDK_SLF7045\"\n  extratexts: [[-49.0, -0.05, \"\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-3.5, 3.5]\n  size: [7.00, 7.00]\n  smd_tht: \"smd\"\n  pins: [[\"smd\", \"1\", -3.15, 0, 1.5, 2.2, 0.0], [\"smd\", \"2\", 3.15, 0, 1.5, 2.2, 0.0]]\n\nL_TDK_SLF7055:\n  description: \"Inductor, TDK, SLF7055, 7.0mmx7.0mm\"\n  datasheet: \"https://product.tdk.com/info/en/document/catalog/smd/inductor_commercial_power_slf7055_en.pdf\"\n  tags: \"Inductor TDK_SLF7055\"\n  extratexts: [[-49.0, -0.05, \"\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-3.5, 3.5]\n  size: [7.00, 7.00]\n  smd_tht: \"smd\"\n  pins: [[\"smd\", \"1\", -3.15, 0, 1.5, 2.2, 0.0], [\"smd\", \"2\", 3.15, 0, 1.5, 2.2, 0.0]]\n\nL_TDK_SLF10145:\n  description: \"Inductor, TDK, SLF10145, 10.1mmx10.1mm\"\n  datasheet: \"https://product.tdk.com/info/en/catalog/datasheets/inductor_automotive_power_slf10145-h_en.pdf\"\n  tags: \"Inductor TDK_SLF10145\"\n  extratexts: [[-49.0, -0.05, \"\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-5.05, 5.05]\n  size: [10.1, 10.1]\n  smd_tht: \"smd\"\n  pins: [[\"smd\", \"1\", -4.05, 0, 2.5, 3.2, 0.0], [\"smd\", \"2\", 4.05, 0, 2.5, 3.2, 0.0]]\n\nL_TDK_SLF10165:\n  description: \"Inductor, TDK, SLF10165, 10.1mmx10.1mm\"\n  datasheet: \"https://product.tdk.com/info/en/catalog/datasheets/inductor_commercial_power_slf10165_en.pdf\"\n  tags: \"Inductor TDK_SLF10165\"\n  extratexts: [[-49.0, -0.05, \"\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-5.05, 5.05]\n  size: [10.1, 10.1]\n  smd_tht: \"smd\"\n  pins: [[\"smd\", \"1\", -4.05, 0, 2.5, 3.2, 0.0], [\"smd\", \"2\", 4.05, 0, 2.5, 3.2, 0.0]]\n\nL_TDK_SLF12555:\n  description: \"Inductor, TDK, SLF12555, 12.5mmx12.5mm\"\n  datasheet: \"https://product.tdk.com/info/en/catalog/datasheets/inductor_commercial_power_slf12555_en.pdf\"\n  tags: \"Inductor SLF12555\"\n  extratexts: [[-49.0, -0.05, \"\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-6.25, 6.25]\n  size: [12.5, 12.5]\n  smd_tht: \"smd\"\n  pins: [[\"smd\", \"1\", -5.55, 0, 2.6, 3.2, 0.0], [\"smd\", \"2\", 5.55, 0, 2.6, 3.2, 0.0]]\n\nL_TDK_SLF12565:\n  description: \"Inductor, TDK, SLF12565, 12.5mmx12.5mm\"\n  datasheet: \"https://product.tdk.com/info/en/catalog/datasheets/inductor_automotive_power_slf12565-h_en.pdf\"\n  tags: \"Inductor SLF12565\"\n  extratexts: [[-49.0, -0.05, \"\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-6.25, 6.25]\n  size: [12.5, 12.5]\n  smd_tht: \"smd\"\n  pins: [[\"smd\", \"1\", -5.55, 0, 2.6, 3.2, 0.0], [\"smd\", \"2\", 5.55, 0, 2.6, 3.2, 0.0]]\n\nL_TDK_SLF12575:\n  description: \"Inductor, TDK, SLF12575, 12.5mmx12.5mm\"\n  datasheet: \"https://product.tdk.com/info/en/catalog/datasheets/inductor_automotive_power_slf12575-h_en.pdf\"\n  tags: \"Inductor SLF12575\"\n  extratexts: [[-49.0, -0.05, \"\", \"F.SilkS\", 3.0, 3.0]]\n  at: [-6.25, 6.25]\n  size: [12.5, 12.5]\n  smd_tht: \"smd\"\n  pins: [[\"smd\", \"1\", -5.55, 0, 2.6, 3.2, 0.0], [\"smd\", \"2\", 5.55, 0, 2.6, 3.2, 0.0]]\n"
  },
  {
    "path": "scripts/Inductors/Choke_Schaffner_RNXXX.py",
    "content": "#http://katalog.we-online.com/en/pbs/WE-MAPI]\n\n#sizes,shapes,etc]\n#name, Type, #pins, A, B, H, L, W, , P, PDiam, PadSize\ninductors = [\n[\"RN102\",  0, 4, 10.0, 10.0,  9.0, 14.0, 14.0,  4.0,  0.6,  2.0 ],\n[\"RN112\",  1, 4, 15.0, 10.0, 12.6, 17.7, 17.1,  4.0,  0.8,  2.0 ],\n[\"RN114\",  1, 4, 20.1, 12.5, 13.2, 22.5, 21.5,  4.0,  0.8,  2.0 ],\n[\"RN116\",  1, 4, 20.1, 12.5, 13.2, 22.5, 21.5,  4.0,  0.8,  2.0 ],\n[\"RN122\",  1, 4, 25.0, 15.0, 16.5, 28.0, 27.0,  4.0,  0.8,  2.0 ],\n[\"RN142\",  1, 4, 30.0, 20.0, 19.7, 33.1, 32.5,  4.3,  0.8,  2.0 ],\n[\"RN143\",  1, 4, 30.0, 20.0, 19.7, 33.1, 32.5,  4.3,  0.8,  2.0 ],\n[\"RN152\",  2, 4, 40.0, 15.0, 25.0, 43.0, 41.8,  4.5,  1.2,  2.5 ],\n[\"RN202\",  3, 4,  5.1, 15.2, 13.5,  8.8, 18.2,  4.5,  0.8,  2.0 ],\n[\"RN204\",  3, 4,  7.6, 10.0, 14.3,  9.0, 14.0,  4.0,  0.5,  2.0 ],\n[\"RN212\",  3, 4, 10.0, 15.0, 20.0, 12.5, 18.0,  4.0,  0.8,  2.0 ],\n[\"RN214\",  3, 4, 12.5, 10.0, 25.0, 15.5, 23.0,  4.0,  0.8,  2.0 ],\n[\"RN216\",  3, 4, 12.5, 10.0, 25.0, 15.5, 23.0,  4.0,  0.8,  2.0 ],\n[\"RN218\",  3, 4, 10.0, 12.5, 20.0, 12.5, 18.0,  4.0,  0.8,  2.0 ],\n[\"RN222\",  3, 4, 15.0, 12.5, 29.3, 18.0, 31.0,  4.0,  0.8,  2.0 ],\n[\"RN232\",  3, 4, 15.0, 12.5, 34.3, 18.0, 31.0,  4.2,  0.8,  2.0 ],\n[\"RN242\",  3, 4, 15.0, 12.5, 34.3, 18.0, 31.0,  4.2,  0.8,  2.0 ]\n]\n\nimport sys\nimport os\nimport math\n\noutput_dir = os.getcwd()\n\n#if specified as an argument, extract the target directory for output footprints\nif len(sys.argv) > 1:\n    out_dir = sys.argv[1]\n    \n    if os.path.isabs(out_dir) and os.path.isdir(out_dir):\n        output_dir = out_dir\n    else:\n        out_dir = os.path.join(os.getcwd(),out_dir)\n        if os.path.isdir(out_dir):\n            output_dir = out_dir\n\nif output_dir and not output_dir.endswith(os.sep):\n    output_dir += os.sep\n        \n#import KicadModTree files\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))\nfrom KicadModTree import *\nfrom KicadModTree.nodes.specialized.PadArray import PadArray\n\nprefix = \"Choke_Schaffner_\"\npart = \"{serie}-0{pn}\"\ndims  = \"{l:0.1f}mmx{w:0.1f}mm\"\ndims2 = \"{l:0.1f}x{w:0.1f}mm\"\n\ndesc = \"Current-compensated Chokes, Schaffner, {pn}\"\ntags = \"chokes schaffner tht\"\nTargetDir = \"Inductor_THT.3dshapes\"\nDatasheet = \"https://www.schaffner.com/products/download/product/datasheet/rn-series-common-mode-chokes-new/\"\n\nfor inductor in inductors:\n    Serie,Type,PN,A,B,H,L,W,P,PDiam,PadSize=inductor\n    \n    Pin1x1 = 0\n    Pin1y1 = 0\n    Pin1dx = 1.0\n    RefX1 = 0\n    RefY1 = round((0 - ((W - B) / 2) - 1.5), 2)\n\n    cx = round(A / 2, 2)\n    cy = round(B / 2, 2)\n\n    fp_name = prefix + part.format(serie=str(Serie), pn=str(PN)) + \"-\" + dims2.format(l=L,w=W)\n    fp = Footprint(fp_name)\n    description = desc.format(pn = part.format(serie=str(Serie), pn=str(PN))) + \", \" + dims.format(l=L,w=W) + \" \" + Datasheet\n    \n#    fp.append(Line(start=[cx - (L / 2), cy - (W / 2)], end=[cx + (L / 2), cy - (W / 2)],layer='F.Fab', width=0.01))\n#    fp.append(Line(start=[cx + (L / 2), cy - (W / 2)], end=[cx + (L / 2), cy + (W / 2)],layer='F.Fab', width=0.01))\n#    fp.append(Line(start=[cx + (L / 2), cy + (W / 2)], end=[cx - (L / 2), cy + (W / 2)],layer='F.Fab', width=0.01))\n#    fp.append(Line(start=[cx - (L / 2), cy + (W / 2)], end=[cx - (L / 2), cy - (W / 2)],layer='F.Fab', width=0.01))\n\n    if Type == 0:\n        #\n        # This have the shape of a box with rounded corners\n        #\n        #\n        # Add the component outline\n        #\n        # Top line\n        Layer = ['F.Fab', 'F.SilkS', 'F.CrtYd']\n        LayerW = [0.1, 0.12, 0.05]\n        LayerD = [0, 0.12, 0.25]\n        for i in range(0, 3):\n            myLayer = Layer[i]\n            myLayerW = LayerW[i]\n            myLayerD = LayerD[i]\n            #\n            # Top line\n            x1 = 0\n            y1 = 0 - (((W - B) / 2) + myLayerD)\n            x2 = A\n            y2 = y1\n            fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n            # Top right arc\n            fp.append(Arc(center=[round(A, 2), round(0, 2)], start=[round(x2, 2), round(y2, 2)], angle=90.0, layer=myLayer, width=myLayerW))\n            # Right line\n            x1 = A + ((L - A) / 2) + myLayerD\n            y1 = 0\n            x2 = x1\n            y2 = B\n            fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n            # Bottom right arc\n            fp.append(Arc(center=[round(A, 2), round(B, 2)], start=[round(x2, 2), round(y2, 2)], angle=90.0, layer=myLayer, width=myLayerW))\n            # Bottom line\n            x1 = A\n            y1 = B + ((W - B) / 2) + myLayerD\n            x2 = 0\n            y2 = y1\n            fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n            # Bottom left arc\n            fp.append(Arc(center=[round(0, 2), round(B, 2)], start=[round(x2, 2), round(y2, 2)], angle=90.0, layer=myLayer, width=myLayerW))\n            # Left line\n            if (i == 0):\n                x1 = 0 - (((L - A) / 2) + myLayerD)\n                y1 = B\n                x2 = x1\n                y2 = 2\n                fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n                x1 = x2;\n                y1 = y2\n                x2 = x1 + 1\n                y2 = 1\n                fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n                x1 = x2;\n                y1 = y2\n                x2 = x1 - 1\n                y2 = 0\n            else:\n                x1 = 0 - (((L - A) / 2) + myLayerD)\n                y1 = B\n                x2 = x1\n                y2 = 0\n            fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n            # Top left arc\n            fp.append(Arc(center=[round(0, 2), round(0, 2)], start=[round(x2, 2), round(y2, 2)], angle=90.0, layer=myLayer, width=myLayerW))\n            \n            Pin1x1 = 0 - (((L - A) / 2) + 0.25)\n            Pin1y1 = 0 - (((W - B) / 2) + 0.25)\n            Pin1dx = 3.0\n        \n    elif Type == 1:\n        #\n        # This have the shape of a box with rounded top and bottom side\n        #\n        #\n        # Add the component outline\n        #\n        # Calculate the arc\n        #\n        Points = []\n        Layer = ['F.Fab', 'F.SilkS', 'F.CrtYd']\n        LayerW = [0.1, 0.12, 0.05]\n        LayerD = [0, 0.12, 0.25]\n        #\n        k = 0.0\n        m = 0.0\n        dx = round(L / 3, 2)\n        dy = round(((W - B) / 2), 2)\n        for i in range(0, 3):\n            myLayer = Layer[i]\n            myLayerW = LayerW[i]\n            myLayerD = LayerD[i]\n            #\n            if (i == 0):\n                #\n                # Top arc\n                #\n                Fabh = dy\n                angleD = 30.0\n                Fabalpha = math.radians(angleD)\n                x1 = round(cx, 2)\n                y1 = round(0, 2)\n                tdy = Fabh * math.cos(Fabalpha)\n                tdx = Fabh * math.sin(Fabalpha)\n                x2 = round(x1 - tdx, 2)\n                y2 = round(0 - tdy, 2)\n                p1 = [x1, y1, x2, y2]\n                Points.append(p1)\n                fp.append(Arc(center=[x1, y1], start=[x2, y2], angle=2*angleD, layer=myLayer, width=myLayerW))\n\n                #\n                # Top left line\n                #\n                x1 = round(cx - (L / 2), 2)\n                y1 = round(0 - (PadSize / 2), 2)\n                stx1 = x1\n                sty1 = y1\n                x2 = x2\n                y2 = y2\n                p1 = [x1, y1, x2, y2]\n                Points.append(p1)\n                fp.append(Line(start=[x1, y1],end=[x2, y2], layer=myLayer, width=myLayerW))\n                #\n                # Top right line\n                #\n                x1 = round(cx + tdx, 2)\n                y1 = y2\n                x2 = round(cx + (L / 2), 2)\n                y2 = round(0 - (PadSize / 2), 2)\n                p1 = [x1, y1, x2, y2]\n                Points.append(p1)\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                #\n                # Right line\n                #\n                x1 = x2\n                y1 = y2\n                x2 = x1\n                y2 = round(B + (PadSize / 2), 2)\n                tty4 = y2;\n                p1 = [x1, y1, x2, y2]\n                Points.append(p1)\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                #\n                #\n                # Bottom arc\n                #\n                Fabh = dy\n                angleD = 30.0\n                Fabalpha = math.radians(angleD)\n                x1 = round(cx, 2)\n                y1 = round(B, 2)\n                tdy = Fabh * math.cos(Fabalpha)\n                tdx = Fabh * math.sin(Fabalpha)\n                x3 = round(cx + tdx, 2)\n                y3 = round(B + tdy, 2)\n                p1 = [x1, y1, x3, y3]\n                Points.append(p1)\n                fp.append(Arc(center=[x1, y1], start=[x3, y3], angle=2*angleD, layer=myLayer, width=myLayerW))\n                #\n                # Bottom right line\n                #\n                x1 = x2\n                y1 = y2\n                x2 = x3\n                y2 = y3\n                p1 = [x1, y1, x2, y2]\n                Points.append(p1)\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                #\n                x1 = round(cx - tdx, 2)\n                y1 = y3\n                x2 = round(cx - (L / 2), 2)\n                y2 = tty4\n                p1 = [x1, y1, x2, y2]\n                Points.append(p1)\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                #\n                # Left line including pin 1 chamfer\n                #\n                x1 = x2\n                y1 = y2\n                x2 = x1\n                y2 = sty1\n                p1 = [x1, y1, x2, y2]\n                Points.append(p1)\n                y2 = 0.5\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                #\n                x1 = x2\n                y1 = y2\n                x2 = x2 + 0.5\n                y2 = 0;\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                #\n                x1 = x2\n                y1 = y2\n                x2 = x2 - 0.5\n                y2 = -0.5;\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                #\n                x1 = x2\n                y1 = y2\n                x2 = x2\n                y2 = sty1\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                #\n                Fabx1 = x2;\n                Faby1 = y2;\n                \n            else:\n                #\n                # Y delta\n                #\n                point = Points[1]\n                k = (point[3] - point[1]) / (point[2] - point[0])\n                m = (point[1] - k * point[0]) - myLayerD - 0.02\n                x1 = point[0] - myLayerD\n                y1 = k * x1 + m\n                ddy = math.fabs(math.sqrt(math.pow(point[1], 2)) - math.sqrt(math.pow(y1, 2)))\n                # Top arc\n                point = Points[0]\n                Fabh = dy\n                x1 = point[0]\n                cx1 = x1\n                y1 = round(point[1] - myLayerD, 2)\n                tdy = Fabh * math.cos(Fabalpha)\n                tdx = Fabh * math.sin(Fabalpha)\n                x2 = round(point[2], 2)\n                cx2 = x2\n                y2 = round(point[3] - myLayerD - 0.02, 2)\n                fp.append(Arc(center=[x1, y1], start=[x2, y2], angle=2*angleD, layer=myLayer, width=myLayerW))\n                #\n                # Top left line\n                #\n                point = Points[1]\n                x1 = round(point[0] - myLayerD, 2)\n                stx1 = x1\n                y1 = round(k * x1 + m, 2)\n                sty1 = y1\n                x2 = round(point[2], 2)\n                y2 = round((k * x2 + m), 2)\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                # Top right line\n                point = Points[2]\n                x1 = round(cx1 + (cx1 - cx2), 2)\n                y1 = y2\n                x2 = round(point[2] + myLayerD, 2)\n                y2 = sty1\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                #\n                # Right line\n                #\n                point = Points[3]\n                x1 = x2\n                y1 = y2\n                x2 = x1\n                tx2 = x2\n                y2 = round(point[3] + ddy, 2)\n                ty2 = y2\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                #\n                # Bottom arc\n                #\n                point = Points[4]\n                Fabh = dy\n                x1 = point[0]\n                cx1 = x1\n                y1 = round(point[1] + myLayerD, 2)\n                tdy = Fabh * math.cos(Fabalpha)\n                tdx = Fabh * math.sin(Fabalpha)\n                x3 = round(point[2], 2)\n                y3 = round(point[3] + myLayerD + 0.02, 2)\n                fp.append(Arc(center=[x1, y1], start=[x3, y3], angle=2*angleD, layer=myLayer, width=myLayerW))\n                #\n                # Bottom right line\n                #\n                point = Points[5]\n                x1 = tx2\n                y1 = ty2\n                x2 = x3\n                y2 = y3\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                # Bottom left line\n                point = Points[6]\n                x1 = round(cx1 - tdx, 2)\n                y1 = y3\n                x2 = stx1\n                y2 = ty2\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n                #\n                point = Points[7]\n                x1 = x2\n                y1 = y2\n                x2 = x1\n                y2 = sty1\n                fp.append(Line(start=[x1, y1], end=[x2, y2], layer=myLayer, width=myLayerW))\n\n                Pin1x1 = x2\n                Pin1y1 = y2\n                Pin1dx = 0.25\n                RefX1 = 1.0\n                RefY1 = -5\n\n    elif Type == 2:\n        #\n        # This have the shape of a hexagon\n        #\n        Points = []\n        # Add the component outline\n        #\n        ty = ((W - B) / 2)\n        alpha = 30.0    # 70 degree\n        alphar = ((2 * math.pi) / 360.0) * alpha\n        tx = ty * (math.sin(alphar) / math.cos(alphar))\n        x1 = 0 - ((L - A) / 2)\n        y1 = 0\n        x2 = x1 + tx\n        y2 = y1 - ty\n        k = (y1 - y2) / (x1 - x2)\n        m = y1 - (k * x1)\n        p1 = [x1, y1, x2, y2, k, m]\n        Points.append(p1)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = x1 + (L - (2 * tx))\n        y2 = y1\n        k = (y1 - y2) / (x1 - x2)\n        m = y1 - (k * x1)\n        p1 = [x1, y1, x2, y2, k, m]\n        Points.append(p1)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = x1 + tx\n        y2 = y1 + ty\n        k = (y1 - y2) / (x1 - x2)\n        m = y1 - (k * x1)\n        p1 = [x1, y1, x2, y2, k, m]\n        Points.append(p1)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = x1\n        y2 = y1 + B\n        k = 0\n        m = 0\n        p1 = [x1, y1, x2, y2, k, m]\n        Points.append(p1)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = x1 - tx\n        y2 = y1 + ty\n        k = (y1 - y2) / (x1 - x2)\n        m = y1 - (k * x1)\n        p1 = [x1, y1, x2, y2, k, m]\n        Points.append(p1)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = x1 - (L - (2 * tx))\n        y2 = y1\n        k = (y1 - y2) / (x1 - x2)\n        m = y1 - (k * x1)\n        p1 = [x1, y1, x2, y2, k, m]\n        Points.append(p1)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = x1 - tx\n        y2 = y1 - ty\n        k = (y1 - y2) / (x1 - x2)\n        m = y1 - (k * x1)\n        p1 = [x1, y1, x2, y2, k, m]\n        Points.append(p1)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = 0 - ((L - A) / 2)\n        tx2 = x2\n        y2 = 2\n        k = (y1 - y2) / (x1 - x2)\n        m = y1 - (k * x1)\n        p1 = [x1, y1, x2, y2, k, m]\n        Points.append(p1)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = x2 + 1\n        y2 = 1\n        k = (y1 - y2) / (x1 - x2)\n        m = y1 - (k * x1)\n        p1 = [x1, y1, x2, y2, k, m]\n        Points.append(p1)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = tx2\n        y2 = 0\n        k = (y1 - y2) / (x1 - x2)\n        m = y1 - (k * x1)\n        p1 = [x1, y1, x2, y2, k, m]\n        Points.append(p1)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n\n        #\n        # Add the component outline\n        #\n        PadDistance = 0.75\n        space=0.12\n        p1 = Points[0]\n        k =  p1[4]\n        m = p1[5]\n        y1 = (0 - ((PadSize / 2) + PadDistance))\n        x1 = ((y1 - m) / k)\n        y1 = y1 - (space * math.sin(alphar))\n        x1 = x1 - (space * math.cos(alphar))\n        y2 = p1[3] - space\n        x2 = ((y2 - (m - (2 * space))) / k)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n        #\n        # Top line\n        #\n        p1 = Points[1]\n        x1 = x2\n        y1 = y2\n        x2 = p1[2] + (space * math.sin(alphar))\n        y2 = y1\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n        #\n        p1 = Points[2]\n        k =  p1[4]\n        m = p1[5]\n        x1 = x2\n        y1 = y2\n        y2 = (0 - ((PadSize / 2) + PadDistance))\n        x2 = ((y2 - m) / k)\n        y2 = y2 - (space * math.sin(alphar))\n        x2 = x2 + (space * math.cos(alphar))\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n        #\n        # right side line\n        #\n        p1 = Points[3]\n        k =  p1[4]\n        m = p1[5]\n        x1 = p1[0] + space\n        y1 = ((PadSize / 2) + PadDistance)\n        x2 = x1\n        y2 = B - ((PadSize / 2) + 0.5)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n        #\n        p1 = Points[4]\n        k =  p1[4]\n        m = p1[5]\n        y1 = B + ((PadSize / 2) + PadDistance)\n        x1 = ((y1 - m) / k)\n        y1 = y1 + (space * math.sin(alphar))\n        x1 = x1 + (space * math.cos(alphar))\n        y2 = p1[3] + space\n        x2 = ((y2 - (m + (2 * space))) / k)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n        #\n        # Bottom line\n        #\n        p1 = Points[5]\n        x1 = x2\n        y1 = y2\n        x2 = p1[2] - (space * math.sin(alphar))\n        y2 = y1\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n        #\n        p1 = Points[6]\n        k =  p1[4]\n        m = p1[5]\n        x1 = x2\n        y1 = y2\n        y2 = B + ((PadSize / 2) + PadDistance)\n        x2 = ((y2 - m) / k)\n        y2 = y2 + (space * math.sin(alphar))\n        x2 = x2 - (space * math.cos(alphar))\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n        #\n        # Left side line\n        #\n        p1 = Points[7]\n        k =  p1[4]\n        m = p1[5]\n        x1 = p1[0] - space\n        y1 = B - ((PadSize / 2) + PadDistance)\n        x2 = x1\n        y2 = ((PadSize / 2) + PadDistance)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n\n        #\n        # Add the component courtyard\n        #\n        PadDistance = 0.75\n        space=0.25\n        p1 = Points[0]\n        k =  p1[4]\n        m = p1[5]\n        y1 = (0 - ((PadSize / 2) + PadDistance))\n        x1 = ((y1 - m) / k)\n        y1 = y1 - (space * math.sin(alphar))\n        x1 = x1 - (space * math.cos(alphar))\n        y2 = p1[3] - space\n        x2 = ((y2 - (m - (2 * space))) / k)\n        scx = x1\n        scy = y1\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.CrtYd',width=0.05))\n        #\n        # Top line\n        #\n        p1 = Points[1]\n        x1 = x2\n        y1 = y2\n        x2 = p1[2] + (space * math.sin(alphar))\n        y2 = y1\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.CrtYd',width=0.05))\n        #\n        p1 = Points[2]\n        k =  p1[4]\n        m = p1[5]\n        x1 = x2\n        y1 = y2\n        y2 = (0 - ((PadSize / 2) + PadDistance))\n        x2 = ((y2 - m) / k)\n        y2 = y2 - (space * math.sin(alphar))\n        x2 = p1[2] + space\n        y2 = p1[3]\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.CrtYd',width=0.05))\n        #\n        # Right side line\n        #\n        p1 = Points[3]\n        k =  p1[4]\n        m = p1[5]\n        x1 = p1[0] + space\n        y1 = p1[1]\n        x2 = x1\n        y2 = p1[3] + (space * math.sin(alphar))\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.CrtYd',width=0.05))\n        #\n        p1 = Points[4]\n        k =  p1[4]\n        m = p1[5]\n        y1 = y2\n        x1 = x2\n        y2 = p1[3] + space\n        x2 = ((y2 - (m + (2 * space))) / k)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.CrtYd',width=0.05))\n        #\n        # Bottom line\n        #\n        p1 = Points[5]\n        x1 = x2\n        y1 = y2\n        x2 = p1[2] - (space * math.sin(alphar))\n        y2 = y1\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.CrtYd',width=0.05))\n        #\n        p1 = Points[6]\n        x1 = x2\n        y1 = y2\n        x2 = p1[2]\n        y2 = p1[3]\n        y2 = y2 + (space * math.sin(alphar))\n        x2 = x2 - (space * math.cos(alphar))\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.CrtYd',width=0.05))\n        #\n        # Left side line\n        #\n        p1 = Points[7]\n        x1 = x2\n        y1 = y2\n        x2 = x1\n        y2 = scy \n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.CrtYd',width=0.05))\n        x1 = x2\n        y1 = y2\n        x2 = scx\n        y2 = scy\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.CrtYd',width=0.05))\n        #\n        Pin1x1 = x1\n        Pin1y1 = scy\n\n        RefX1 = 10.0\n        \n    elif Type == 3:\n        #\n        # This have the shape of a box\n        #\n        #\n        # Add the component outline\n        #\n        x1 = 0 - ((L - A) / 2)\n        y1 = 0 - ((W - B) / 2)\n        x2 = x1 + L\n        y2 = y1\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = x1\n        y2 = y1 + W\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = x1 - L\n        y2 = y1\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = x1\n        y2 = 1\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = x1 + 1\n        y2 = y1 - 1\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = 0 - ((L - A) / 2)\n        y2 = -1\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n        x1 = x2\n        y1 = y2\n        x2 = 0 - ((L - A) / 2)\n        y2 = 0 - ((W - B) / 2)\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.Fab',width=0.1))\n\n        #\n        # Add the component outline\n        #\n        x1 = (0 - ((L - A) / 2)) - 0.12\n        y1 = (0 - ((W - B) / 2)) - 0.12\n        x2 = x1 + L + 0.24\n        y2 = y1\n        if (y1 > ((PadSize / 2) + 0.25)):\n            x1 = ((PadSize / 2) + 0.5)\n            x2 = A - (PadSize / 2) - 0.5\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n        #\n        x1 = x1 + L + 0.24\n        y1 = y2 \n        x2 = x1\n        y2 = y1 + W + 0.24\n        if (x1 < (A + ((PadSize / 2) + 0.25))):\n            y1 = (PadSize / 2) + 0.5\n            y2 = B - (PadSize / 2) - 0.5\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n        #\n        x1 = x1\n        y1 = (0 - ((W - B) / 2)) + W + 0.12\n        x2 = (0 - ((L - A) / 2)) - 0.12\n        y2 = y1\n        if (y2 < (B + ((PadSize / 2) + 0.25))):\n            x1 = ((PadSize / 2) + 0.5)\n            x2 = A - (PadSize / 2) - 0.5\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n        #\n        x1 = x2\n        y1 = y2 \n        x2 = x1\n        y2 = (0 - ((W - B) / 2)) - 0.12\n        if (x1 > (0 - ((PadSize / 2) + 0.25))):\n            y1 = (PadSize / 2) + 0.5\n            y2 = B - (PadSize / 2) - 0.5\n        fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n\n        #\n        # Add the component courtyard\n        #\n        x1 = (0 - ((L - A) / 2)) - 0.25\n        y1 = (0 - ((W - B) / 2)) - 0.25\n        if (x1 > (0 - ((PadSize / 2) + 0.25))):\n            x1 = 0 - ((PadSize / 2) + 0.25)\n        if (y1 > (0 - ((PadSize / 2) + 0.25))):\n            y1 = 0 - ((PadSize / 2) + 0.25)\n        Pin1x1 = x1\n        Pin1y1 = y1\n        x2 = x1 + A - Pin1x1\n        y2 = y1 + B - Pin1y1\n        if (x2 < (A + ((L - A) / 2) + 0.25)):\n            x2 = (A + ((L - A) / 2) + 0.25)\n        if (y2 < (B + ((W - B) / 2) + 0.25)):\n            y2 = (B + ((W - B) / 2) + 0.25)\n        if (x2 < (A + (PadSize / 2) + 0.25)):\n            x2 = (A + (PadSize / 2) + 0.25)\n        if (y2 < (B + (PadSize / 2) + 0.25)):\n            y2 = (B + (PadSize / 2) + 0.25)\n        fp.append(RectLine(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.CrtYd',width=0.05))\n\n        RefX1 = 0.0\n        RefY1 = 0 - (((W - B) / 2) + 2)\n\n    #\n    # Add Pin 1 marker\n    #\n    x1 = Pin1x1 - 0.25\n    y1 = Pin1y1 - 0.25\n    x2 = x1 + Pin1dx\n    y2 = y1\n    fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n    x1 = x1\n    y1 = y1\n    x2 = x1\n    y2 = y1 + 3.0\n    fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer='F.SilkS',width=0.12))\n\n    fp.setTags(tags)\n    fp.setDescription(description)\n    \n    #\n    # Set general values\n    #\n    fp.append(Text(type='reference', text='REF**', at=[RefX1, RefY1], layer='F.SilkS'))\n    fp.append(Text(type='value', text=fp_name,     at=[round((A / 2), 2), round(((W - B) / 2) + B + 1.5,   2)], layer='F.Fab'))\n    fp.append(Text(type='user', text=\"%R\",         at=[round((A / 2), 2), round((B / 2), 2)], layer='F.Fab'))\n    \n    #\n    # Add 3D model\n    #\n    fp.append(Model(filename=\"${KISYS3DMOD}/\" + TargetDir + \"/\" + fp_name + \".wrl\", at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n    \n    #\n    # Add pads\n    #\n    fp.append(Pad(number=1,at=[0, 0], layers=Pad.LAYERS_THT, shape=Pad.SHAPE_RECT,   type=Pad.TYPE_THT,  size=[PadSize,PadSize], drill=round(PDiam + 0.1, 2)))\n    fp.append(Pad(number=2,at=[A, 0], layers=Pad.LAYERS_THT, shape=Pad.SHAPE_CIRCLE, type=Pad.TYPE_THT,  size=[PadSize,PadSize], drill=round(PDiam + 0.1, 2)))\n    fp.append(Pad(number=3,at=[0, B], layers=Pad.LAYERS_THT, shape=Pad.SHAPE_CIRCLE, type=Pad.TYPE_THT,  size=[PadSize,PadSize], drill=round(PDiam + 0.1, 2)))\n    fp.append(Pad(number=4,at=[A, B], layers=Pad.LAYERS_THT, shape=Pad.SHAPE_CIRCLE, type=Pad.TYPE_THT,  size=[PadSize,PadSize], drill=round(PDiam + 0.1, 2)))\n\n    #filename\n    filename = output_dir + fp_name + \".kicad_mod\"\n    \n    file_handler = KicadFileHandler(fp)\n    file_handler.writeFile(filename)\n"
  },
  {
    "path": "scripts/Inductors/Murata_DEM35xxC.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))\n\nfrom KicadModTree import *\n\ndatasheet = \"https://www.murata.com/~/media/webrenewal/products/inductor/chip/tokoproducts/wirewoundferritetypeforpl/m_dem3518c.ashx\"\nfootprint_name = \"L_Murata_DEM35xxC\"\n\npkgWidth = 3.9\npkgHeight = 3.7\npadXSpacing = 3.3\npadWidth = 1\npadHeight = 1.4\n\nf = Footprint(footprint_name)\nf.setDescription(datasheet)\nf.setTags(\"Inductor SMD DEM35xxC\")\nf.setAttribute(\"smd\")\nf.append(Model(filename=\"${KISYS3DMOD}/Inductor_SMD.3dshapes/\" + footprint_name + \".wrl\",\n               at=[0.0, 0.0, 0.0],\n               scale=[1.0, 1.0, 1.0],\n               rotate=[0.0, 0.0, 0.0]))\n\npadSize = [padWidth, padHeight]\ntextSize = [1.0, 1.0]\nfabRefTextSize = [0.7, 0.7]\n\nthickness1 = 0.1\nthickness2 = 0.15\n\nwCrtYd = 0.05\nwFab = 0.1\nwSilkS = 0.12\ncrtYd = 0.25\nsilkClearance = 0.2\n\nxCenter = 0.0\nxPadRight = padXSpacing / 2\nxFabRight = pkgWidth / 2\nxSilkRight = xPadRight\nxRightCrtYd = max(xPadRight + padWidth / 2, xFabRight) + crtYd\n\nxLeftCrtYd = - xRightCrtYd\nxPadLeft = -xPadRight\nxFabLeft = -xFabRight\nxSilkTopLeft = -xSilkRight\nxSilkBottomLeft = -xSilkRight\n\nyCenter = 0.0\nyFabBottom = pkgHeight / 2\nySilkBottom = yFabBottom + silkClearance\nyBottomCrtYd = yFabBottom + crtYd\n\nyTopCrtYd = -yBottomCrtYd\nySilkTop = -ySilkBottom\nyFabTop = -yFabBottom\n\nyValue = yFabBottom + 1.25\nyRef = yFabTop - 1.25\n\nf.append(Text(type=\"reference\", text=\"REF**\", at=[xCenter, yRef],\n              layer=\"F.SilkS\", size=textSize, thickness=thickness2))\nf.append(Text(type=\"value\", text=footprint_name, at=[xCenter, yValue],\n              layer=\"F.Fab\", size=textSize, thickness=thickness2))\nf.append(Text(type=\"user\", text=\"%R\", at=[xCenter, yCenter],\n              layer=\"F.Fab\", size=fabRefTextSize, thickness=thickness1))\n\nf.append(RectLine(start=[xLeftCrtYd, yTopCrtYd],\n                  end=[xRightCrtYd, yBottomCrtYd],\n                  layer=\"F.CrtYd\", width=wCrtYd))\n\nf.append(PolygoneLine(polygone=[[xFabLeft, yFabTop],\n                                [xFabRight, yFabTop],\n                                [xFabRight, yFabBottom],\n                                [xFabLeft, yFabBottom],\n                                [xFabLeft, yFabTop]],\n                      layer=\"F.Fab\", width=wFab))\n\nf.append(Line(start=[xSilkTopLeft, ySilkTop],\n              end=[xSilkRight, ySilkTop],\n              layer=\"F.SilkS\", width=wSilkS))\nf.append(Line(start=[xSilkBottomLeft, ySilkBottom],\n              end=[xSilkRight, ySilkBottom],\n              layer=\"F.SilkS\", width=wSilkS))\n\npadShape = Pad.SHAPE_ROUNDRECT\nradiusRatio = 0.2\n\nf.append(Pad(number=1, type=Pad.TYPE_SMT, shape=padShape,\n             at=[xPadLeft, yCenter], size=padSize, layers=Pad.LAYERS_SMT,\n             radius_ratio=radiusRatio))\nf.append(Pad(number=2, type=Pad.TYPE_SMT, shape=padShape,\n             at=[xPadRight, yCenter], size=padSize, layers=Pad.LAYERS_SMT,\n             radius_ratio=radiusRatio))\n\nfile_handler = KicadFileHandler(f)\nfile_handler.writeFile(footprint_name + \".kicad_mod\")\n"
  },
  {
    "path": "scripts/Inductors/bourns-srn.py",
    "content": "#http://katalog.we-online.com/en/pbs/WE-MAPI]\n\n#sizes,shapes,etc]\n#name, L, W, pad-w, pad-gap, pad-h\ninductors = [\n[1610,1.6,1.6,1.8,0.4,1.8],\n[2010,2.0,1.6,2.3,0.6,1.9],\n[2506,2.5,2.0,2.8,1.1,2.3],\n[2508,2.5,2.0,2.8,1.1,2.3],\n[2510,2.5,2.0,2.8,1.1,2.3],\n[2512,2.5,2.0,2.8,1.1,2.3],\n[3010,3.0,3.0,3.4,0.8,3.4],\n[3012,3.0,3.0,3.4,0.8,3.4],\n[3015,3.0,3.0,3.4,0.8,3.4],\n[3020,3.0,3.0,3.5,0.8,3.4],\n[4020,4.0,4.0,3.35,1.39,3.7],\n]\n\nimport sys\nimport os\n\noutput_dir = os.getcwd()\n\n#if specified as an argument, extract the target directory for output footprints\nif len(sys.argv) > 1:\n    out_dir = sys.argv[1]\n    \n    if os.path.isabs(out_dir) and os.path.isdir(out_dir):\n        output_dir = out_dir\n    else:\n        out_dir = os.path.join(os.getcwd(),out_dir)\n        if os.path.isdir(out_dir):\n            output_dir = out_dir\n\nif output_dir and not output_dir.endswith(os.sep):\n    output_dir += os.sep\n        \n#import KicadModTree files\nsys.path.append(\"..\\\\..\")\nfrom KicadModTree import *\nfrom KicadModTree.nodes.specialized.PadArray import PadArray\n\nprefix = \"Inductor_\"\npart = \"Wurth_MAPI-{pn}\"\ndims = \"{l:0.1f}mmx{w:0.1f}mm\"\n\ndesc = \"Inductor, Wurth Elektronik, {pn}\"\ntags = \"inductor wurth smd\"\n\nfor inductor in inductors:\n    name,l,w,x,g,y = inductor\n    \n    fp_name = prefix + part.format(pn=str(name))\n    \n    fp = Footprint(fp_name)\n    \n    description = desc.format(pn = part.format(pn=str(name))) + \", \" + dims.format(l=l,w=w)\n    \n    fp.setTags(tags)\n    fp.setAttribute(\"smd\")\n    fp.setDescription(description)\n    \n    # set general values\n    fp.append(Text(type='reference', text='REF**', at=[0,-y/2 - 1], layer='F.SilkS'))\n    fp.append(Text(type='value', text=fp_name, at=[0,y/2 + 1.5], layer='F.Fab'))\n    \n    #calculate pad center\n    #pad-width pw\n    pw = (x-g) / 2\n    c = g/2 + pw/2\n    \n    #add the component outline\n    fp.append(RectLine(start=[-l/2,-w/2],end=[l/2,w/2],layer='F.Fab',width=0.15))\n    \n    layers = [\"F.Cu\",\"F.Paste\",\"F.Mask\"]\n    \n    #add pads\n    fp.append(Pad(number=1,at=[-c,0],layers=layers,shape=Pad.SHAPE_RECT,type=Pad.TYPE_SMT,size=[pw,y]))\n    fp.append(Pad(number=2,at=[c,0],layers=layers,shape=Pad.SHAPE_RECT,type=Pad.TYPE_SMT,size=[pw,y]))\n    \n    #add inductor courtyard\n    cx = c + pw/2\n    cy = y / 2\n    \n    fp.append(RectLine(start=[-cx,-cy],end=[cx,cy],offset=0.35,width=0.05,grid=0.05,layer=\"F.CrtYd\"))\n    \n    #add lines\n    fp.append(Line(start=[-g/2+0.2,-w/2-0.1],end=[g/2-0.2,-w/2-0.1]))\n    fp.append(Line(start=[-g/2+0.2,w/2+0.1],end=[g/2-0.2,w/2+0.1]))\n    \n    #Add a model\n    fp.append(Model(filename=\"Inductors.3dshapes/\" + fp_name + \".wrl\"))\n    \n    #filename\n    filename = output_dir + fp_name + \".kicad_mod\"\n    \n    file_handler = KicadFileHandler(fp)\n    file_handler.writeFile(filename)\n    "
  },
  {
    "path": "scripts/Inductors/generator for normal packages found under SMD_chip_package_rlc-etc",
    "content": ""
  },
  {
    "path": "scripts/Inductors/vishay_IHSM.py",
    "content": "\"\"\"\nvishay IHSM series inductors\nhttp://www.vishay.com/docs/34018/ihsm3825.pdf\nhttp://www.vishay.com/docs/34019/ihsm4825.pdf\nhttp://www.vishay.com/docs/34020/ihsm5832.pdf\nhttp://www.vishay.com/docs/34021/ihsm7832.pdf\n\"\"\"\n\n#sizes,shapes,etc]\n#name, L, W, pad-w, pad-w, pad-gap, pad-h, datasheet\ninductors = [\n[3825, 11.18, 6.35, 4.6, 5.6, 5.08, \"http://www.vishay.com/docs/34018/ihsm3825.pdf\"],\n[4825, 13.72, 6.35, 4.6, 5.6, 7.62, \"http://www.vishay.com/docs/34019/ihsm4825.pdf\"],\n[5832, 16.26, 8.13, 6.6, 7.4, 8.763, \"http://www.vishay.com/docs/34020/ihsm5832.pdf\"],\n[7382, 21.34, 8.13, 6.6, 7.4, 13.462, \"http://www.vishay.com/docs/34021/ihsm7832.pdf\"]\n]\n\nimport sys\nimport os\n\noutput_dir = os.getcwd()\n\n#if specified as an argument, extract the target directory for output footprints\nif len(sys.argv) > 1:\n    out_dir = sys.argv[1]\n    \n    if os.path.isabs(out_dir) and os.path.isdir(out_dir):\n        output_dir = out_dir\n    else:\n        out_dir = os.path.join(os.getcwd(),out_dir)\n        if os.path.isdir(out_dir):\n            output_dir = out_dir\n\nif output_dir and not output_dir.endswith(os.sep):\n    output_dir += os.sep\n        \n#import KicadModTree files\nsys.path.append(\"..\\\\..\")\nfrom KicadModTree import *\nfrom KicadModTree.nodes.specialized.PadArray import PadArray\n\nprefix = \"Inductor_\"\npart = \"Vishay_IHSM-{pn}\"\ndims = \"{l:0.1f}mmx{w:0.1f}mm\"\n\ndesc = \"Inductor, Vishay, {pn}, {datasheet}\"\ntags = \"inductor vishay icsm smd\"\n\nfor inductor in inductors:\n    name,l,w,x,y,g,datasheet = inductor\n    \n    #pad center pos\n    c = g/2 + x/2\n    \n    fp_name = prefix + part.format(pn=str(name))\n    \n    fp = Footprint(fp_name)\n    \n    description = desc.format(pn = part.format(pn=str(name)), datasheet=datasheet) + \", \" + dims.format(l=l,w=w)\n    \n    fp.setTags(tags)\n    fp.setAttribute(\"smd\")\n    fp.setDescription(description)\n    \n    #add inductor courtyard\n    cx = max(l/2, (c+x/2))\n    cy = max(w/2, y/2)\n    \n    fp.append(RectLine(start=[-cx,-cy],end=[cx,cy],offset=0.35,width=0.05,grid=0.05,layer=\"F.CrtYd\"))\n\n    # set general values\n    fp.append(Text(type='reference', text='REF**', at=[0,-cy - 1], layer='F.SilkS'))\n    fp.append(Text(type='value', text=fp_name, at=[0,cy + 1.5], layer='F.Fab'))\n\n    \n    #calculate pad center\n    #pad-width pw\n    pw = x\n    \n    #add the component outline\n    fp.append(RectLine(start=[-l/2,-w/2],end=[l/2,w/2],layer='F.Fab',width=0.15))\n    \n    layers = [\"F.Cu\",\"F.Paste\",\"F.Mask\"]\n    \n    #add pads\n    fp.append(Pad(number=1,at=[-c,0],layers=layers,shape=Pad.SHAPE_RECT,type=Pad.TYPE_SMT,size=[x,y]))\n    fp.append(Pad(number=2,at=[c,0],layers=layers,shape=Pad.SHAPE_RECT,type=Pad.TYPE_SMT,size=[x,y]))\n    \n    poly = [\n        {'x': -l/2-0.1,'y': -y/2-0.3},\n        {'x': -l/2-0.1,'y': -w/2-0.1},\n        {'x': 0,'y': -w/2-0.1},\n    ]\n    \n    fp.append(PolygoneLine(polygone=poly))\n    fp.append(PolygoneLine(polygone=poly, x_mirror=0))\n    fp.append(PolygoneLine(polygone=poly, y_mirror=0))\n    fp.append(PolygoneLine(polygone=poly, x_mirror=0))\n    \n    #Add a model\n    fp.append(Model(filename=\"Inductors.3dshapes/\" + fp_name + \".wrl\"))\n    \n    #filename\n    filename = output_dir + fp_name + \".kicad_mod\"\n    \n    file_handler = KicadFileHandler(fp)\n    file_handler.writeFile(filename)\n    \n    print(fp_name)\n    "
  },
  {
    "path": "scripts/Inductors/we-hci.py",
    "content": "#http://katalog.we-online.com/en/pbs/WE-MAPI]\n\n#sizes,shapes,etc]\n#name, L, W, pad-w, pad-gap, pad-h\ninductors = [\n[5040,5.5,5.2,1.9,2.2,1.6],\n[7030,6.9,6.9,2.7,2.4,2.2],\n[7040,6.9,6.9,2.7,2.4,2.2],\n[7050,6.9,6.9,2.7,2.4,2.2],\n[1030,10.6,10.6,3.8,3.9,3.5],\n[1040,10.2,10.2,3.5,4.5,4],\n[1050,10.2,10.2,3.85,3.8,4],\n[1335,12.8,12.8,3.85,6.3,5],\n[1350,12.8,12.8,4.5,6,5],\n[1365,12.8,12.8,4.5,6,5],\n[2212,22.5,22.0,7,9.5,7],\n[1890,18.2,18.2,6,7.3,6],\n[1890,18.2,18.2,6,7.3,6],\n]\n\nimport sys\nimport os\n\noutput_dir = os.getcwd()\n\n#if specified as an argument, extract the target directory for output footprints\nif len(sys.argv) > 1:\n    out_dir = sys.argv[1]\n    \n    if os.path.isabs(out_dir) and os.path.isdir(out_dir):\n        output_dir = out_dir\n    else:\n        out_dir = os.path.join(os.getcwd(),out_dir)\n        if os.path.isdir(out_dir):\n            output_dir = out_dir\n\nif output_dir and not output_dir.endswith(os.sep):\n    output_dir += os.sep\n        \n#import KicadModTree files\nsys.path.append(\"..\\\\..\")\nfrom KicadModTree import *\nfrom KicadModTree.nodes.specialized.PadArray import PadArray\n\nprefix = \"Inductor_\"\npart = \"Wurth_HCI-{pn}\"\ndims = \"{l:0.1f}mmx{w:0.1f}mm\"\n\ndesc = \"Inductor, Wurth Elektronik, {pn}\"\ntags = \"inductor wurth hci smd\"\n\nfor inductor in inductors:\n    name,l,w,x,g,y = inductor\n    \n    fp_name = prefix + part.format(pn=str(name))\n    \n    fp = Footprint(fp_name)\n    \n    description = desc.format(pn = part.format(pn=str(name))) + \", \" + dims.format(l=l,w=w)\n    \n    fp.setTags(tags)\n    fp.setAttribute(\"smd\")\n    fp.setDescription(description)\n    \n    # set general values\n    fp.append(Text(type='reference', text='REF**', at=[0,-w/2 - 1], layer='F.SilkS'))\n    fp.append(Text(type='value', text=fp_name, at=[0,w/2 + 1.5], layer='F.Fab'))\n\n    #add inductor outline\n    fp.append(RectLine(start=[-l/2,-w/2],end=[l/2,w/2],layer='F.Fab',width=0.15))\n    \n    #calculate pad center\n    #pad-width pw\n    pw = x\n    c = g/2 + pw/2\n    \n    layers = [\"F.Cu\",\"F.Paste\",\"F.Mask\"]\n    \n    #add pads\n    fp.append(Pad(number=1,at=[-c,0],layers=layers,shape=Pad.SHAPE_RECT,type=Pad.TYPE_SMT,size=[pw,y]))\n    fp.append(Pad(number=2,at=[c,0],layers=layers,shape=Pad.SHAPE_RECT,type=Pad.TYPE_SMT,size=[pw,y]))\n    \n    #add inductor courtyard\n    cx = c + pw/2\n    cy = w / 2\n    \n    fp.append(RectLine(start=[-cx,-cy],end=[cx,cy],offset=0.3,width=0.05,grid=0.05,layer=\"F.CrtYd\"))\n    \n    offset = 0.1\n    ly = y/2 + 4 * offset\n    \n    x1 = l / 2 + offset\n    y1 = w / 2 + offset\n    \n    top = [\n    {'x': -x1, 'y': ly},\n    {'x': -x1, 'y': y1},\n    {'x':  x1, 'y': y1},\n    {'x':  x1, 'y': ly},\n    ]\n    \n    \n    fp.append(PolygoneLine(polygone=top))\n    fp.append(PolygoneLine(polygone=top,y_mirror=0))\n    \n    #Add a model\n    fp.append(Model(filename=\"Inductors.3dshapes/\" + fp_name + \".wrl\"))\n    \n    #filename\n    filename = output_dir + fp_name + \".kicad_mod\"\n    \n    file_handler = KicadFileHandler(fp)\n    file_handler.writeFile(filename)\n    "
  },
  {
    "path": "scripts/Inductors/we-hcm.py",
    "content": "#http://katalog.we-online.com/en/pbs/WE-MAPI]\n\n#sizes,shapes,etc]\n#name, L, W, pad-w, pad-gap, pad-h\ninductors = [\n[7050, 7.15, 7, 2, 3.3, 3.1],\n[7070, 7.4, 7.2, 2.55, 2.5, 2.2],\n[1050, 10.2, 7, 2, 6.35, 3.05],\n[1070, 10.1, 7, 3.6, 4, 2.6],\n[1078, 9.4, 6.2, 3.2, 4, 2.54],\n[1052, 10.5, 10.3, 2.45, 5.8, 2.7],\n[1190, 10.5, 11, 4, 4.2, 2.7],\n[1240, 10, 11.8, 2.6, 6.8, 4.5],\n[1350, 13.5, 13.3, 2.9, 8, 5.4],\n[1390, 12.5, 13, 2.5, 10, 5]\n]\n\nimport sys\nimport os\n\noutput_dir = os.getcwd()\n\n#if specified as an argument, extract the target directory for output footprints\nif len(sys.argv) > 1:\n    out_dir = sys.argv[1]\n    \n    if os.path.isabs(out_dir) and os.path.isdir(out_dir):\n        output_dir = out_dir\n    else:\n        out_dir = os.path.join(os.getcwd(),out_dir)\n        if os.path.isdir(out_dir):\n            output_dir = out_dir\n\nif output_dir and not output_dir.endswith(os.sep):\n    output_dir += os.sep\n        \n#import KicadModTree files\nsys.path.append(\"..\\\\..\")\nfrom KicadModTree import *\nfrom KicadModTree.nodes.specialized.PadArray import PadArray\n\nprefix = \"Inductor_\"\npart = \"Wurth_HCM-{pn}\"\ndims = \"{l:0.1f}mmx{w:0.1f}mm\"\n\ndesc = \"Inductor, Wurth Elektronik, {pn}\"\ntags = \"inductor wurth hcm smd\"\n\nfor inductor in inductors:\n    name,l,w,x,g,y = inductor\n    \n    #pad center pos\n    c = g/2 + x/2\n    \n    fp_name = prefix + part.format(pn=str(name))\n    \n    fp = Footprint(fp_name)\n    \n    description = desc.format(pn = part.format(pn=str(name))) + \", \" + dims.format(l=l,w=w)\n    \n    fp.setTags(tags)\n    fp.setAttribute(\"smd\")\n    fp.setDescription(description)\n    \n    #add inductor courtyard\n    cx = max(l/2, (c+x/2))\n    cy = max(w/2, y/2)\n    \n    fp.append(RectLine(start=[-cx,-cy],end=[cx,cy],offset=0.35,width=0.05,grid=0.05,layer=\"F.CrtYd\"))\n\n    # set general values\n    fp.append(Text(type='reference', text='REF**', at=[0,-cy - 1], layer='F.SilkS'))\n    fp.append(Text(type='value', text=fp_name, at=[0,cy + 1.5], layer='F.Fab'))\n\n    \n    #calculate pad center\n    #pad-width pw\n    pw = x\n    \n    #add the component outline\n    fp.append(RectLine(start=[-l/2,-w/2],end=[l/2,w/2],layer='F.Fab',width=0.15))\n    \n    layers = [\"F.Cu\",\"F.Paste\",\"F.Mask\"]\n    \n    #add pads\n    fp.append(Pad(number=1,at=[-c,0],layers=layers,shape=Pad.SHAPE_RECT,type=Pad.TYPE_SMT,size=[x,y]))\n    fp.append(Pad(number=2,at=[c,0],layers=layers,shape=Pad.SHAPE_RECT,type=Pad.TYPE_SMT,size=[x,y]))\n    \n    poly = [\n        {'x': -l/2-0.1,'y': -y/2-0.3},\n        {'x': -l/2-0.1,'y': -w/2-0.1},\n        {'x': 0,'y': -w/2-0.1},\n    ]\n    \n    fp.append(PolygoneLine(polygone=poly))\n    fp.append(PolygoneLine(polygone=poly, x_mirror=0))\n    fp.append(PolygoneLine(polygone=poly, y_mirror=0))\n    fp.append(PolygoneLine(polygone=poly, x_mirror=0))\n    \n    #Add a model\n    fp.append(Model(filename=\"Inductors.3dshapes/\" + fp_name + \".wrl\"))\n    \n    #filename\n    filename = output_dir + fp_name + \".kicad_mod\"\n    \n    file_handler = KicadFileHandler(fp)\n    file_handler.writeFile(filename)\n    \n    print(fp_name)\n    "
  },
  {
    "path": "scripts/Inductors/we-mapi.py",
    "content": "#http://katalog.we-online.com/en/pbs/WE-MAPI]\n\n#sizes,shapes,etc]\n#name, L, W, pad-w, pad-gap, pad-h\ninductors = [\n[1610,1.6,1.6,1.8,0.4,1.8],\n[2010,2.0,1.6,2.3,0.6,1.9],\n[2506,2.5,2.0,2.8,1.1,2.3],\n[2508,2.5,2.0,2.8,1.1,2.3],\n[2510,2.5,2.0,2.8,1.1,2.3],\n[2512,2.5,2.0,2.8,1.1,2.3],\n[3010,3.0,3.0,3.4,0.8,3.4],\n[3012,3.0,3.0,3.4,0.8,3.4],\n[3015,3.0,3.0,3.4,0.8,3.4],\n[3020,3.0,3.0,3.5,0.8,3.4],\n[4020,4.0,4.0,3.35,1.39,3.7],\n]\n\nimport sys\nimport os\n\noutput_dir = os.getcwd()\n\n#if specified as an argument, extract the target directory for output footprints\nif len(sys.argv) > 1:\n    out_dir = sys.argv[1]\n    \n    if os.path.isabs(out_dir) and os.path.isdir(out_dir):\n        output_dir = out_dir\n    else:\n        out_dir = os.path.join(os.getcwd(),out_dir)\n        if os.path.isdir(out_dir):\n            output_dir = out_dir\n\nif output_dir and not output_dir.endswith(os.sep):\n    output_dir += os.sep\n        \n#import KicadModTree files\nsys.path.append(\"..\\\\..\")\nfrom KicadModTree import *\nfrom KicadModTree.nodes.specialized.PadArray import PadArray\n\nprefix = \"Inductor_\"\npart = \"Wurth_MAPI-{pn}\"\ndims = \"{l:0.1f}mmx{w:0.1f}mm\"\n\ndesc = \"Inductor, Wurth Elektronik, {pn}\"\ntags = \"inductor wurth smd\"\n\nfor inductor in inductors:\n    name,l,w,x,g,y = inductor\n    \n    fp_name = prefix + part.format(pn=str(name))\n    \n    fp = Footprint(fp_name)\n    \n    description = desc.format(pn = part.format(pn=str(name))) + \", \" + dims.format(l=l,w=w)\n    \n    fp.setTags(tags)\n    fp.setAttribute(\"smd\")\n    fp.setDescription(description)\n    \n    # set general values\n    fp.append(Text(type='reference', text='REF**', at=[0,-y/2 - 1], layer='F.SilkS'))\n    fp.append(Text(type='value', text=fp_name, at=[0,y/2 + 1.5], layer='F.Fab'))\n    \n    #calculate pad center\n    #pad-width pw\n    pw = (x-g) / 2\n    c = g/2 + pw/2\n    \n    #add the component outline\n    fp.append(RectLine(start=[-l/2,-w/2],end=[l/2,w/2],layer='F.Fab',width=0.15))\n    \n    layers = [\"F.Cu\",\"F.Paste\",\"F.Mask\"]\n    \n    #add pads\n    fp.append(Pad(number=1,at=[-c,0],layers=layers,shape=Pad.SHAPE_RECT,type=Pad.TYPE_SMT,size=[pw,y]))\n    fp.append(Pad(number=2,at=[c,0],layers=layers,shape=Pad.SHAPE_RECT,type=Pad.TYPE_SMT,size=[pw,y]))\n    \n    #add inductor courtyard\n    cx = c + pw/2\n    cy = y / 2\n    \n    fp.append(RectLine(start=[-cx,-cy],end=[cx,cy],offset=0.35,width=0.05,grid=0.05,layer=\"F.CrtYd\"))\n    \n    #add lines\n    fp.append(Line(start=[-g/2+0.2,-w/2-0.1],end=[g/2-0.2,-w/2-0.1]))\n    fp.append(Line(start=[-g/2+0.2,w/2+0.1],end=[g/2-0.2,w/2+0.1]))\n    \n    #Add a model\n    fp.append(Model(filename=\"Inductors.3dshapes/\" + fp_name + \".wrl\"))\n    \n    #filename\n    filename = output_dir + fp_name + \".kicad_mod\"\n    \n    file_handler = KicadFileHandler(fp)\n    file_handler.writeFile(filename)\n    "
  },
  {
    "path": "scripts/LEDs_SMD/generator for normal packages  found under SMD_chip_package_rlc-etc",
    "content": ""
  },
  {
    "path": "scripts/LEDs_SMD/plcc4.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))\n\nfrom KicadModTree import *\n\ndef plcc4(args):\n    footprint_name = args[\"name\"]\n\n    pkgWidth = args[\"pkg_width\"]\n    pkgHeight = args[\"pkg_height\"]\n\n    padXSpacing = args[\"pad_x_spacing\"]\n    padYSpacing = args[\"pad_y_spacing\"]\n\n    padWidth = args[\"pad_width\"]\n    padHeight = args[\"pad_height\"]\n\n    pads_clockwise = args[\"pads_clockwise\"]\n\n    desc = str(pkgWidth) + \"mm x \" + str(pkgHeight) + \"mm PLCC4 LED, \"\n\n    f = Footprint(footprint_name)\n    f.setDescription(desc + args[\"datasheet\"])\n    f.setTags(\"LED Cree PLCC-4\")\n    f.setAttribute(\"smd\")\n    f.append(Model(filename=\"${KISYS3DMOD}/LEDs.3dshapes/\" + footprint_name + \".wrl\",\n                   at=[0.0, 0.0, 0.0],\n                   scale=[1.0, 1.0, 1.0],\n                   rotate=[0.0, 0.0, 0.0]))\n\n    p = [padWidth, padHeight]\n    r = pkgHeight * 0.4\n    s = [1.0, 1.0]\n    sFabRef = [0.5, 0.5]\n\n    t1 = 0.075\n    t2 = 0.15\n\n    wCrtYd = 0.05\n    wFab = 0.1\n    wSilkS = 0.12\n    crtYd = 0.25\n    silkClearance = 0.2\n\n    xCenter = 0.0\n    xPadRight = padXSpacing / 2\n    xFabRight = pkgWidth / 2\n    xSilkRight = xPadRight + padWidth / 2 + silkClearance\n    xRightCrtYd = xSilkRight + crtYd\n\n    xLeftCrtYd = -xRightCrtYd\n    xSilkLeft = -xSilkRight\n    xPadLeft = -xPadRight\n    xFabLeft = -xFabRight\n    xChamfer = xFabLeft + 1.0\n\n    yCenter = 0.0\n    yPadBottom = padYSpacing / 2\n    yFabBottom = pkgHeight / 2\n    ySilkBottom = max(yFabBottom + 0.1,\n                      yPadBottom + padHeight / 2 + silkClearance)\n    yBottomCrtYd = ySilkBottom + crtYd\n\n    yTopCrtYd = -yBottomCrtYd\n    ySilkTop = -ySilkBottom\n    yFabTop = -yFabBottom\n    yPadTop = -yPadBottom\n    yChamfer = yFabTop + 1\n\n    yValue = yFabBottom + 1.25\n    yRef = yFabTop - 1.25\n\n    f.append(Text(type=\"reference\", text=\"REF**\", at=[xCenter, yRef],\n                  layer=\"F.SilkS\", size=s, thickness=t2))\n    f.append(Text(type=\"value\", text=footprint_name, at=[xCenter, yValue],\n                  layer=\"F.Fab\", size=s, thickness=t2))\n    f.append(Text(type=\"user\", text=\"%R\", at=[xCenter, yCenter],\n                  layer=\"F.Fab\", size=sFabRef, thickness=t1))\n\n    f.append(RectLine(start=[xLeftCrtYd, yTopCrtYd],\n                      end=[xRightCrtYd, yBottomCrtYd],\n                      layer=\"F.CrtYd\", width=wCrtYd))\n\n    f.append(Line(start=[xChamfer, yFabTop],\n                  end=[xFabLeft, yChamfer],\n                  layer=\"F.Fab\", width=wFab))\n    f.append(RectLine(start=[xFabLeft, yFabTop],\n                      end=[xFabRight, yFabBottom],\n                      layer=\"F.Fab\", width=wFab))\n    f.append(Circle(center=[xCenter, yCenter], radius=r,\n                    layer=\"F.Fab\", width=wFab))\n\n    f.append(PolygoneLine(polygone=[[xSilkLeft, yPadTop],\n                                    [xSilkLeft, ySilkTop],\n                                    [xSilkRight, ySilkTop]],\n                          layer=\"F.SilkS\", width=wSilkS))\n    f.append(Line(start=[xSilkLeft, ySilkBottom],\n                  end=[xSilkRight, ySilkBottom],\n                  layer=\"F.SilkS\", width=wSilkS))\n\n    if pads_clockwise:\n        pads = [\"1\", \"2\", \"3\", \"4\"]\n    else:\n        pads = [\"1\", \"4\", \"3\", \"2\"]\n\n    f.append(Pad(number=pads[0], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                 at=[xPadLeft, yPadTop], size=p, layers=Pad.LAYERS_SMT))\n    f.append(Pad(number=pads[1], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                 at=[xPadRight, yPadTop], size=p, layers=Pad.LAYERS_SMT))\n    f.append(Pad(number=pads[2], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                 at=[xPadRight, yPadBottom], size=p, layers=Pad.LAYERS_SMT))\n    f.append(Pad(number=pads[3], type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                 at=[xPadLeft, yPadBottom], size=p, layers=Pad.LAYERS_SMT))\n\n    file_handler = KicadFileHandler(f)\n    file_handler.writeFile(footprint_name + \".kicad_mod\")\n\n\nif __name__ == '__main__':\n    parser = ModArgparser(plcc4)\n    # the root node of .yml files is parsed as name\n    parser.add_parameter(\"name\", type=str, required=True)\n    parser.add_parameter(\"datasheet\", type=str, required=True)\n    parser.add_parameter(\"pkg_width\", type=float, required=False, default=2.0)\n    parser.add_parameter(\"pkg_height\", type=float, required=False, default=2.0)\n    parser.add_parameter(\"pad_x_spacing\", type=float, required=False, default=1.5)\n    parser.add_parameter(\"pad_y_spacing\", type=float, required=False, default=1.1)\n    parser.add_parameter(\"pad_width\", type=float, required=False, default=1.0)\n    parser.add_parameter(\"pad_height\", type=float, required=False, default=0.8)\n    parser.add_parameter(\"pads_clockwise\", type=bool, required=False, default=True)\n\n    # now run our script which handles the whole part of parsing the files\n    parser.run()\n"
  },
  {
    "path": "scripts/LEDs_SMD/plcc4.yml",
    "content": "LED_Cree-PLCC4_2x2mm_CW:\n  datasheet: http://www.cree.com/~/media/Files/Cree/LED-Components-and-Modules/HB/Data-Sheets/CLMVBFKA.pdf\n  pkg_width: 2.0\n  pkg_height: 2.0\n  pad_x_spacing: 1.5\n  pad_y_spacing: 1.1\n  pad_width: 1.0\n  pad_height: 0.8\n  pads_clockwise: true\nLED_Cree-PLCC4_3.2x2.8mm_CCW:\n  datasheet: http://www.cree.com/led-components/media/documents/CLV1AFKB(874).pdf\n  pkg_width: 3.2\n  pkg_height: 2.8\n  pad_x_spacing: 2.5\n  pad_y_spacing: 1.4\n  pad_width: 1.0\n  pad_height: 0.8\n  pads_clockwise: false\n"
  },
  {
    "path": "scripts/LEDs_SMD/smlvn6.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))\n\nfrom KicadModTree import *\n\ndatasheet = \"https://www.rohm.com/datasheet/SMLVN6RGB1U\"\nfootprint_name = \"LED_ROHM_SMLVN6\"\npkgWidth = 3.1\npkgHeight = 2.8\npadXSpacing = 3.05\npadYSpacing = 1.05\npadWidth = 1.45\npadHeight = 0.6\npadCornerHeight = 0.8\n\nf = Footprint(footprint_name)\nf.setDescription(datasheet)\nf.setTags(\"LED ROHM SMLVN6\")\nf.setAttribute(\"smd\")\nf.append(Model(filename=\"${KISYS3DMOD}/LED_SMD.3dshapes/\" + footprint_name + \".wrl\",\n               at=[0.0, 0.0, 0.0],\n               scale=[1.0, 1.0, 1.0],\n               rotate=[0.0, 0.0, 0.0]))\n\np = [padWidth, padHeight]\npCorner = [padWidth, padCornerHeight]\ns = [1.0, 1.0]\nsFabRef = [0.7, 0.7]\n\nt1 = 0.1\nt2 = 0.15\n\nwCrtYd = 0.05\nwFab = 0.1\nwSilkS = 0.12\ncrtYd = 0.3\nsilkClearance = 0.2\n\nxCenter = 0.0\nxPadRight = padXSpacing / 2\nxFabRight = pkgWidth / 2\nxSilkRight = xPadRight\nxRightCrtYd = max(xPadRight + padWidth / 2, xFabRight) + crtYd\n\nxLeftCrtYd = - xRightCrtYd\nxPadLeft = -xPadRight\nxFabLeft = -xFabRight\nxChamfer = xFabLeft + 1.0\nxSilkTopLeft = -xSilkRight - (padWidth / 2) + (wSilkS / 2)\nxSilkBottomLeft = -xSilkRight\n\nyCenter = 0.0\nyPadBottom = padYSpacing\nyFabBottom = pkgHeight / 2\nyBottom = max(yFabBottom + 0.1, yPadBottom + padHeight / 2)\nySilkBottom = yBottom + silkClearance\nyBottomCrtYd = yBottom + crtYd\n\nyTopCrtYd = -yBottomCrtYd\nySilkTop = -ySilkBottom\nyFabTop = -yFabBottom\nyPadTop = -yPadBottom\nyChamfer = yFabTop + 1\n\nyValue = yFabBottom + 1.25\nyRef = yFabTop - 1.25\n\nf.append(Text(type=\"reference\", text=\"REF**\", at=[xCenter, yRef],\n              layer=\"F.SilkS\", size=s, thickness=t2))\nf.append(Text(type=\"value\", text=footprint_name, at=[xCenter, yValue],\n              layer=\"F.Fab\", size=s, thickness=t2))\nf.append(Text(type=\"user\", text=\"%R\", at=[xCenter, yCenter],\n              layer=\"F.Fab\", size=sFabRef, thickness=t1))\n\nf.append(RectLine(start=[xLeftCrtYd, yTopCrtYd],\n                  end=[xRightCrtYd, yBottomCrtYd],\n                  layer=\"F.CrtYd\", width=wCrtYd))\n\nf.append(PolygoneLine(polygone=[[xFabLeft, yChamfer],\n                                [xChamfer, yFabTop],\n                                [xFabRight, yFabTop],\n                                [xFabRight, yFabBottom],\n                                [xFabLeft, yFabBottom],\n                                [xFabLeft, yChamfer]],\n                      layer=\"F.Fab\", width=wFab))\n\nf.append(Line(start=[xSilkTopLeft, ySilkTop],\n              end=[xSilkRight, ySilkTop],\n              layer=\"F.SilkS\", width=wSilkS))\nf.append(Line(start=[xSilkBottomLeft, ySilkBottom],\n              end=[xSilkRight, ySilkBottom],\n              layer=\"F.SilkS\", width=wSilkS))\n\npads = [\"1\", \"6\", \"2\", \"5\", \"3\", \"4\"]\npadShape = Pad.SHAPE_ROUNDRECT\nradiusRatio = 0.2\n\nf.append(Pad(number=pads[0], type=Pad.TYPE_SMT, shape=padShape,\n             at=[xPadLeft, yPadTop], size=pCorner, layers=Pad.LAYERS_SMT,\n             radius_ratio=radiusRatio))\nf.append(Pad(number=pads[1], type=Pad.TYPE_SMT, shape=padShape,\n             at=[xPadRight, yPadTop], size=pCorner, layers=Pad.LAYERS_SMT,\n             radius_ratio=radiusRatio))\nf.append(Pad(number=pads[2], type=Pad.TYPE_SMT, shape=padShape,\n             at=[xPadLeft, yCenter], size=p, layers=Pad.LAYERS_SMT,\n             radius_ratio=radiusRatio))\nf.append(Pad(number=pads[3], type=Pad.TYPE_SMT, shape=padShape,\n             at=[xPadRight, yCenter], size=p, layers=Pad.LAYERS_SMT,\n             radius_ratio=radiusRatio))\nf.append(Pad(number=pads[4], type=Pad.TYPE_SMT, shape=padShape,\n             at=[xPadLeft, yPadBottom], size=pCorner, layers=Pad.LAYERS_SMT,\n             radius_ratio=radiusRatio))\nf.append(Pad(number=pads[5], type=Pad.TYPE_SMT, shape=padShape,\n             at=[xPadRight, yPadBottom], size=pCorner, layers=Pad.LAYERS_SMT,\n             radius_ratio=radiusRatio))\n\nfile_handler = KicadFileHandler(f)\nfile_handler.writeFile(footprint_name + \".kicad_mod\")\n"
  },
  {
    "path": "scripts/LEDs_THT/make_LEDs_THT.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom drawing_tools import *\nfrom footprint_scripts_LEDs import *\n\n\nif __name__ == '__main__':\n    # standard resistors: http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf\n    type = \"round\"\n    script3d_rv=\"leds_round_ver.py\"\n    with open(script3d_rv, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_rh=\"leds_round_hor.py\"\n    with open(script3d_rh, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_reh=\"leds_rect_hor.py\"\n    with open(script3d_reh, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_rreh=\"leds_rect_round_hor.py\"\n    with open(script3d_rreh, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n\n    d2=0\n    R_POW = 0\n    clname=\"LED\"\n    lbname=\"LEDs\"\n    ddrill = 0.9\n\n    type=\"round\"; pins=2;\n    rm=2.54; rin=3; w=3.8; h=w; height3d=4.3; height3d_bottom=1; name_additions=[]; specialtags=[]; add_description=\"\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname, lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    pins = 3; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-3VSURKCGKC(Ver.8A).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname, lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    pins=2; rm=2.54; rin=5; w=5.8; h=w; height3d=7.6; height3d_bottom=1; name_additions=[]; specialtags=[]; add_description=\"http://cdn-reichelt.de/documents/datenblatt/A500/LL-504BC2E-009.pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname, lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    pins = 3; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-59EGC(Ver.17A).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname, lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    pins = 4; rm=1.27; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-154A4SUREQBFZGEW(Ver.9A).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname, lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    pins=2; rm=2.54; rin=4; w=4.8; h=w; height3d=6; height3d_bottom=1; name_additions=[]; specialtags=[]; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-43GD(Ver.12B).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname, lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    pins=2; rm=2.54; rin=8; w=9; h=w; height3d=9; height3d_bottom=2; name_additions=[]; specialtags=[]; add_description=\"http://cdn-reichelt.de/documents/datenblatt/A500/LED8MMGE_LED8MMGN_LED8MMRT%23KIN.pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname, lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    pins = 3; add_description=\"\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname, lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    pins=2; rm=2.54; rin=10; w=11; h=w; height3d=11.5; height3d_bottom=2; name_additions=[]; specialtags=[]; add_description=\"http://cdn-reichelt.de/documents/datenblatt/A500/LED10-4500RT%23KIN.pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname, lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    pins = 3; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-819EGW(Ver.14A).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname, lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    pins=2; rm=2.54; rin=20; w=23; h=w; height3d=10; height3d_bottom=3.5; name_additions=[]; specialtags=[]; add_description=\"http://cdn-reichelt.de/documents/datenblatt/A500/DLC2-6GD%28V6%29.pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname, lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"oval\"; pins=2; rm=2.54; rin=0; w=5.2; h=3.8; height3d=7; height3d_bottom=0; name_additions=[]; specialtags=[\"Oval\"]; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-5603QBC-D(Ver.12B).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"_Oval\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"box\"; pins=2; rm=2.54; rin=2; w=4.8; h=2.5; height3d=4.5; height3d_bottom=3.5; name_additions=[\"FlatTop\"]; specialtags=[\"Round\", \"FlatTop\"]; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-13GD(Ver.11B).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"box\"; pins=2; rm=2.54; rin=1.8; w=3.3; h=2.4; height3d=1.4; height3d_bottom=1.6; name_additions=[]; specialtags=[\"Round\"]; add_description=\"\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"round\"; pins=2; rm=2.54; rin=3; w=3.8; h=w; height3d=4.8; height3d_bottom=6-4.8; name_additions=[\"FlatTop\"]; specialtags=[\"Round\",\"FlatTop\"]; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-47XEC(Ver.9A).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"round\"; pins=2; rm=2.54; rin=5; w=5.9; h=w; height3d=8.6; height3d_bottom=1; name_additions=[\"FlatTop\"]; specialtags=[\"Round\",\"FlatTop\"]; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-483GDT(Ver.15B).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"box\"; pins=2; rm=2.54; rin=2; w=4; h=2.8; height3d=1.95; height3d_bottom=5-1.95; name_additions=[\"FlatTop\"]; specialtags=[\"Round\",\"FlatTop\"]; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-1034IDT(Ver.9A).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"box\"; pins=2; rm=2.54; rin=0; w=3.9; h=1.75; height3d=7; height3d_bottom=0; name_additions=[\"FlatTop\"]; specialtags=[\"Rectangular\"]; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-2774GD(Ver.7B).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"_Rectangular\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"box\"; pins=2; rm=2.54; rin=0; w=3.9; h=1.9; height3d=7; height3d_bottom=0; name_additions=[]; specialtags=[\"Rectangular\"]; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-144GDT(Ver.14B).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"_Rectangular\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"box\"; pins=2; rm=2.54; rin=0; w=3; h=2;  height3d=7; height3d_bottom=0; name_additions=[]; specialtags=[\"Rectangular\"]; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-169XCGDK(Ver.9B).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"_Rectangular\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"box\"; pins=2; rm=2.54; rin=0; w=5; h=2;  height3d=9.7; height3d_bottom=0; name_additions=[]; specialtags=[\"Rectangular\"]; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-169XCGDK(Ver.9B).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"_Rectangular\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"box\"; pins=3; rm=2.54; rin=0; w=5; h=2;  height3d=9.7; height3d_bottom=0; name_additions=[]; specialtags=[\"Rectangular\"]; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-169XCGDK(Ver.9B).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"_Rectangular\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"box\"; pins=2; rm=2.54; rin=0; w=5; h=5;  height3d=9.7; height3d_bottom=0; name_additions=[]; specialtags=[\"Rectangular\"]; add_description=\"http://www.kingbright.com/attachments/file/psearch/000/00/00/L-169XCGDK(Ver.9B).pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"_Rectangular\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"box\"; pins=2; rm=2.54; rin=0; w=4.5; h=1.6;  height3d=5.7; height3d_bottom=0; name_additions=[]; specialtags=[\"Rectangular\",\"SideEmitter\"]; add_description=\"http://cdn-reichelt.de/documents/datenblatt/A500/LED15MMGE_LED15MMGN%23KIN.pdf\"\n    makeLEDRadial(pins=pins, rm=rm, w=w, h=h, ddrill=ddrill, rin=rin, type=type, x_3d=[0, 0, 0], s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags, add_description=add_description, classname=clname+\"_SideEmitter_Rectangular\", lib_name=lbname,name_additions=name_additions, script3d=script3d_rv, height3d=height3d, height3d_bottom=height3d_bottom)\n    type=\"round\"; pins=2; rm=2.54; dled=3; dledout=3.8; offset=2.54;wled=5.3; height3d=3; name_additions=[]; specialtags=[]; add_description=\"\"\n    \n    offsets=[1.27,3.81,6.35]\n    for ledypos in [2,6,10]:\n        for offset in offsets:\n            makeLEDHorizontal(ledypos=ledypos, pins=pins, rm=rm, ddrill=ddrill,dled=dled, dledout=dledout, offsetled=offset, wled=wled, type=type, x_3d=[0, 0, 0],s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags,add_description=add_description,classname=clname, lib_name=lbname, name_additions=name_additions, script3d=script3d_rh, height3d=height3d)\n    type=\"round\"; pins=2; rm=2.54; dled=5; dledout=5.8; offset=2.54;wled=8.6; height3d=5; name_additions=[]; specialtags=[]; add_description=\"\"\n    for ledypos in [3,9,15]:\n        for offset in offsets:\n            makeLEDHorizontal(ledypos=ledypos, pins=pins, rm=rm, ddrill=ddrill,dled=dled, dledout=dledout, offsetled=offset, wled=wled, type=type, x_3d=[0, 0, 0],s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags,add_description=add_description,classname=clname, lib_name=lbname, name_additions=name_additions, script3d=script3d_rh, height3d=height3d)\n    type=\"box\"; pins=2; rm=2.54; dled=1.8; dledout=3.3; wled=3; wledback=1.6; height3d=2.4; height3d_bottom=1.6; name_additions=[]; specialtags=[\"\"]; add_description=\"\"\n    for ledypos in [1.65, 1.65+3.3, 1.65+3.3*2]:\n        for offset in offsets:\n            makeLEDHorizontal(ledypos=ledypos, pins=pins, rm=rm, ddrill=ddrill,dled=dled, dledout=dledout, wledback=wledback, offsetled=offset, wled=wled, type=type, x_3d=[0, 0, 0],s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags,add_description=add_description,classname=clname+\"\", lib_name=lbname, name_additions=name_additions, script3d=script3d_rreh, height3d=height3d)\n    type=\"box\"; pins=2; rm=2.54; dled=5; dledout=5; wled=9.7; wledback=0; height3d=2; height3d_bottom=1.6; name_additions=[]; specialtags=[\"Rectangular\"]; add_description=\"\"\n    for ledypos in [1, 3, 5]:\n        for offset in offsets:\n            makeLEDHorizontal(ledypos=ledypos, pins=pins, rm=rm, ddrill=ddrill,dled=dled, dledout=dledout, wledback=wledback, offsetled=offset, wled=wled, type=type, x_3d=[0, 0, 0],s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=specialtags,add_description=add_description,classname=clname+\"_Rectangular\", lib_name=lbname, name_additions=name_additions, script3d=script3d_reh, height3d=height3d)\n\n    "
  },
  {
    "path": "scripts/Mounting_Hardware/mounting_hole.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport argparse\nimport yaml\nimport math\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load parent path of KicadModTree\n\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\n\n\n# https://stackoverflow.com/questions/4265546/python-round-to-nearest-05\ndef round_to(n, precision):\n    correction = 0.5 if n >= 0 else -0.5\n    return int(n/precision+correction) * precision\n\n\ndef create_footprint(name, **kwargs):\n    kicad_mod = Footprint(name)\n\n    # init kicad footprint\n    kicad_mod.setDescription(kwargs['description'])\n    kicad_mod.setTags('Mounting Hole')\n\n    # load some general values\n    hole_x = float(kwargs['hole_x'])\n    hole_y = float(kwargs['hole_y'])\n    anular_ring = float(kwargs['anular_ring'])\n    courtjard = float(kwargs['courtjard'])\n    create_via = kwargs['via']\n\n    pad_x = hole_x + 2*anular_ring\n    pad_y = hole_y + 2*anular_ring\n    courtjard_x = pad_x + 2*courtjard\n    courtjard_y = pad_y + 2*courtjard\n\n    # set general values\n    kicad_mod.append(Text(type='reference', text='REF**', at=[0, -courtjard_y/2 - 0.75], layer='F.SilkS'))\n    kicad_mod.append(Text(type='value', text=name, at=[0, courtjard_y/2 + 0.75], layer='F.Fab'))\n\n    # create courtyard\n    if hole_x == hole_y:\n        kicad_mod.append(Circle(center=[0, 0], radius=courtjard_x/2., layer='F.CrtYd'))\n    elif hole_x > hole_y:\n        courtjard_length_x = courtjard_x - courtjard_y\n        kicad_mod.append(RectLine(start=[courtjard_length_x / 2, courtjard_y / 2], end=[-courtjard_length_x / 2, courtjard_y / 2],\n                                  layer='F.CrtYd'))\n        kicad_mod.append(RectLine(start=[courtjard_length_x / 2, -courtjard_y / 2], end=[-courtjard_length_x / 2, -courtjard_y / 2],\n                     layer='F.CrtYd'))\n        kicad_mod.append(Arc(center=[courtjard_length_x/2 , 0], start=[courtjard_length_x / 2, -courtjard_y / 2], angle=180, layer='F.CrtYd'))\n        kicad_mod.append(Arc(center=[-courtjard_length_x / 2, 0], start=[-courtjard_length_x / 2, courtjard_y / 2], angle=180, layer='F.CrtYd'))\n    else: # hole_x < hole_y\n        courtjard_length_y = courtjard_y - courtjard_x\n        kicad_mod.append(\n            RectLine(start=[courtjard_x / 2, courtjard_length_y / 2], end=[courtjard_x / 2, -courtjard_length_y / 2],\n                     layer='F.CrtYd'))\n        kicad_mod.append(\n            RectLine(start=[-courtjard_x / 2, courtjard_length_y / 2], end=[-courtjard_x / 2, -courtjard_length_y / 2],\n                     layer='F.CrtYd'))\n        kicad_mod.append(\n            Arc(center=[0, courtjard_length_y / 2], start=[courtjard_x / 2, courtjard_length_y / 2], angle=180,\n                layer='F.CrtYd'))\n        kicad_mod.append(\n            Arc(center=[0, -courtjard_length_y / 2], start=[-courtjard_x / 2, -courtjard_length_y / 2], angle=180,\n                layer='F.CrtYd'))\n\n    # create pads\n    pad_kwargs = {\n        'number': 1,\n        'type': Pad.TYPE_THT,\n        'at': [0, 0],\n        'size': [pad_x, pad_y],\n        'layers': ['*.Cu', '*.Mask']\n    }\n    if hole_x == hole_y:\n        kicad_mod.append(Pad(**pad_kwargs, shape=Pad.SHAPE_CIRCLE, drill=hole_x))\n    else:\n        kicad_mod.append(Pad(**pad_kwargs, shape=Pad.SHAPE_OVAL, drill=[hole_x, hole_y]))\n\n    # create via's\n    if create_via:\n        via_count = int(kwargs['via_count'])\n        via_diameter = float(kwargs['via_diameter'])\n        x_size = hole_x + anular_ring\n        y_size = hole_y + anular_ring\n\n        circle_radius = min(x_size, y_size) / 2\n        circle_scope = min(x_size, y_size) * math.pi\n\n        if hole_x > hole_y:\n            line_scope_x = 2 * (x_size - y_size)\n            line_scope_y = 0\n        else:\n            line_scope_x = 0\n            line_scope_y = 2 * (y_size - x_size)\n        line_scope = line_scope_x + line_scope_y\n        vias_scope = circle_scope + line_scope\n\n        for step in range(via_count):\n            scope_step = (vias_scope / via_count * step - line_scope_y / 4 + vias_scope) % vias_scope # align on right center\n\n            if scope_step <= circle_scope / 4:\n                local_scope_pos = scope_step\n                circle_pos = local_scope_pos / circle_scope * 2 * math.pi\n                step_x = math.cos(circle_pos) * circle_radius + line_scope_x / 4\n                step_y = math.sin(circle_pos) * circle_radius + line_scope_y / 4\n            elif scope_step <= circle_scope / 4 + line_scope_x / 2:\n                local_scope_pos = scope_step - circle_scope / 4\n                step_x = line_scope_x / 4 - local_scope_pos\n                step_y = y_size / 2\n            elif scope_step <= circle_scope / 2 + line_scope_x / 2:\n                local_scope_pos = scope_step - line_scope_x / 2  # angle of circle already included\n                circle_pos = local_scope_pos / circle_scope * 2 * math.pi\n                step_x = math.cos(circle_pos) * circle_radius - line_scope_x / 4\n                step_y = math.sin(circle_pos) * circle_radius + line_scope_y / 4\n            elif scope_step <= circle_scope / 2 + line_scope_x / 2 + line_scope_y / 2:\n                local_scope_pos = scope_step - circle_scope / 2 - line_scope_x / 2\n                step_x = -x_size / 2\n                step_y = line_scope_y / 4 - local_scope_pos\n            elif scope_step <= 3 * circle_scope / 4 + line_scope_x / 2 + line_scope_y / 2:\n                local_scope_pos = scope_step - line_scope_x / 2 -  line_scope_y / 2 # angle of circle already included\n                circle_pos = local_scope_pos / circle_scope * 2 * math.pi\n                step_x = math.cos(circle_pos) * circle_radius - line_scope_x / 4\n                step_y = math.sin(circle_pos) * circle_radius - line_scope_y / 4\n            elif scope_step <= 3 * circle_scope / 4 + line_scope_x + line_scope_y / 2:\n                local_scope_pos = scope_step - 3 * circle_scope / 4 - line_scope_x / 2 - line_scope_y / 2\n                step_x = -line_scope_x / 4 + local_scope_pos\n                step_y = -y_size / 2\n            elif scope_step <= circle_scope + line_scope_x + line_scope_y / 2:\n                local_scope_pos = scope_step - line_scope_x - line_scope_y / 2  # angle of circle already included\n                circle_pos = local_scope_pos / circle_scope * 2 * math.pi\n                step_x = math.cos(circle_pos) * circle_radius + line_scope_x / 4\n                step_y = math.sin(circle_pos) * circle_radius - line_scope_y / 4\n            elif scope_step < circle_scope + line_scope_x + line_scope_y:\n                local_scope_pos = scope_step - circle_scope - line_scope_x - line_scope_y / 2\n                step_x = x_size / 2\n                step_y = -line_scope_y / 4 + local_scope_pos\n            else: # error\n                raise \"invalid scope_step\"\n\n            kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n                                 at=[step_x, step_y], size=[via_diameter+0.1, via_diameter+0.1], drill=via_diameter, layers=['*.Cu', '*.Mask']))\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('{name}.kicad_mod'.format(name=name))\n\n\ndef parse_and_execute_yml_file(filepath):\n    with open(filepath, 'r') as stream:\n        try:\n            yaml_parsed = yaml.safe_load(stream)\n            for footprint in yaml_parsed:\n                print(\"generate {name}.kicad_mod\".format(name=footprint))\n                create_footprint(footprint, **yaml_parsed.get(footprint))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='Parse *.kicad_mod.yml file(s) and create matching footprints')\n    parser.add_argument('files', metavar='file', type=str, nargs='+',\n                        help='yml-files to parse')\n    #parser.add_argument('-v', '--verbose', help='show more information when creating footprint', action='store_true')\n    # TODO: allow writing into sub file\n    args = parser.parse_args()\n    for filepath in args.files:\n        parse_and_execute_yml_file(filepath)\n"
  },
  {
    "path": "scripts/Mounting_Hardware/wuerth_smt_spacer.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n#sys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\n\n# export PYTHONPATH=\"${PYTHONPATH}<path to kicad-footprint-generator directory>\"\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\ndef roundToBase(value, base):\n    return round(value/base) * base\n\ndef generate_footprint(params, mpn, configuration):\n    fp_params = params['footprint']\n    mech_params = params['mechanical']\n    part_params = params['parts'][mpn]\n\n    if 'id' in mech_params:\n        size = str(mech_params['id'])\n    elif 'ext_thread' in mech_params:\n        size = str(mech_params['ext_thread']['od'])\n\n    if 'M' not in size:\n        size = \"{}mm\".format(size)\n\n    td = \"\"\n    size_prefix = \"\"\n    hole_type = \"inside through hole\"\n    if 'thread_depth' in part_params:\n        hole_type = \"inside blind hole\"\n        td = \"_ThreadDepth{}mm\".format(part_params['thread_depth'])\n    elif 'ext_thread' in mech_params:\n        hole_type = \"external\"\n        size_prefix = 'External'\n\n    h = part_params['h'] if 'h' in part_params else part_params['h1']\n\n    suffix = ''\n    if 'suffix' in params:\n        suffix = '_{}'.format(params['suffix'])\n\n    fp_name = \"Mounting_Wuerth_{series}-{size_prefix}{size}_H{h}mm{td}{suffix}_{mpn}\".format(\n                    size=size, h=h, mpn=mpn, td=td, size_prefix=size_prefix,\n                    series=params['series_prefix'], suffix=suffix)\n\n    kicad_mod = Footprint(fp_name)\n    kicad_mod.setAttribute('smd')\n\n    kicad_mod.setDescription(\"Mounting Hardware, {hole_type} {size}, height {h}, Wuerth electronics {mpn} ({ds:s}), generated with kicad-footprint-generator\".format(size=size, h=h, mpn=mpn, ds=part_params['datasheet'], hole_type=hole_type))\n\n    kicad_mod.setTags('Mounting {} {}'.format(size, mpn))\n\n    paste_count = fp_params['ring']['paste'].get('paste_count', 4)\n\n    kicad_mod.append(\n        RingPad(\n            number='1', at=(0, 0),\n            size=fp_params['ring']['od'], inner_diameter=fp_params['ring']['id'],\n            num_anchor=4, num_paste_zones=paste_count,\n            paste_round_radius_radio=0.25,\n            paste_max_round_radius=0.1,\n            paste_to_paste_clearance=fp_params['ring']['paste']['clearance'],\n            paste_inner_diameter=fp_params['ring']['paste']['id'],\n            paste_outer_diameter=fp_params['ring']['paste']['od']\n            ))\n    if 'npth' in fp_params:\n        kicad_mod.append(\n            Pad(at=[0, 0], number=\"\",\n                type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE, size=fp_params['npth'],\n                drill=fp_params['npth'], layers=Pad.LAYERS_NPTH))\n\n    kicad_mod.append(\n        Circle(\n            center=[0, 0], radius=mech_params['od']/2,\n            layer='F.Fab', width=configuration['fab_line_width']\n            ))\n\n    ########################### CrtYd #################################\n    rc = max(mech_params['od'], fp_params['ring']['od'])/2+configuration['courtyard_offset']['default']\n    rc = roundToBase(rc, configuration['courtyard_grid'])\n\n\n    kicad_mod.append(\n        Circle(\n            center=[0, 0], radius=rc,\n            layer='F.CrtYd', width=configuration['courtyard_line_width']\n            ))\n\n    ########################### SilkS #################################\n\n\n\n    ######################### Text Fields ###############################\n    rb = mech_params['od']/2\n    body_edge={'left':-rb, 'right':rb, 'top':-rb, 'bottom':rb}\n    addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n        courtyard={'top':-rc, 'bottom':rc}, fp_name=fp_name, text_y_inside_position='center')\n\n    ##################### Output and 3d model ############################\n    model3d_path_prefix = configuration.get('3d_model_prefix','${KISYS3DMOD}/')\n\n    lib_name = \"Mounting_Wuerth\"\n    model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n        model3d_path_prefix=model3d_path_prefix, lib_name=lib_name, fp_name=fp_name)\n    kicad_mod.append(Model(filename=model_name))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=fp_name)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--params', type=str, nargs='?', help='the part definition file', default='./wuerth_smt_spacer.yaml')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.params, 'r') as params_stream:\n        try:\n            params = yaml.safe_load(params_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    for series in params:\n        for mpn in params[series]['parts']:\n            generate_footprint(params[series], mpn, configuration)\n"
  },
  {
    "path": "scripts/Mounting_Hardware/wuerth_smt_spacer.yaml",
    "content": "2.25mm:\n  series_prefix: WA-SMST\n  footprint:\n    ring:\n      id: 3\n      od: 5.3\n      paste:\n        clearance: 0.6\n        id: 3.1\n        od: 5.12\n    npth: 3\n  mechanical:\n    id: 2.25\n    od: 4.35\n    od1: 2.8\n    h1: 1.4\n  parts:\n    9774010943:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774010943.pdf\n      h: 1\n    9774015943:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774015943.pdf\n      h: 1.5\n    9774020943:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774020943.pdf\n      h: 2\n    9774025943:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774025943.pdf\n      h: 2.5\n    9774030943:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774030943.pdf\n      h: 3\n    9774035943:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774035943.pdf\n      h: 3.5\n    9774040943:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774040943.pdf\n      h: 4\n    9774045943:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774045943.pdf\n      h: 4.5\n    9774050943:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774050943.pdf\n      h: 5\n    9774060943:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774060943.pdf\n      h: 6\n    9774070943:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774070943.pdf\n      h: 7\n    9774080943:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774080943.pdf\n      h: 8\n\n2.7mm:\n  series_prefix: WA-SMST\n  footprint:\n    ring:\n      id: 3.7\n      od: 6\n      paste:\n        clearance: 0.65\n        id: 3.8\n        od: 5.84\n    npth: 3.7\n  mechanical:\n    id: 2.7\n    od: 5.1\n    od1: 3.5\n    h1: 1.4\n  parts:\n    9774010951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774010951.pdf\n      h: 1\n    9774015951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774015951.pdf\n      h: 1.5\n    9774020951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774020951.pdf\n      h: 2\n    9774025951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774025951.pdf\n      h: 2.5\n    9774030951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774030951.pdf\n      h: 3\n    9774040951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774040951.pdf\n      h: 4\n    9774050951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774050951.pdf\n      h: 5\n    9774055951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774055951.pdf\n      h: 5.5\n    9774060951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774060951.pdf\n      h: 6\n    9774065951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774065951.pdf\n      h: 6.5\n    9774070951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774070951.pdf\n      h: 7\n    9774080951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774080951.pdf\n      h: 8\n    9774090951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774090951.pdf\n      h: 9\n    9774100951:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774100951.pdf\n      h: 10\n\n3.3mm:\n  series_prefix: WA-SMST\n  footprint:\n    ring:\n      id: 4.4\n      od: 7.4\n      paste: # measured from eagle footprint (not dimensioned in datasheet)\n        clearance: 0.5\n        id: 4.72\n        od: 6.92\n    npth: 4.4\n  mechanical:\n    id: 3.3\n    od: 6\n    od1: 4.2\n    h1: 1.4\n  parts:\n    9774010960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774010960.pdf,\n      h: 1\n    9774015960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774015960.pdf,\n      h: 1.5\n    9774020960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774020960.pdf,\n      h: 2\n    9774025960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774025960.pdf,\n      h: 2.5\n    9774030960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774030960.pdf,\n      h: 3\n    9774040960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774040960.pdf,\n      h: 4\n    9774050960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774050960.pdf,\n      h: 5\n    9774060960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774060960.pdf,\n      h: 6\n    9774070960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774070960.pdf,\n      h: 7\n    9774080960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774080960.pdf,\n      h: 8\n    9774090960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774090960.pdf,\n      h: 9\n    9774100960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774100960.pdf,\n      h: 10\n    9774110960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774110960.pdf,\n      h: 11\n    9774120960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774120960.pdf,\n      h: 12\n    9774130960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774130960.pdf,\n      h: 13\n    9774140960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774140960.pdf,\n      h: 14\n    9774150960:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774150960.pdf,\n      h: 15\n\n4.5mm:\n  series_prefix: WA-SMST\n  footprint:\n    ring:\n      id: 5.4\n      od: 9.4\n      paste:\n        clearance: 0.8\n        id: 5.48\n        od: 9.27\n    npth: 5.4\n  mechanical:\n    id: 4.5\n    od: 8.2\n    od1: 5.2\n    h1: 1.4\n  parts:\n    9774010982:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774010982.pdf\n      h: 1\n    9774020982:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774020982.pdf\n      h: 2\n    9774030982:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774030982.pdf\n      h: 3\n    9774040982:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774040982.pdf\n      h: 4\n    9774050982:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774050982.pdf\n      h: 5\n    9774060982:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774060982.pdf\n      h: 6\n    9774070982:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774070982.pdf\n      h: 7\n    9774080982:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774080982.pdf\n      h: 8\n    9774090982:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774090982.pdf\n      h: 9\n    9774100982:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774100982.pdf\n      h: 10\n\nM1.6:\n  series_prefix: WA-SMSI\n  footprint:\n    ring:\n      id: 2.1\n      od: 4\n      paste:\n        clearance: 0.4\n        id: 2.2\n        od: 3.8\n    npth: 2.1\n  mechanical:\n    id: M1.6\n    od: 3.3\n    od1: 1.9\n    h1: 0.7\n  parts:\n    9774010633:\n      datasheet: https://katalog.we-online.com/em/datasheet/9774010633.pdf\n      h: 1\n    9774015633:\n      datasheet: https://katalog.we-online.com/em/datasheet/9774015633.pdf\n      h: 1.5\n    9774020633:\n      datasheet: https://katalog.we-online.com/em/datasheet/9774020633.pdf\n      h: 2\n    9774025633:\n      datasheet: https://katalog.we-online.com/em/datasheet/9774025633.pdf\n      h: 2.5\n    9774030633:\n      datasheet: https://katalog.we-online.com/em/datasheet/9774030633.pdf\n      h: 3\n    97730356334:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730356334.pdf\n      h: 3.5\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n    97730406334:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730406334.pdf\n      h: 4\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n    97730456334:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730456334.pdf\n      h: 4.5\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n    97730506334:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730506334.pdf\n      h: 5\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n    97730606334:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730606334.pdf\n      h: 6\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n\nM1.6_s:\n  series_prefix: WA-SMSI\n  footprint:\n    ring:\n      id: 1\n      od: 4\n      paste:\n        paste_count: 2\n        clearance: 1.1\n        id: 1.2\n        od: 3.8\n    npth: 1\n  mechanical:\n    id: M1.6\n    od: 3.3\n    od1: 0.8\n    h1: 0.5\n  parts:\n    97730256332:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730256332.pdf\n      h: 2.5\n      thread_depth: 1.5\n      drill_depth: 1.63 # from 3d model\n    97730306332:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730306332.pdf\n      h: 3\n      thread_depth: 1.8\n      drill_depth: 1.93 # from 3d model\n    97730356332:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730356332.pdf\n      h: 3.5\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n    97730406332:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730406332.pdf\n      h: 4\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n    97730456332:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730456332.pdf\n      h: 4.5\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n    97730506332:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730506332.pdf\n      h: 5\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n    97730606332:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730606332.pdf\n      h: 6\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n\nM1.6_smt:\n  series_prefix: WA-SMSI\n  suffix: NoNPTH\n  footprint:\n    ring:\n      id: 0\n      od: 4\n      paste:\n        clearance: 0.3\n        id: 0.6 # 2*clearance to ensure proper handling (would need to implement a segment instead of an arc to really handle this. Too much work for now.)\n        od: 3.8\n  mechanical:\n    id: M1.6\n    od: 3.3\n  parts:\n    97730256330:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730256330R.pdf\n      h: 2.5\n      thread_depth: 1.5\n      drill_depth: 1.63 # from 3d model\n    97730306330:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730306330.pdf\n      h: 3\n      thread_depth: 1.8\n      drill_depth: 1.93 # from 3d model\n    97730356330:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730356330.pdf\n      h: 3.5\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n    97730406330:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730406330.pdf\n      h: 4\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n    97730456330:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730456330.pdf\n      h: 4.5\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n    97730506330:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730506330.pdf\n      h: 5\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n    97730606330:\n      datasheet: https://katalog.we-online.com/em/datasheet/97730606330.pdf\n      h: 6\n      thread_depth: 2\n      drill_depth: 3.13 # from 3d model\n\nM2:\n  series_prefix: WA-SMSI\n  footprint:\n    ring:\n      id: 3\n      od: 5.3\n      paste: # from 2.25mm ID version (Has same mechanical dimensions)\n        clearance: 0.6\n        id: 3.1\n        od: 5.12\n    npth: 3\n  mechanical:\n    id: M2\n    od: 4.35\n    od1: 2.8\n    h1: 1.4\n  parts:\n    9774010243:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774010243.pdf\n      h: 1\n    9774015243:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774015243.pdf\n      h: 1.5\n    9774020243:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774020243.pdf\n      h: 2\n    9774025243:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774025243.pdf\n      h: 2.5\n    9774030243:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774030243.pdf\n      h: 3\n    9774035243:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774035243.pdf\n      h: 3.5\n    9774040243:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774040243.pdf\n      h: 4\n    9774045243:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774045243.pdf\n      h: 4.5\n    9774050243:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774050243.pdf\n      h: 5\n    9774060243:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774060243.pdf\n      h: 6\n    9774070243:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774070243.pdf\n      h: 7\n    9774080243:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774080243.pdf\n      h: 8\n\nM3:\n  series_prefix: WA-SMSI\n  footprint:\n    ring:\n      id: 4.4\n      od: 7.4\n      paste: # measured from eagle footprint (not dimensioned in datasheet)\n        clearance: 0.5\n        id: 4.72\n        od: 6.92\n    npth: 4.4\n  mechanical:\n    id: M3\n    od: 6\n    od1: 4.2\n    h1: 1.4\n  parts:\n    9774010360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774010360.pdf\n      h: 1\n    9774015360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774015360.pdf\n      h: 1.5\n    9774020360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774020360.pdf\n      h: 2\n    9774025360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774025360.pdf\n      h: 2.5\n    9774030360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774030360R.pdf\n      h: 3\n    9774040360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774040360.pdf\n      h: 4\n    9774050360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774050360.pdf\n      h: 5\n    9774060360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774060360.pdf\n      h: 6\n    9774070360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774070360.pdf\n      h: 7\n    9774080360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774080360.pdf\n      h: 8\n    9774090360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774090360.pdf\n      h: 9\n    9774100360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774100360.pdf\n      h: 10\n    9774110360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774110360.pdf\n      h: 11\n    9774120360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774120360.pdf\n      h: 12\n    9774130360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774130360.pdf\n      h: 13\n    9774140360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774140360.pdf\n      h: 14\n    9774150360:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774150360.pdf\n      h: 15\n\nM4:\n  series_prefix: WA-SMSI\n  footprint:\n    ring:\n      id: 5.4\n      od: 9.4\n      paste:\n        clearance: 0.8\n        id: 5.48\n        od: 9.27\n    npth: 5.4\n  mechanical:\n    id: 4.5\n    od: 8.2\n    od1: 5.2\n    h1: 1.4\n  parts:\n    9774010482:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774010482.pdf\n      h: 1\n    9774020482:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774020482.pdf\n      h: 2\n    9774030482:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774030482.pdf\n      h: 3\n    9774040482:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774040482.pdf\n      h: 4\n    9774050482:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774050482.pdf\n      h: 5\n    9774060482:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774060482.pdf\n      h: 6\n    9774070482:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774070482.pdf\n      h: 7\n    9774080482:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774080482.pdf\n      h: 8\n    9774090482:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774090482.pdf\n      h: 9\n    9774100482:\n      datasheet: https://katalog.we-online.de/em/datasheet/9774100482.pdf\n      h: 10\n\n3.2R:\n  series_prefix: WA-SMSR\n  suffix: ReverseMount\n  footprint:\n    ring:\n      id: 4.5\n      od: 7.4\n      paste:\n        clearance: 0.8\n        id: 4.58\n        od: 7.27\n    npth: 4.4\n  mechanical:\n    id: 3.2\n    od: 6\n    od1: 4.2\n    h: 1\n  parts:\n    9775026960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775026960R.pdf\n      h1: 2.6\n    9775031960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775031960.pdf\n      h1: 3.1\n    9775036960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775036960.pdf\n      h1: 3.6\n    9775041960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775041960.pdf\n      h1: 4.1\n    9775046960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775046960.pdf\n      h1: 4.6\n    9775051960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775051960.pdf\n      h1: 5.1\n    9775056960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775056960.pdf\n      h1: 5.6\n    9775066960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775066960.pdf\n      h1: 6.6\n    9775076960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775076960.pdf\n      h1: 7.6\n    9775086960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775086960.pdf\n      h1: 8.6\n    9775096960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775096960.pdf\n      h1: 9.6\n    9775106960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775106960.pdf\n      h1: 10.6\n    9775116960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775116960.pdf\n      h1: 11.6\n\nM3R:\n  series_prefix: WA-SMSR\n  suffix: ReverseMount\n  footprint:\n    ring:\n      id: 4.5\n      od: 7.4\n      paste:\n        clearance: 0.8\n        id: 4.58\n        od: 7.27\n    npth: 4.4\n  mechanical:\n    id: M3\n    od: 6\n    od1: 4.2\n    h: 1\n  parts:\n    9775026360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775026360.pdf\n      h1: 2.6\n    9775031360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775031360.pdf\n      h1: 3.1\n    9775036360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775036360.pdf\n      h1: 3.6\n    9775041360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775041360.pdf\n      h1: 4.1\n    9775046360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775046360.pdf\n      h1: 4.6\n    9775051360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775051360.pdf\n      h1: 5.1\n    9775056360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775056360.pdf\n      h1: 5.6\n    9775066360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775066360.pdf\n      h1: 6.6\n    9775076360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775076360.pdf\n      h1: 7.6\n    9775086360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775086360.pdf\n      h1: 8.6\n    9775096360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775096360.pdf\n      h1: 9.6\n    9775106360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775106360.pdf\n      h1: 10.6\n    9775116360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9775116360.pdf\n      h1: 11.6\n\nsnap:\n  series_prefix: WA-SMSSR\n  suffix: SnapRivet\n  footprint:\n    ring:\n      id: 4.4\n      od: 7.4\n      paste:\n        clearance: 0.8\n        id: 4.48\n        od: 7.27\n    npth: 4.4\n  mechanical:\n    id: 3.3\n    id1: 2.15\n    t1: 0.5\n    od: 6\n    od1: 4.2\n    h1: 1.4\n  parts:\n    9776100960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9776100960R.pdf\n      h: 10\n    9776020960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9776020960.pdf\n      h: 2\n    9776025960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9776025960.pdf\n      h: 2.5\n    9776030960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9776030960.pdf\n      h: 3\n    9776040960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9776040960.pdf\n      h: 4\n    9776050960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9776050960.pdf\n      h: 5\n    9776060960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9776060960.pdf\n      h: 6\n    9776070960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9776070960.pdf\n      h: 7\n    9776080960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9776080960.pdf\n      h: 8\n    9776090960:\n      datasheet: https://katalog.we-online.com/em/datasheet/9776090960.pdf\n      h: 9\n\nexternal_m3:\n  series_prefix: WA-SMSE\n  footprint:\n    ring:\n      id: 1\n      od: 7.4\n      paste:\n        paste_count: 2\n        clearance: 1.06\n        id: 1.2\n        od: 7.2\n    npth: 1\n  mechanical:\n    ext_thread:\n      od: M3\n      L: 6\n      undercut:\n        od: 2.2\n        L: [0.5, 1.25]\n        r: 0.2\n    od: 6\n    od1: 0.8\n    h1: 0.5\n  parts:\n    9771050360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9771050360.pdf\n      h: 5\n    9771060360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9771060360.pdf\n      h: 6\n    9771070360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9771070360.pdf\n      h: 7\n    9771080360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9771080360.pdf\n      h: 8\n    9771090360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9771090360.pdf\n      h: 9\n    9771100360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9771100360.pdf\n      h: 10\n    9771110360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9771110360.pdf\n      h: 11\n    9771120360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9771120360.pdf\n      h: 12\n    9771130360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9771130360.pdf\n      h: 13\n    9771140360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9771140360.pdf\n      h: 14\n    9771150360:\n      datasheet: https://katalog.we-online.com/em/datasheet/9771150360.pdf\n      h: 15\n"
  },
  {
    "path": "scripts/Mounting_Holes/mounting_hole_long.yaml",
    "content": "MountingHole_5.3x7.3mm_M5_Pad_Via:\n    description: \"Mounting Hole 5.3x7.3mm, M5, including vias\"\n    courtjard: 0.25\n    hole_x: 7.3\n    hole_y: 5.3\n    anular_ring: 2\n    via: True\n    via_diameter: 0.6\n    via_count: 16\n\n"
  },
  {
    "path": "scripts/Multicomp/connectors_multicomp_mc9a12.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nsys.path.append(\"../../kicad_mod\") # load kicad_mod path\n\nimport argparse\nfrom kicad_mod import KicadMod, createNumberedPadsTHT\n\nparser = argparse.ArgumentParser()\nparser.add_argument('pincount', help='number of pins of the jst connector', type=int, nargs=1)\nparser.add_argument('-v', '--verbose', help='show extra information while generating the footprint', action='store_true') #TODO\nargs = parser.parse_args()\n\n# http://www.farnell.com/datasheets/1520732.pdf\n\npincount = int(args.pincount[0])\npad_spacing = 2.54\nstart_pos_x = 0\nend_pos_x = pad_spacing*(pincount-2)/2\n\n# Through-hole type shrouded header, Top entry type\nfootprint_name = 'Multicomp_MC9A12-{pincount:02g}34_2x{pincount_half:02g}x2.54mm_Straight'.format(pincount=pincount, pincount_half=pincount/2) # TODO: name\n\nkicad_mod = KicadMod(footprint_name)\nkicad_mod.setDescription('http://www.farnell.com/datasheets/1520732.pdf')\nkicad_mod.setTags('connector multicomp MC9A MC9A12')\n\n# set general values\nkicad_mod.addText('reference', 'REF**', {'x':start_pos_x-3, 'y':-7}, 'F.SilkS')\nkicad_mod.addText('value', footprint_name, {'x':end_pos_x/2., 'y':5}, 'F.Fab')\n\n# create Silkscreen\n\n# outline\nkicad_mod.addRectLine({'x':start_pos_x-3.87-1.2, 'y':3.2}, {'x':end_pos_x+3.87+1.2, 'y':-pad_spacing-3.2}, 'F.SilkS', 0.15)\n\n# slot(s)\nif pincount < 60:\n    kicad_mod.addPolygoneLine([{'x':((start_pos_x+end_pos_x)/2)-4.45/2, 'y':3.2}\n                              ,{'x':((start_pos_x+end_pos_x)/2)-4.45/2, 'y':1.9}\n                              ,{'x':start_pos_x-3.87, 'y':1.9}\n                              ,{'x':start_pos_x-3.87, 'y':-pad_spacing-1.9}\n                              ,{'x':end_pos_x+3.87, 'y':-pad_spacing-1.9}\n                              ,{'x':end_pos_x+3.87, 'y':1.9}\n                              ,{'x':((start_pos_x+end_pos_x)/2)+4.45/2, 'y':1.9}\n                              ,{'x':((start_pos_x+end_pos_x)/2)+4.45/2, 'y':3.2}], 'F.SilkS', 0.15)\nelse:\n    kicad_mod.addPolygoneLine([{'x':((start_pos_x+end_pos_x)/2)-4.45/2-7.3-4.1, 'y':3.2}\n                              ,{'x':((start_pos_x+end_pos_x)/2)-4.45/2-7.3-4.1, 'y':1.9}\n                              ,{'x':start_pos_x-3.87, 'y':1.9}\n                              ,{'x':start_pos_x-3.87, 'y':-pad_spacing-1.9}\n                              ,{'x':end_pos_x+3.87, 'y':-pad_spacing-1.9}\n                              ,{'x':end_pos_x+3.87, 'y':1.9}\n                              ,{'x':((start_pos_x+end_pos_x)/2)+4.45/2+7.3+4.1, 'y':1.9}\n                              ,{'x':((start_pos_x+end_pos_x)/2)+4.45/2+7.3+4.1, 'y':3.2}], 'F.SilkS', 0.15)\n\n    kicad_mod.addPolygoneLine([{'x':((start_pos_x+end_pos_x)/2)-4.45/2-7.3, 'y':3.2}\n                              ,{'x':((start_pos_x+end_pos_x)/2)-4.45/2-7.3, 'y':1.9}\n                              ,{'x':((start_pos_x+end_pos_x)/2)-4.45/2, 'y':1.9}\n                              ,{'x':((start_pos_x+end_pos_x)/2)-4.45/2, 'y':3.2}], 'F.SilkS', 0.15)\n    \n    kicad_mod.addPolygoneLine([{'x':((start_pos_x+end_pos_x)/2)+4.45/2+7.3, 'y':3.2}\n                              ,{'x':((start_pos_x+end_pos_x)/2)+4.45/2+7.3, 'y':1.9}\n                              ,{'x':((start_pos_x+end_pos_x)/2)+4.45/2, 'y':1.9}\n                              ,{'x':((start_pos_x+end_pos_x)/2)+4.45/2, 'y':3.2}], 'F.SilkS', 0.15)\n\n# lines above the footprint\nkicad_mod.addPolygoneLine([{'x':end_pos_x/2-0.25, 'y':-pad_spacing-3.2}\n                          ,{'x':end_pos_x/2-0.25, 'y':-pad_spacing-3.2-0.2}\n                          ,{'x':end_pos_x/2+0.25, 'y':-pad_spacing-3.2-0.2}\n                          ,{'x':end_pos_x/2+0.25, 'y':-pad_spacing-3.2}], 'F.SilkS', 0.15)\nkicad_mod.addLine({'x':end_pos_x/2-0.25, 'y':-pad_spacing-3.2-0.1}, {'x':end_pos_x/2+0.25, 'y':-pad_spacing-3.2-0.1}, 'F.SilkS', 0.15)\n\nkicad_mod.addPolygoneLine([{'x':end_pos_x+2.4-0.25, 'y':-pad_spacing-3.2}\n                          ,{'x':end_pos_x+2.4-0.25, 'y':-pad_spacing-3.2-0.2}\n                          ,{'x':end_pos_x+2.4+0.25, 'y':-pad_spacing-3.2-0.2}\n                          ,{'x':end_pos_x+2.4+0.25, 'y':-pad_spacing-3.2}], 'F.SilkS', 0.15)\nkicad_mod.addLine({'x':end_pos_x+2.4-0.25, 'y':-pad_spacing-3.2-0.1}, {'x':end_pos_x+2.4+0.25, 'y':-pad_spacing-3.2-0.1}, 'F.SilkS', 0.15)\n\nkicad_mod.addPolygoneLine([{'x':start_pos_x-2.4-0.25, 'y':-pad_spacing-3.2}\n                          ,{'x':start_pos_x-2.4-0.25, 'y':-pad_spacing-3.2-0.2}\n                          ,{'x':start_pos_x-2.4+0.25, 'y':-pad_spacing-3.2-0.2}\n                          ,{'x':start_pos_x-2.4+0.25, 'y':-pad_spacing-3.2}], 'F.SilkS', 0.15)\nkicad_mod.addLine({'x':start_pos_x-2.4-0.25, 'y':-pad_spacing-3.2-0.1}, {'x':start_pos_x-2.4+0.25, 'y':-pad_spacing-3.2-0.1}, 'F.SilkS', 0.15)\n\n# triangle which is pointing at 1\nkicad_mod.addPolygoneLine([{'x':start_pos_x-2.2, 'y':0.6}\n                          ,{'x':start_pos_x-2.2, 'y':-0.6}\n                          ,{'x':start_pos_x-1.6, 'y':0}\n                          ,{'x':start_pos_x-2.2, 'y':0.6}], 'F.SilkS', 0.15)\n\n# create Courtyard\ndef round_to(n, precision):\n    correction = 0.5 if n >= 0 else -0.5\n    return int( n/precision+correction ) * precision\n\nkicad_mod.addRectLine({'x':round_to(start_pos_x-3.87-1.2-0.5,0.05), 'y':3.2+0.5}, {'x':round_to(end_pos_x+3.87+1.2+0.5,0.05), 'y':round_to(-pad_spacing-3.2-0.5,0.05)}, 'F.CrtYd', 0.05)\n\n# create pads\npad_diameter = 1\npad_size = {'x':1.7, 'y':1.7}\n\nfor pad_number in range(1, pincount, 2):\n    pad_pos_x = (pad_number-1)/2*pad_spacing\n    if pad_number == 1:\n        kicad_mod.addPad(pad_number, 'thru_hole', 'rect', {'x':pad_pos_x, 'y':0}, pad_size, pad_diameter, ['*.Cu', '*.Mask', 'F.SilkS'])\n    else:\n        kicad_mod.addPad(pad_number, 'thru_hole', 'circle', {'x':pad_pos_x, 'y':0}, pad_size, pad_diameter, ['*.Cu', '*.Mask', 'F.SilkS'])\n\n    kicad_mod.addPad(pad_number+1, 'thru_hole', 'circle', {'x':pad_pos_x, 'y':-pad_spacing}, pad_size, pad_diameter, ['*.Cu', '*.Mask', 'F.SilkS'])\n\n# output kicad model\nprint(kicad_mod)\n"
  },
  {
    "path": "scripts/Multicomp/connectors_multicomp_mc9a22.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nsys.path.append(\"../../kicad_mod\") # load kicad_mod path\n\nimport argparse\nfrom kicad_mod import KicadMod, createNumberedPadsTHT\n\nparser = argparse.ArgumentParser()\nparser.add_argument('pincount', help='number of pins of the jst connector', type=int, nargs=1)\nparser.add_argument('-v', '--verbose', help='show extra information while generating the footprint', action='store_true') #TODO\nargs = parser.parse_args()\n\n# http://www.farnell.com/cad/360651.pdf\n\npincount = int(args.pincount[0])\npad_spacing = 2.54\nstart_pos_x = 0\nend_pos_x = pad_spacing*(pincount-2)/2\n\n# Through-hole type shrouded header, Top entry type\nfootprint_name = \"Multicomp_MC9A22-{pincount:02g}34_2x{pincount_half:02g}x2.54mm_Angled\".format(pincount=pincount, pincount_half=pincount/2)\n\nkicad_mod = KicadMod(footprint_name)\nkicad_mod.setDescription('http://www.farnell.com/cad/360651.pdf')\nkicad_mod.setTags('connector multicomp MC9A MC9A22')\n\n# set general values\nkicad_mod.addText('reference', 'REF**', {'x':start_pos_x-3, 'y':-15}, 'F.SilkS')\nkicad_mod.addText('value', footprint_name, {'x':end_pos_x/2., 'y':-5.5}, 'F.Fab')\n\n# create Silkscreen\n\n# outline\n\nkicad_mod.addRectLine({'x':start_pos_x-3.87-1.2, 'y':-pad_spacing-1.8}, {'x':end_pos_x+3.87+1.2, 'y':-pad_spacing-1.8-8.9}, 'F.SilkS', 0.15)\n\n\n# slot(s)\ndef draw_pin_silk(slot_pin_x):\n    kicad_mod.addPolygoneLine([{'x':slot_pin_x-0.4, 'y':-pad_spacing-1.8-8.9+6.6}\n                              ,{'x':slot_pin_x-0.4, 'y':-pad_spacing-1.8-8.5}\n                              ,{'x':slot_pin_x-0.2, 'y':-pad_spacing-1.8-8.7}\n                              ,{'x':slot_pin_x+0.2, 'y':-pad_spacing-1.8-8.7}\n                              ,{'x':slot_pin_x+0.4, 'y':-pad_spacing-1.8-8.5}\n                              ,{'x':slot_pin_x+0.4, 'y':-pad_spacing-1.8-8.9+6.6}], 'F.SilkS', 0.15)\n                              \nkicad_mod.addPolygoneLine([{'x':((start_pos_x+end_pos_x)/2)-4.45/2, 'y':-pad_spacing-1.8-8.9}\n                          ,{'x':((start_pos_x+end_pos_x)/2)-4.45/2, 'y':-pad_spacing-1.8-8.9+6.6}\n                          ,{'x':((start_pos_x+end_pos_x)/2)+4.45/2, 'y':-pad_spacing-1.8-8.9+6.6}\n                          ,{'x':((start_pos_x+end_pos_x)/2)+4.45/2, 'y':-pad_spacing-1.8-8.9}], 'F.SilkS', 0.15)\n\nif pincount%4 != 0:\n    slot_pin_x = start_pos_x+((int)(pincount/4)*pad_spacing)\n\n    draw_pin_silk(slot_pin_x)\nelse:\n    slot_pin_x = start_pos_x+((int)(pincount/4-1)*pad_spacing)\n    draw_pin_silk(slot_pin_x)\n    \n    slot_pin_x = start_pos_x+((int)(pincount/4)*pad_spacing)\n    draw_pin_silk(slot_pin_x)\n    \n    if pincount >= 60:\n        slot_pin_x = start_pos_x+((int)(pincount/4-1-4)*pad_spacing)\n        draw_pin_silk(slot_pin_x)\n        \n        slot_pin_x = start_pos_x+((int)(pincount/4+4)*pad_spacing)\n        draw_pin_silk(slot_pin_x)\n    \n\nif pincount >= 60:\n    kicad_mod.addPolygoneLine([{'x':((start_pos_x+end_pos_x)/2)-4.45/2-7.3, 'y':-pad_spacing-1.8-8.9}\n                              ,{'x':((start_pos_x+end_pos_x)/2)-4.45/2-7.3, 'y':-pad_spacing-1.8-8.9+6.6}\n                              ,{'x':((start_pos_x+end_pos_x)/2)-4.45/2-7.3-4.1, 'y':-pad_spacing-1.8-8.9+6.6}\n                              ,{'x':((start_pos_x+end_pos_x)/2)-4.45/2-7.3-4.1, 'y':-pad_spacing-1.8-8.9}], 'F.SilkS', 0.15)\n  \n    kicad_mod.addPolygoneLine([{'x':((start_pos_x+end_pos_x)/2)+4.45/2+7.3, 'y':-pad_spacing-1.8-8.9}\n                              ,{'x':((start_pos_x+end_pos_x)/2)+4.45/2+7.3, 'y':-pad_spacing-1.8-8.9+6.6}\n                              ,{'x':((start_pos_x+end_pos_x)/2)+4.45/2+7.3+4.1, 'y':-pad_spacing-1.8-8.9+6.6}\n                              ,{'x':((start_pos_x+end_pos_x)/2)+4.45/2+7.3+4.1, 'y':-pad_spacing-1.8-8.9}], 'F.SilkS', 0.15)\n\n# triangle which is pointing at 1\nkicad_mod.addPolygoneLine([{'x':start_pos_x-1, 'y':-12.5}\n                          ,{'x':start_pos_x+1, 'y':-12.5}\n                          ,{'x':start_pos_x, 'y':-11}\n                          ,{'x':start_pos_x-1, 'y':-12.5}], 'F.SilkS', 0.15)\n\n# create Courtyard\ndef round_to(n, precision):\n    correction = 0.5 if n >= 0 else -0.5\n    return int( n/precision+correction ) * precision\n\nkicad_mod.addRectLine({'x':round_to(start_pos_x-3.87-1.2-0.5,0.05), 'y':1.7/2+0.5}, {'x':round_to(end_pos_x+3.87+1.2+0.5,0.05), 'y':round_to(-pad_spacing-1.8-8.9-0.5,0.05)}, 'F.CrtYd', 0.05)\n\n# create pads\npad_diameter = 1\npad_size = {'x':1.7, 'y':1.7}\n\nfor pad_number in range(1, pincount, 2):\n    pad_pos_x = (pad_number-1)/2*pad_spacing\n    if pad_number == 1:\n        kicad_mod.addPad(pad_number, 'thru_hole', 'rect', {'x':pad_pos_x, 'y':0}, pad_size, pad_diameter, ['*.Cu', '*.Mask', 'F.SilkS'])\n    else:\n        kicad_mod.addPad(pad_number, 'thru_hole', 'circle', {'x':pad_pos_x, 'y':0}, pad_size, pad_diameter, ['*.Cu', '*.Mask', 'F.SilkS'])\n\n    kicad_mod.addPad(pad_number+1, 'thru_hole', 'circle', {'x':pad_pos_x, 'y':-pad_spacing}, pad_size, pad_diameter, ['*.Cu', '*.Mask', 'F.SilkS'])\n    \n    kicad_mod.addLine({'x':pad_pos_x-0.4, 'y':-1.1}, {'x':pad_pos_x-0.4, 'y':-pad_spacing+1.1}, 'F.SilkS', 0.15)\n    kicad_mod.addLine({'x':pad_pos_x+0.4, 'y':-1.1}, {'x':pad_pos_x+0.4, 'y':-pad_spacing+1.1}, 'F.SilkS', 0.15)\n    \n    kicad_mod.addLine({'x':pad_pos_x-0.4, 'y':-pad_spacing-1.1}, {'x':pad_pos_x-0.4, 'y':-pad_spacing-1.8}, 'F.SilkS', 0.15)\n    kicad_mod.addLine({'x':pad_pos_x+0.4, 'y':-pad_spacing-1.1}, {'x':pad_pos_x+0.4, 'y':-pad_spacing-1.8}, 'F.SilkS', 0.15)\n\n# output kicad model\nprint(kicad_mod)\n"
  },
  {
    "path": "scripts/Multicomp/create_connectors_multicomp.sh",
    "content": "#!/bin/bash\n\nmkdir Connectors_Multicomp.pretty\n\n# Wire-To-Board-Steckverbinder, Straight\nfor i in \"10\" \"14\" \"16\" \"20\" \"26\" \"34\" \"40\" \"50\" \"60\" \"64\"\ndo\n    i_2=$((i/2))\n    if [ $i_2 -lt 10 ]\n    then\n        PIN_NUMBER=\"0${i_2}\"\n    else\n        PIN_NUMBER=${i_2}\n    fi\n    \n   ./connectors_multicomp_mc9a12.py $i > \"Connectors_Multicomp.pretty/Multicomp_MC9A12-${i}34_2x${PIN_NUMBER}x2.54mm_Straight.kicad_mod\"\ndone\n\n# Wire-To-Board-Steckverbinder, Right Angle\nfor i in \"10\" \"14\" \"16\" \"20\" \"26\" \"34\" \"40\" \"50\" \"60\"\ndo\n    i_2=$((i/2))\n    if [ $i_2 -lt 10 ]\n    then\n        PIN_NUMBER=\"0${i_2}\"\n    else\n        PIN_NUMBER=${i_2}\n    fi\n    \n   ./connectors_multicomp_mc9a22.py $i > \"Connectors_Multicomp.pretty/Multicomp_MC9A22-${i}34_2x${PIN_NUMBER}x2.54mm_Angled.kicad_mod\"\ndone\n"
  },
  {
    "path": "scripts/Oscillators_SMD/make_oscillators.py",
    "content": "#!/usr/bin/env python\r\n\r\nimport sys\r\nimport os\r\nimport math\r\n\r\n# ensure that the kicad-footprint-generator directory is available\r\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\r\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\r\n\r\nfrom KicadModTree import *  # NOQA\r\nfrom drawing_tools import *\r\nfrom footprint_scripts_crystals import *\r\n\r\n\r\n\r\n\r\nif __name__ == '__main__':\r\n    standardtags=\"SMD SMT crystal oscillator\"\r\n    # common settings\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_IQD_IQXO70\", addSizeFootprintName=True, pins=4,\r\n                  pad_sep_x=5.08, pad_sep_y=4.2, pad=[1.8,2.0], pack_width=7.5, pack_height=5, pack_bevel=0.4,\r\n                   hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=2,\r\n                   description=\"IQD Crystal Clock Oscillator IQXO-70, http://www.iqdfrequencyproducts.com/products/details/iqxo-70-11-30.pdf\", tags=standardtags+\"\",\r\n                   lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_Fordahl_DFAS15\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=2.6+1.5, pad_sep_y=1.6+1.2, pad=[1.5, 1.2], pack_width=5, pack_height=3.2, pack_bevel=0.1,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=0.5,\r\n                          description=\"Ultraminiature Crystal Clock Oscillator TXCO Fordahl DFA S15-OV/UOV, http://www.iqdfrequencyproducts.com/products/details/iqxo-70-11-30.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_Fordahl_DFAS11\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=5.08, pad_sep_y=4.4, pad=[1.4,2], pack_width=7, pack_height=5,\r\n                          pack_bevel=0.1,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=2,\r\n                          description=\"Miniature Crystal Clock Oscillator TXCO Fordahl DFA S11-OV/UOV, http://www.iqdfrequencyproducts.com/products/details/iqxo-70-11-30.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_Fordahl_DFAS2\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=5.08, pad_sep_y=4.4, pad=[1.4, 2], pack_width=7.3, pack_height=5.08,\r\n                          pack_bevel=0.1,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=2,\r\n                          description=\"Mminiature Crystal Clock Oscillator TXCO Fordahl DFA S2-KS/LS/US, http://www.iqdfrequencyproducts.com/products/details/iqxo-70-11-30.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_Fordahl_DFAS3\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=5.08, pad_sep_y=6.4, pad=[1.5, 2.2], pack_width=9.1, pack_height=7.2,\r\n                          pack_bevel=0.1,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=2,\r\n                          description=\"Miniature Crystal Clock Oscillator TXCO Fordahl DFA S3-KS/LS/US, http://www.iqdfrequencyproducts.com/products/details/iqxo-70-11-30.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_Fordahl_DFAS7\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=19.0, pad_sep_y=7.6, pad=[2.6,1.3], pack_width=19.9, pack_height=12.9,\r\n                          pack_bevel=2,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=2,\r\n                          description=\"Miniature Crystal Clock Oscillator TXCO Fordahl DFA S7-K/L, http://www.iqdfrequencyproducts.com/products/details/iqxo-70-11-30.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_Fordahl_DFAS7\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=19.0, pad_sep_y=7.6, pad=[2.6, 1.3], pack_width=19.9, pack_height=12.9,\r\n                          pack_bevel=2,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=2,\r\n                          description=\"Miniature Crystal Clock Oscillator TXCO Fordahl DFA S7-K/L, http://www.iqdfrequencyproducts.com/products/details/iqxo-70-11-30.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystal(footprint_name=\"Oscillator_SMD_Fordahl_DFAS1\", addSizeFootprintName=True, pins=6,\r\n                          pad_sep_x=2.54, pad_sep_y=8.9, pad=[1.27, 2.54], pack_width=14.8, pack_height=9.1,\r\n                          pack_bevel=1,style=\"rect1bevel\",\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=0.5,\r\n                          description=\"Miniature Crystal Clock Oscillator TXCO Fordahl DFA S1-KHZ/LHZ, http://www.iqdfrequencyproducts.com/products/details/iqxo-70-11-30.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_Abracon_ASV\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=5.08, pad_sep_y=4.0, pad=[1.8, 2], pack_width=7, pack_height=5.08,\r\n                          pack_bevel=0.1,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=2,\r\n                          description=\"Miniature Crystal Clock Oscillator Abracon ASV series, http://www.abracon.com/Oscillators/ASV.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_Abracon_ASE\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=2.1, pad_sep_y=1.65, pad=[1.3, 1.1], pack_width=3.2, pack_height=2.5,\r\n                          pack_bevel=0.1,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=0.5,\r\n                          description=\"Miniature Crystal Clock Oscillator Abracon ASE series, http://www.abracon.com/Oscillators/ASEseries.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_TXC_7C\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=2.54, pad_sep_y=2.2, pad=[1.4, 1.2], pack_width=5, pack_height=3.2,\r\n                          pack_bevel=0.2,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=1,\r\n                          description=\"Miniature Crystal Clock Oscillator TXC 7C series, http://www.txccorp.com/download/products/osc/7C_o.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_EuroQuartz_XO32\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=2.15, pad_sep_y=1.55, pad=[1,0.9], pack_width=3.2, pack_height=2.5,\r\n                          pack_bevel=0.1,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=0.5,\r\n                          description=\"Miniature Crystal Clock Oscillator EuroQuartz XO32 series, http://cdn-reichelt.de/documents/datenblatt/B400/XO32.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_EuroQuartz_XO53\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=2.54, pad_sep_y=2.2, pad=[1.4,1.2], pack_width=5, pack_height=3.2,\r\n                          pack_bevel=0.1,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=1,\r\n                          description=\"Miniature Crystal Clock Oscillator EuroQuartz XO53 series, http://cdn-reichelt.de/documents/datenblatt/B400/XO53.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_EuroQuartz_XO91\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=5, pad_sep_y=4.2, pad=[2, 2], pack_width=7, pack_height=5,\r\n                          pack_bevel=0.1,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=2,\r\n                          description=\"Miniature Crystal Clock Oscillator EuroQuartz XO91 series, http://cdn-reichelt.de/documents/datenblatt/B400/XO91.pdf\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_SeikoEpson_SG8002JA\", addSizeFootprintName=True, pins=4,\r\n                          style=\"dip\",\r\n                          pad_sep_x=5.08, pad_sep_y=8.8,\r\n                          pad=[1.3, 3], pack_width=14, pack_height=8.65, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal Oscillator Seiko Epson SG-8002JA https://support.epson.biz/td/api/doc_check.php?mode=dl&lang=en&Parts=SG-8002DC\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_SeikoEpson_SG8002JC\", addSizeFootprintName=True, pins=4,\r\n                          style=\"dip\",\r\n                          pad_sep_x=5.08, pad_sep_y=4.6,\r\n                          pad=[1.3, 2.1], pack_width=10.5, pack_height=5, pack_bevel=0, hasAdhesive=False,\r\n                          adhesivePos=[0, 0],\r\n                          adhesiveSize=0.5,\r\n                          description=\"SMD Crystal Oscillator Seiko Epson SG-8002JC https://support.epson.biz/td/api/doc_check.php?mode=dl&lang=en&Parts=SG-8002DC\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_SeikoEpson_SG8002CE\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=2.4, pad_sep_y=1.9, pad=[1.4,1.2], pack_width=3.2, pack_height=2.5,\r\n                          pack_bevel=0.1,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=0.5,\r\n                          description=\"SMD Crystal Oscillator Seiko Epson SG-8002CE https://support.epson.biz/td/api/doc_check.php?mode=dl&lang=en&Parts=SG-8002DC\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_SeikoEpson_SG8002LB\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=2.54, pad_sep_y=2.2, pad=[1.6, 1.5], pack_width=5, pack_height=3.2,\r\n                          pack_bevel=0.0,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=0.5,\r\n                          description=\"SMD Crystal Oscillator Seiko Epson SG-8002LB https://support.epson.biz/td/api/doc_check.php?mode=dl&lang=en&Parts=SG-8002DC\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_SeikoEpson_SG8002CA\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=5.08, pad_sep_y=4.2, pad=[1.8, 2], pack_width=7, pack_height=5,\r\n                          pack_bevel=0.0,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=2,\r\n                          description=\"SMD Crystal Oscillator Seiko Epson SG-8002CA https://support.epson.biz/td/api/doc_check.php?mode=dl&lang=en&Parts=SG-8002DC\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n    makeSMDCrystalAndHand(footprint_name=\"Oscillator_SMD_SeikoEpson_SG210\", addSizeFootprintName=True, pins=4,\r\n                          pad_sep_x=1.7, pad_sep_y=1.3, pad=[1.1,0.9], pack_width=2.5, pack_height=2,\r\n                          pack_bevel=0.0,\r\n                          hasAdhesive=True, adhesivePos=[0, 0], adhesiveSize=2,\r\n                          description=\"SMD Crystal Oscillator Seiko Epson SG-210 https://support.epson.biz/td/api/doc_check.php?mode=dl&lang=en&Parts=SG-210SED\",\r\n                          tags=standardtags + \"\",\r\n                          lib_name=\"Oscillators\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0])\r\n\r\n"
  },
  {
    "path": "scripts/Packages/Package_BGA/bga.yaml",
    "content": "BGA-624_21.0x21.0mm_Layout25x25_P0.8mm:\n  description: \"BGA-624\"\n  size_source: \"https://www.nxp.com/docs/en/package-information/SOT1529-1.pdf\"\n  body_size_x: 21.0\n  body_size_y: 21.0\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.0625\n  layout_x: 25\n  layout_y: 25\n  row_skips: [[1], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]\nLFBGA-100_10x10mm_Layout10x10_P0.8mm:\n  description: \"LFBGA-100\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f103tb.pdf#page=87\"\n  body_size_x: 10.0\n  body_size_y: 10.0\n  pitch: 0.8\n  pad_diameter: 0.5\n  mask_margin: 0.035\n  paste_margin: 0.000001\n  layout_x: 10\n  layout_y: 10\nLFBGA-144_10x10mm_Layout12x12_P0.8mm:\n  description: \"LFBGA-144\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f103ze.pdf#page=114\"\n  body_size_x: 10.0\n  body_size_y: 10.0\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.035\n  paste_margin: 0.000001\n  layout_x: 12\n  layout_y: 12\nTexas_DSBGA-28_1.9x3.0mm_Layout4x7_P0.4mm:\n  description: \"Texas Instruments, DSBGA, area grid\"\n  size_source: \"http://www.ti.com/lit/ds/symlink/bq51050b.pdf, http://www.ti.com/lit/an/snva009ag/snva009ag.pdf\"\n  body_size_x: 1.9\n  body_size_y: 3.0\n  overall_height: 0.625\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.05\n  layout_x: 4\n  layout_y: 7\nTexas_DSBGA-49_3.33x3.488mm_Layout7x7_P0.4mm:\n  description: \"Texas Instruments, DSBGA, area grid\"\n  size_source: \"http://www.ti.com/lit/ds/symlink/msp430f2234.pdf, http://www.ti.com/lit/an/snva009ag/snva009ag.pdf\"\n  body_size_x: 3.33\n  body_size_y: 3.488\n  overall_height: 0.625\n  pitch: 0.4\n  pad_diameter: 0.225\n  layout_x: 7\n  layout_y: 7\n  mask_margin: 0.05\nTexas_DSBGA-64_3.415x3.535mm_Layout8x8_P0.4mm:\n  description: \"Texas Instruments, DSBGA, area grid\"\n  size_source: \"http://www.ti.com/lit/ds/slas718g/slas718g.pdf, http://www.ti.com/lit/an/snva009ag/snva009ag.pdf\"\n  body_size_x: 3.415\n  body_size_y: 3.535\n  overall_height: 0.625\n  pitch: 0.4\n  pad_diameter: 0.225\n  layout_x: 8\n  layout_y: 8\n  mask_margin: 0.05\nTexas_DSBGA-8_1.5195x1.5195mm_Layout3x3_P0.5mm:\n  description: \"Texas Instruments, DSBGA, area grid, YZR pad definition\"\n  size_source: \"http://www.ti.com/lit/ml/mxbg270/mxbg270.pdf\"\n  body_size_x: 1.5195\n  body_size_y: 1.5195\n  overall_height: 0.6\n  pitch: 0.5\n  pad_diameter: 0.2625\n  layout_x: 3\n  layout_y: 3\n  mask_margin: 0.05\n  row_skips: [[], [2], []]\nTexas_MicroStar_Junior_BGA-113_7.0x7.0mm_Layout12x12_P0.5mm:\n  description: \"Texas Instruments, BGA Microstar Junior\"\n  size_source: \"http://www.ti.com/lit/ml/mpbg674/mpbg674.pdf, http://www.ti.com/lit/wp/ssyz015b/ssyz015b.pdf\"\n  body_size_x: 7\n  body_size_y: 7\n  pitch: 0.5\n  pad_diameter: 0.25\n  layout_x: 12\n  layout_y: 12\n  mask_margin: 0.025\n  row_skips: [[], [], [[4, 11]], [3, 10], [3, 10], [3, 6, 7, 10], [3, 6, 7, 10], [3, 10], [3, 10], [[3, 11]], [], []]\nTFBGA-64_5x5mm_Layout8x8_P0.5mm:\n  description: \"TFBGA-64\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f100v8.pdf#page=83\"\n  body_size_x: 5.0\n  body_size_y: 5.0\n  pitch: 0.5\n  pad_diameter: 0.28\n  mask_margin: 0.045\n  paste_margin: 0.000001\n  layout_x: 8\n  layout_y: 8\nTFBGA-100_8x8mm_Layout10x10_P0.8mm:\n  description: \"TFBGA-100\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f746zg.pdf#page=199\"\n  body_size_x: 8.0\n  body_size_y: 8.0\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.035\n  paste_margin: 0.000001\n  layout_x: 10\n  layout_y: 10\nTFBGA-121_10x10mm_Layout11x11_P0.8mm:\n  description: \"TFBGA-121\"\n  size_source: \"http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#p495\"\n  body_size_x: 10.0\n  body_size_y: 10.0\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.035\n  paste_margin: 0.000001\n  layout_x: 11\n  layout_y: 11\nMicrochip_TFBGA-196_11x11mm_Layout14x14_P0.75mm_SMD:\n  description: \"TFBGA-196\"\n  size_source: \"http://ww1.microchip.com/downloads/en/DeviceDoc/SAMA5D2-Series-Data-Sheet-DS60001476C.pdf#page=2956\"\n  body_size_x: 11.0\n  body_size_y: 11.0\n  overall_height: 1.20\n  pitch: 0.75\n  pad_diameter: 0.35\n  mask_margin: -0.0375\n  paste_margin: 0.000001\n  layout_x: 14\n  layout_y: 14\nTFBGA-216_13x13mm_Layout15x15_P0.8mm:\n  description: \"TFBGA-216\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f746zg.pdf#page=219\"\n  body_size_x: 13.0\n  body_size_y: 13.0\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.035\n  paste_margin: 0.000001\n  layout_x: 15\n  layout_y: 15\n  row_skips: [[], [], [], [], [], [], [[7, 10]], [[7, 10]], [[7, 10]], [], [], [], [], [], []]\nTFBGA-265_14x14mm_Layout17x17_P0.8mm:\n  description: \"TFBGA-265\"\n  size_source: \"http://www.st.com/resource/en/datasheet/DM00387108.pdf#page=223\"\n  body_size_x: 14.0\n  body_size_y: 14.0\n  pitch: 0.8\n  pad_diameter: 0.325\n  mask_margin: 0.0325\n  paste_ratio: 0.0125\n  layout_x: 17\n  layout_y: 17\n  row_skips: [[], [], [], [], [], [[6, 13]], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [[6, 13]], [], [], [], [], []]\nUCBGA-36_2.5x2.5mm_Layout6x6_P0.4mm:\n  description: \"UCBGA-36\"\n  size_source: \"https://www.latticesemi.com/view_document?document_id=213\"\n  body_size_x: 2.5\n  body_size_y: 2.5\n  pitch: 0.4\n  pad_diameter: 0.27\n  mask_margin: 0.035\n  paste_margin: 0.000001\n  layout_x: 6\n  layout_y: 6\nUCBGA-49_3x3mm_Layout7x7_P0.4mm:\n  description: \"UCBGA-49\"\n  size_source: \"https://www.latticesemi.com/view_document?document_id=213\"\n  body_size_x: 3\n  body_size_y: 3\n  pitch: 0.4\n  pad_diameter: 0.27\n  mask_margin: 0.035\n  paste_margin: 0.000001\n  layout_x: 7\n  layout_y: 7\nUCBGA-81_4x4mm_Layout9x9_P0.4mm:\n  description: \"UCBGA-81\"\n  size_source: \"https://www.latticesemi.com/view_document?document_id=213\"\n  body_size_x: 4\n  body_size_y: 4\n  pitch: 0.4\n  pad_diameter: 0.27\n  mask_margin: 0.035\n  paste_margin: 0.000001\n  layout_x: 9\n  layout_y: 9\nUFBGA-64_5x5mm_Layout8x8_P0.5mm:\n  description: \"UFBGA-64\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f051t8.pdf#page=91\"\n  body_size_x: 5.0\n  body_size_y: 5.0\n  pitch: 0.5\n  pad_diameter: 0.28\n  mask_margin: 0.045\n  paste_margin: 0.000001\n  layout_x: 8\n  layout_y: 8\nUFBGA-100_7x7mm_Layout12x12_P0.5mm:\n  description: \"UFBGA-100\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f103tb.pdf#page=93\"\n  body_size_x: 7.0\n  body_size_y: 7.0\n  pitch: 0.5\n  pad_diameter: 0.28\n  mask_margin:  0.045\n  paste_margin: 0.000001\n  layout_x: 12\n  layout_y: 12\n  row_skips: [[], [], [6, 7], [[4, 10]], [[4, 10]], [[3, 11]], [[3, 11]], [[4, 10]], [[4, 10]], [6, 7], [], []]\nXBGA-121_10x10mm_Layout11x11_P0.8mm:\n  description: \"XBGA-121\"\n  size_source: \"http://ww1.microchip.com/downloads/en/DeviceDoc/39969b.pdf\"\n  body_size_x: 10.0\n  body_size_y: 10.0\n  pitch: 0.8\n  pad_diameter: 0.32\n  mask_margin: 0.04\n  paste_margin: 0.0001\n  layout_x: 11\n  layout_y: 11\nUFBGA-132_7x7mm_Layout12x12_P0.5mm:\n  description: \"UFBGA-132\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32l152zc.pdf#page=123\"\n  body_size_x: 7.0\n  body_size_y: 7.0\n  pitch: 0.5\n  pad_diameter: 0.27\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 12\n  layout_y: 12\n  row_skips: [[], [], [], [], [[5, 9]], [5, 8], [5, 8], [[5, 9]], [], [], [], []]\nUFBGA-144_7x7mm_Layout12x12_P0.5mm:\n  description: \"UFBGA-144\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f446ze.pdf#page=186\"\n  body_size_x: 7.0\n  body_size_y: 7.0\n  pitch: 0.5\n  pad_diameter: 0.28\n  mask_margin: 0.045\n  paste_margin: 0.000001\n  layout_x: 12\n  layout_y: 12\nUFBGA-144_10x10mm_Layout12x12_P0.8mm:\n  description: \"UFBGA-144\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f446ze.pdf#page=189\"\n  body_size_x: 10.0\n  body_size_y: 10.0\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.075\n  paste_margin: 0.000001\n  layout_x: 12\n  layout_y: 12\nUFBGA-169_7x7mm_Layout13x13_P0.5mm:\n  description: \"UFBGA-169\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f429ng.pdf#page=218\"\n  body_size_x: 7.0\n  body_size_y: 7.0\n  pitch: 0.5\n  pad_diameter: 0.27\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 13\n  layout_y: 13\nUFBGA-201_10x10mm_Layout15x15_P0.65mm:\n  description: \"UFBGA-201\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f207vg.pdf#page=166\"\n  body_size_x: 10.0\n  body_size_y: 10.0\n  pitch: 0.65\n  pad_diameter: 0.3\n  mask_margin: 0.05\n  paste_margin: 0.000001\n  layout_x: 15\n  layout_y: 15\n  row_skips: [[], [], [], [], [[5, 12]], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [[5, 12]], [], [], [], []]\nWLP-4_0.73x0.73mm_Layout2x2_P0.35mm_Ball0.22mm_Pad0.2mm:\n  description: \"WLP-4\"\n  size_source: \"https://datasheets.maximintegrated.com/en/ds/MAX40200.pdf\"\n  body_size_x: 0.728\n  body_size_y: 0.728\n  pitch: 0.35\n  pad_diameter: 0.2\n  mask_margin: 0.02\n  paste_margin: 0.000001\n  layout_x: 2\n  layout_y: 2\n  row_skips: [[], []]\nLattice_caBGA-381_17.0x17.0mm_Layout20x20_P0.8mm_Ball0.4mm_Pad0.4mm:\n  description: \"Lattice caBGA-381, ECP5 FPGAs\"\n  size_source: \"http://www.latticesemi.com/view_document?document_id=213\"\n  body_size_x: 17.0\n  body_size_y: 17.0\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.075\n  layout_x: 20\n  layout_y: 20\n  row_skips: [[1, 20], [], [], [], [], [], [], [], [], [], [], [], [], [], [6, 7, 8, 9, 10, 11, 12, 13, 14, 15], [], [], [], [], [1, 4, 9, 10, 13, 18, 20]]\nLattice_caBGA-381_17.0x17.0mm_Layout20x20_P0.8mm_Ball0.4mm_Pad0.6mm_SMD:\n  description: \"Lattice caBGA-381, ECP5 FPGAs\"\n  size_source: \"http://www.latticesemi.com/view_document?document_id=213\"\n  body_size_x: 17.0\n  body_size_y: 17.0\n  pitch: 0.8\n  pad_diameter: 0.6\n  mask_margin: -0.05\n  layout_x: 20\n  layout_y: 20\n  row_skips: [[1, 20], [], [], [], [], [], [], [], [], [], [], [], [], [], [6, 7, 8, 9, 10, 11, 12, 13, 14, 15], [], [], [], [], [1, 4, 9, 10, 13, 18, 20]]\nLattice_caBGA-756_27.0x27.0mm_Layout32x32_P0.8mm:\n  description: \"Lattice caBGA-756, ECP5 FPGAs\"\n  size_source: \"http://www.latticesemi.com/view_document?document_id=213\"\n  body_size_x: 27.0\n  body_size_y: 27.0\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.075\n  layout_x: 32\n  layout_y: 32\n  row_skips: [[1, 6, 12, 21, 27, 32], [6, 12, 21, 27], [6, 12, 21, 27], [6, 12, 21, 27], [6, 12, 21, 27], [6, 7, 12, 21, 26, 27], [1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 20, 21, 25, 26, 27, 28, 29, 30, 31, 32], [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26], [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25], [8, 9, 24, 25], [8, 9, 24, 25], [1, 2, 3, 4, 5, 6, 7, 8, 9, 24, 25, 26, 27, 28, 29, 30, 31, 32], [8, 9, 24, 25], [8, 9, 24, 25], [8, 9, 24, 25], [8, 9, 24, 25], [8, 9, 24, 25], [8, 9, 24, 25], [7, 8, 9, 24, 25, 26], [8, 9, 24, 25], [1, 2, 3, 4, 5, 6, 7, 8, 9, 24, 25, 26, 27, 28, 29, 30, 31, 32], [8, 9, 24, 25], [8, 9, 24, 25], [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25], [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13, 18, 21, 24, 25, 26, 27, 28, 29, 30, 31, 32], [6, 7, 8, 10, 13, 18, 21, 25, 26, 27], [6, 10, 13, 18, 21, 27], [6, 27], [6, 27], [6, 10, 13, 16, 19, 22, 25, 27], [1, 6, 10, 13, 16, 19, 22, 25, 27, 32]]\nAnalog_BGA-28_4.0x6.25mm_Layout4x7_P0.8mm_Ball0.45mm_Pad0.4:\n   description: \"Analog BGA-28, 0.4mm pad\"\n   size_source: \"https://www.analog.com/media/en/technical-documentation/data-sheets/8063fa.pdf\"\n   body_size_x: 4.0\n   body_size_y: 6.25\n   pitch: 0.8\n   pad_diameter: 0.4\n   mask_margin: 0.05\n   layout_x: 4\n   layout_y: 7\nST_uTFBGA-36_3.6x3.6mm_Layout6x6_P0.5mm:\n   description: \"ST uTFBGA-36, 0.25mm pad\"\n   size_source: \"https://www.st.com/resource/en/datasheet/stulpi01a.pdf\"\n   body_size_x: 3.6\n   body_size_y: 3.6\n   pitch: 0.5\n   pad_diameter: 0.25\n   mask_margin: 0.05\n   layout_x: 6\n   layout_y: 6\nWLP-9_1.448x1.468mm_Layout3x3_P0.4mm_Ball0.27mm_Pad0.25mm:\n  description: \"WLP-9\"\n  size_source: \"https://pdfserv.maximintegrated.com/package_dwgs/21-100168.PDF\"\n  body_size_x: 1.468\n  body_size_y: 1.448\n  pitch: 0.4\n  pad_diameter: 0.27\n  mask_margin: 0.02\n  paste_margin: 0.000001\n  layout_x: 3\n  layout_y: 3\nVFBGA-86_6x6mm_Layout10x10_P0.55mm_Ball0.25mm_Pad0.2mm:\n  description: \"VFBGA-86\"\n  size_source: \"https://www.dialog-semiconductor.com/sites/default/files/da1469x_datasheet_3v1.pdf#page=740\"\n  body_size_x: 6.0\n  body_size_y: 6.0\n  pitch: 0.55\n  pad_diameter: 0.2\n  layout_x: 10\n  layout_y: 10\n  row_skips: [[], [6], [5, 7], [4, 7, 8], [3, 5, 7], [6, 8], [7], [4, 6], [], []]\nBGA-200_10.0x14.5mm_Layout12x22_P0.80x0.65mm:\n  description: \"BGA-200\"\n  size_source: \"http://www.issi.com/WW/pdf/43-46LQ32256A-AL.pdf\"\n  body_size_x: 10.0\n  body_size_y: 14.5\n  pitch_x: 0.80\n  pitch_y: 0.65\n  pad_diameter: 0.27\n  layout_x: 12\n  layout_y: 22\n  row_skips: [[6,7],[6,7],[6,7],[6,7],[6,7],[6,7],[6,7],[6,7],[6,7],[6,7],[[1,13]],[[1,13]],[6,7],[6,7],[6,7],[6,7],[6,7],[6,7],[6,7],[6,7],[6,7],[6,7]]\nInfineon_LFBGA-292_17x17mm_Layout20x20_P0.8mm_Ball0.5mm_Pad0.35:\n  description: \"Infineon LFBGA-292, 0.35mm pad\"\n  size_source: \"https://www.infineon.com/cms/en/product/packages/PG-LFBGA/PG-LFBGA-292-11/\"\n  body_size_x: 17.0\n  body_size_y: 17.0\n  pitch: 0.8\n  pad_diameter: 0.35\n  layout_x: 20\n  layout_y: 20\n  row_skips: [\n    [],\n    [],\n    [3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],\n    [3,18],\n    [3,18],\n    [3,6,7,8,9,10,11,12,13,14,15,18],\n    [3,6,7,14,15,18],\n    [3,6,8,13,15,18],\n    [3,6,9,12,15,18],\n    [3,6,15,18],\n    [3,6,15,18],\n    [3,6,9,12,15,18],\n    [3,6,8,13,15,18],\n    [3,6,7,14,15,18],\n    [3,6,7,8,9,10,11,12,13,14,15,18],\n    [3,18],\n    [3,18],\n    [3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],\n    [],\n    []\n  ]\n"
  },
  {
    "path": "scripts/Packages/Package_BGA/bga_xilinx.yaml",
    "content": "# Artix-7 FPGA Packages\n# Notes:\n#  - Often names are similiar, e.g. FB, FBG and FBV. I choose FBG as it is the common one.\n#    The addition stems from different solder types for the BGA balls\n#  - Xilinx_CPG236 and Xilinx_CPG238 are the same, different name comes from bank differences\n#  - Xilinx_CSG324 and Xilinx_CSG325 are the same, different name comes from bank differences\n#  - Xilinx_RS484 and Xilinx_SBG484 have same landing pattern but different heights/3D packages\n#  - Xilinx_RB484, Xilinx_FBG484 and Xilinx_FGG484 have same landing pattern but different heights/3D packages\n#  - Xilinx_RB676, Xilinx_FBG676 and Xilinx_FGG676 have same landing pattern but different heights/3D packages\n\nXilinx_CPG236:\n  description: \"Artix-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=266\"\n  additional_tags: \"CP236 CPG236\"\n  body_size_x: 10\n  body_size_y: 10\n  pitch: 0.5\n  pad_diameter: 0.275\n  mask_margin: 0.05\n  layout_x: 19\n  layout_y: 19\n  row_skips: [[], [], [], [[4,17]], [[4,17]], [[4,17]], [[4,7],[14,17]], [[4,7],[14,17]], [[4,7],[14,17]], [[4,7],[9,12],[14,17]], [[4,7],[14,17]], [[4,7],[14,17]], [[4,7],[14,17]], [[4,17]], [[4,17]], [[4,17]], [], [], []]\nXilinx_CPG238:\n  description: \"Artix-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=267\"\n  additional_tags: \"CPG238\"\n  body_size_x: 10\n  body_size_y: 10\n  pitch: 0.5\n  pad_diameter: 0.275\n  mask_margin: 0.05\n  layout_x: 19\n  layout_y: 19\n  row_skips: [[], [], [], [[4,17]], [[4,17]], [[4,17]], [[4,7],[14,17]], [[4,7],[14,17]], [[4,7],[14,17]], [[4,7],[9,12],[14,17]], [[4,7],[14,17]], [[4,7],[14,17]], [[4,7],[14,17]], [[4,17]], [[4,17]], [[4,17]], [], [], []]\nXilinx_CSG324:\n  description: \"Artix-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=268\"\n  additional_tags: \"CS324 CSG324\"\n  body_size_x: 15\n  body_size_y: 15\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.05\n  layout_x: 18\n  layout_y: 18\nXilinx_CSG325:\n  description: \"Artix-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=268\"\n  additional_tags: \"CS325 CSG235\"\n  body_size_x: 15\n  body_size_y: 15\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.05\n  layout_x: 18\n  layout_y: 18\nXilinx_SBG484:\n  description: \"Artix-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=270\"\n  additional_tags: \"SB484 SBG484 SBV484\"\n  body_size_x: 19\n  body_size_y: 19\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.05\n  layout_x: 22\n  layout_y: 22\nXilinx_RS484:\n  description: \"Artix-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=279\"\n  additional_tags: \"RS484\"\n  body_size_x: 19\n  body_size_y: 19\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.05\n  layout_x: 22\n  layout_y: 22\nXilinx_FTG256:\n  description: \"Artix-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=269\"\n  additional_tags: \"FT256 FTG256\"\n  body_size_x: 17\n  body_size_y: 17\n  pitch: 1\n  pad_diameter: 0.4\n  mask_margin: 0.05\n  layout_x: 16\n  layout_y: 16\nXilinx_FBG484:\n  description: \"Artix-7, Kintex-7 and Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=271, ttps://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=281, https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=82\"\n  additional_tags: \"FB484 FBG484 FBV484\"\n  body_size_x: 23\n  body_size_y: 23\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 22\n  layout_y: 22\nXilinx_FGG484:\n  description: \"Artix-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=275\"\n  additional_tags: \"FG484 FGG484\"\n  body_size_x: 23\n  body_size_y: 23\n  pitch: 1\n  pad_diameter: 0.5\n  mask_margin: 0.05\n  layout_x: 22\n  layout_y: 22\nXilinx_RB484:\n  description: \"Artix-7 and Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=278, https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=92\"\n  additional_tags: \"RB484\"\n  body_size_x: 23\n  body_size_y: 23\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 22\n  layout_y: 22\nXilinx_FBG676:\n  description: \"Artix-7, Kintex-7 and Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=273, https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=284, https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=84\"\n  additional_tags: \"FB676 FBG676 FBV676\"\n  body_size_x: 27\n  body_size_y: 27\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 26\n  layout_y: 26\nXilinx_FGG676:\n  description: \"Artix-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=276\"\n  additional_tags: \"FG676 FGG676\"\n  body_size_x: 27\n  body_size_y: 27\n  pitch: 1\n  pad_diameter: 0.5\n  mask_margin: 0.05\n  layout_x: 26\n  layout_y: 26\nXilinx_RB676:\n  description: \"Artix-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=280\"\n  additional_tags: \"RB676\"\n  body_size_x: 27\n  body_size_y: 27\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 26\n  layout_y: 26\nXilinx_FFG1156:\n  description: \"Artix-7, Kintex-7 and Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=277, https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=296, https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=91\"\n  additional_tags: \"FF1156 FFG1156 FFV1156\"\n  body_size_x: 35\n  body_size_y: 35\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 34\n  layout_y: 34\n  \n# Spartan-7 FPGA Packages\n# Notes:\nXilinx_CPGA196:\n  description: \"Spartan-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=260\"\n  additional_tags: \"CPGA196\"\n  body_size_x: 8\n  body_size_y: 8\n  pitch: 0.5\n  pad_diameter: 0.275\n  mask_margin: 0.05\n  layout_x: 14\n  layout_y: 14\nXilinx_FTGB196:\n  description: \"Spartan-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=261\"\n  additional_tags: \"FTGB196\"\n  body_size_x: 15\n  body_size_y: 15\n  pitch: 1\n  pad_diameter: 0.4\n  mask_margin: 0.05\n  layout_x: 14\n  layout_y: 14\nXilinx_CSGA225:\n  description: \"Spartan-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=262\"\n  additional_tags: \"CSGA225\"\n  body_size_x: 13\n  body_size_y: 13\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.05\n  layout_x: 15\n  layout_y: 15\nXilinx_CSGA324:\n  description: \"Spartan-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=263\"\n  additional_tags: \"CSGA324\"\n  body_size_x: 15\n  body_size_y: 15\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.05\n  layout_x: 18\n  layout_y: 18\nXilinx_FGGA484:\n  description: \"Spartan-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=264\"\n  additional_tags: \"FGGA484\"\n  body_size_x: 23\n  body_size_y: 23\n  pitch: 1\n  pad_diameter: 0.5\n  mask_margin: 0.05\n  layout_x: 22\n  layout_y: 22\nXilinx_FGGA676:\n  description: \"Spartan-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=265\"\n  additional_tags: \"FGGA676\"\n  body_size_x: 27\n  body_size_y: 27\n  pitch: 1\n  pad_diameter: 0.5\n  mask_margin: 0.05\n  layout_x: 26\n  layout_y: 26\n  \n# Virtex-7 FPGA Packages\n# Notes: \n#  - FFG1157 and FFG1158 have same footprint and same 3D package and are therefore in one footprint\n#  - FFG1926, FFG1927, FFG1928 and FFG1930 have same footprint and same 3D package and are therefore in one footprint\n#  - FLG1925, FLG1926, FLG1928 and FLG1930 have same footprint and same 3D package and are therefore in one footprint \n#  - RF1157 and RF1158 have same footprint and same 3D package and are therefore in one footprint\nXilinx_FFG1157_FFG1158:\n  description: \"Virtex-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=299\"\n  additional_tags: \"FF1157 FFG1157 FFV1157 FF1158 FFG1158 FFV1158\"\n  body_size_x: 35\n  body_size_y: 35\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 34\n  layout_y: 34\nXilinx_FFG1761:\n  description: \"Virtex-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=300\"\n  additional_tags: \"FF1761 FFG1761\"\n  body_size_x: 42.5\n  body_size_y: 42.5\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 42\n  layout_y: 42\n  row_skips: [[1,42], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [1,42]] \nXilinx_FFV1761:\n  description: \"Virtex-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=301\"\n  additional_tags: \"FFV1761\"\n  body_size_x: 42.5\n  body_size_y: 42.5\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 42\n  layout_y: 42\n  row_skips: [[1,42], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [1,42]] \nXilinx_FHG1761:\n  description: \"Virtex-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=302\"\n  additional_tags: \"FH1761 FHG1761\"\n  body_size_x: 45\n  body_size_y: 45\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 42\n  layout_y: 42\n  row_skips: [[1,42], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [1,42]] \nXilinx_FFG1926_FFG1927_FFG1928_FFG1930:\n  description: \"Virtex-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=303\"\n  additional_tags: \"FF1926 FFG1926 FF1927 FFG1927 FFV1927 FF1928 FFG1928 FF1930 FFG1930\"\n  body_size_x: 45\n  body_size_y: 45\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 44\n  layout_y: 44\n  row_skips: [[1,2,43,44], [1,44], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [1,44], [1,2,43,44]] \nXilinx_FLG1925_FLG1926_FLG1928_FLG1930:\n  description: \"Virtex-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=304\"\n  additional_tags: \"FL1925 FLG1925 FL1926 FLG1926 FL1928 FLG1928 FL1930 FLG1930\"\n  body_size_x: 45\n  body_size_y: 45\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 44\n  layout_y: 44\n  row_skips: [[1,2,43,44], [1,44], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [1,44], [1,2,43,44]] \nXilinx_RF1157_RF1158:\n  description: \"Virtex-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=305\"\n  additional_tags: \"RF1157 RF1158\"\n  body_size_x: 35\n  body_size_y: 35\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 34\n  layout_y: 34\nXilinx_RF1761:\n  description: \"Virtex-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=306\"\n  additional_tags: \"RF1761\"\n  body_size_x: 42.5\n  body_size_y: 42.5\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 42\n  layout_y: 42\n  row_skips: [[1,42], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [1,42]]\nXilinx_RF1930:\n  description: \"Virtex-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=307\"\n  additional_tags: \"RF1930\"\n  body_size_x: 45\n  body_size_y: 45\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 44\n  layout_y: 44\n  row_skips: [[1,2,43,44], [1,44], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [1,44], [1,2,43,44]] \n\n# Kintex-7 FPGA Packages\n# Notes: \n#  - FBG484 has the same name for Artix and Kintex devices, although the 3d model is slightly different\n#  - FBG676 has the same name for Artix and Kintex devices, although the 3d model is slightly different\n#  - FF900, FFG900, FFV900, FF901, FFG901 and FFV901 have same footprint and same 3D package and are therefore in one footprint\n#  - FFG1156 has the same name for Artix and Kintex devices\n\n# For Xilinx_FBG484 refer to Artix-7 models\n# For Xilinx_FBG676 refer to Artix-7 models\nXilinx_FBG900:\n  description: \"Kintex-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=289\"\n  additional_tags: \"FB900 FBG900 FBV900\"\n  body_size_x: 31\n  body_size_y: 31\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 30\n  layout_y: 30\nXilinx_FFG676:\n  description: \"Kintex-7 and Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=292, https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=88\"\n  additional_tags: \"FF676 FFG676 FFV676\"\n  body_size_x: 27\n  body_size_y: 27\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 26\n  layout_y: 26\nXilinx_FFG900_FFG901:\n  description: \"Kintex-7 and Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=294, https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=90\"\n  additional_tags: \"FF900 FFG900 FFV900 FF901 FFG901 FFV901\"\n  body_size_x: 31\n  body_size_y: 31\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 30\n  layout_y: 30\n# For Xilinx_FFG1156 refer to Artix-7 \nXilinx_RF676:\n  description: \"Kintex-7 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=297\"\n  additional_tags: \"RF676\"\n  body_size_x: 27\n  body_size_y: 27\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 26\n  layout_y: 26\nXilinx_RF900:\n  description: \"Kintex-7 and Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug475_7Series_Pkg_Pinout.pdf#page=298, https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=94\"\n  additional_tags: \"RF900\"\n  body_size_x: 31\n  body_size_y: 31\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 30\n  layout_y: 30\n\n# Zynq-7000 FPGA Packages\n# Notes: \n#  - Xilinx_FBG484 has the same name for Artix and Zynq devices\n#  - Xilinx_FBG676 has the same name for Artix and Zynq devices\n#  - Xilinx_FFG676 has the same name for Kintex and Zynq devices\n#  - Xilinx_FFG900_FFG901 has the same name for Kintex and Zynq devices\n#  - Xilinx_FFG1156 has the same name for Artix and Zynq devices\n#  - Xilinx_RB484 has the same name for Artix and Zynq devices\n#  - Xilinx_RF900 has the same name for Kintex and Zynq devices\nXilinx_CLG225:\n  description: \"Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=77\"\n  additional_tags: \"CLG225\"\n  body_size_x: 13\n  body_size_y: 13\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.05\n  layout_x: 15\n  layout_y: 15\nXilinx_CLG400:\n  description: \"Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=78\"\n  additional_tags: \"CLG400 CL400\"\n  body_size_x: 17\n  body_size_y: 17\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.05\n  layout_x: 20\n  layout_y: 20\nXilinx_CLG484_CLG485:\n  description: \"Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=79\"\n  additional_tags: \"CLG484 CL484 CLG485 CL485\"\n  body_size_x: 19\n  body_size_y: 19\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.05\n  layout_x: 22\n  layout_y: 22\nXilinx_SBG485:\n  description: \"Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=80\"\n  additional_tags: \"SBG485 SBV485\"\n  body_size_x: 19\n  body_size_y: 19\n  pitch: 0.8\n  pad_diameter: 0.4\n  mask_margin: 0.05\n  layout_x: 22\n  layout_y: 22\n# For Xilinx_FBG484 refer to Artix-7\n# For Xilinx_FBG676 refer to Artix-7\n# For Xilinx_FFG676 refer to Kintex-7\n# For Xilinx_FFG900_FFG901 refer to Kintex-7\n# For Xilinx_FFG1156 refer to Artix-7\n# For Xilinx_RB484 refer to Artix-7\nXilinx_RFG676:\n  description: \"Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=93\"\n  additional_tags: \"RF676 RFG676\"\n  body_size_x: 27\n  body_size_y: 27\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 26\n  layout_y: 26\n# For Xilinx_RF900 refer to Kintex-7\nXilinx_RF1156:\n  description: \"Zynq-7000 BGA, NSMD pad definition Appendix A\"\n  size_source: \"https://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf#page=95\"\n  additional_tags: \"RF1156\"\n  body_size_x: 35\n  body_size_y: 35\n  pitch: 1\n  pad_diameter: 0.53\n  mask_margin: 0.05\n  layout_x: 34\n  layout_y: 34\n"
  },
  {
    "path": "scripts/Packages/Package_BGA/csp.yaml",
    "content": "WLCSP-12_1.403x1.555mm_P0.4mm_Stagger:\n  description: \"WLCSP-12, staggered array\"\n  size_source: \"http://ww1.microchip.com/downloads/en/devicedoc/atmel-8235-8-bit-avr-microcontroller-attiny20_datasheet.pdf#page=208\"\n  body_size_x: 1.403\n  body_size_y: 1.555\n  pitch_x: 0.2\n  pitch_y: 0.346333\n  pad_diameter: 0.215\n  mask_margin: 0.0325\n  paste_margin: 0.000001\n  layout_x: 6\n  layout_y: 4\n  row_skips: [[2, 4, 6], [1, 3, 5], [2, 4, 6], [1, 3, 5]]\nST_WLCSP-25_Die425:\n  description: \"WLCSP-25\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32l031f6.pdf#page=112\"\n  body_size_x: 2.097\n  body_size_y: 2.493\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 5\n  layout_y: 5\nST_WLCSP-25_Die444:\n  description: \"WLCSP-25\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f031k6.pdf#page=93\"\n  body_size_x: 2.423\n  body_size_y: 2.325\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 5\n  layout_y: 5\nST_WLCSP-25_Die457:\n  description: \"WLCSP-25\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32l011k3.pdf#page=100\"\n  body_size_x: 2.133\n  body_size_y: 2.070\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 5\n  layout_y: 5\nST_WLCSP-36_Die417:\n  description: \"WLCSP-36\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32l052t8.pdf#page=123\"\n  body_size_x: 2.61\n  body_size_y: 2.88\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 6\n  layout_y: 6\nST_WLCSP-36_Die440:\n  description: \"WLCSP-36\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f051t8.pdf#page=103\"\n  body_size_x: 2.605\n  body_size_y: 2.703\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 6\n  layout_y: 6\nST_WLCSP-36_Die445:\n  description: \"WLCSP-36\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f042k6.pdf#page=96\"\n  body_size_x: 2.605\n  body_size_y: 2.703\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 6\n  layout_y: 6\nST_WLCSP-36_Die458:\n  description: \"WLCSP-36\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f410t8.pdf#page=119\"\n  body_size_x: 2.553\n  body_size_y: 2.579\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 6\n  layout_y: 6\nST_WLCSP-49_Die423:\n  description: \"WLCSP-49\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f401vc.pdf#page=115\"\n  body_size_x: 2.965\n  body_size_y: 2.965\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 7\n  layout_y: 7\nST_WLCSP-49_Die431:\n  description: \"WLCSP-49\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f411vc.pdf#page=124\"\n  body_size_x: 2.999\n  body_size_y: 3.185\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 7\n  layout_y: 7\nST_WLCSP-49_Die433:\n  description: \"WLCSP-49\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f401ce.pdf#page=116\"\n  body_size_x: 3.029\n  body_size_y: 3.029\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 7\n  layout_y: 7\nST_WLCSP-49_Die435:\n  description: \"WLCSP-49\"\n  size_source: \"http://www.st.com/resource/en/datasheet/DM00257211.pdf#page=191\"\n  body_size_x: 3.141\n  body_size_y: 3.127\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 7\n  layout_y: 7\nST_WLCSP-49_Die438:\n  description: \"WLCSP-49\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f303r8.pdf#page=112\"\n  body_size_x: 3.89\n  body_size_y: 3.74\n  pitch: 0.5\n  pad_diameter: 0.29\n  mask_margin: 0.03\n  paste_margin: 0.01\n  layout_x: 7\n  layout_y: 7\nST_WLCSP-49_Die439:\n  description: \"WLCSP-49\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f301r8.pdf#page=117\"\n  body_size_x: 3.417\n  body_size_y: 3.151\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 7\n  layout_y: 7\nST_WLCSP-49_Die447:\n  description: \"WLCSP-49\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32l072kz.pdf#page=134\"\n  body_size_x: 3.294\n  body_size_y: 3.258\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 7\n  layout_y: 7\nST_WLCSP-49_Die448:\n  description: \"WLCSP-49\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f071v8.pdf#page=106\"\n  body_size_x: 3.277\n  body_size_y: 3.109\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 7\n  layout_y: 7\nST_WLCSP-63_Die427:\n  description: \"WLCSP-63\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32l151cc.pdf#page=125\"\n  body_size_x: 3.228\n  body_size_y: 4.164\n  pitch: 0.4\n  pad_diameter: 0.24\n  mask_margin: 0.0325\n  paste_margin: 0.000001\n  layout_x: 7\n  layout_y: 9\nST_WLCSP-64_Die414:\n  description: \"WLCSP-64\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f103ze.pdf#page=120\"\n  body_size_x: 4.466\n  body_size_y: 4.395\n  pitch: 0.5\n  pad_diameter: 0.25\n  mask_margin: 0.025\n  paste_margin: 0.035\n  layout_x: 8\n  layout_y: 8\nST_WLCSP-64_Die427:\n  description: \"WLCSP-64\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32l152zc.pdf#page=126\"\n  body_size_x: 4.539\n  body_size_y: 4.911\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 8\n  layout_y: 8\nST_WLCSP-64_Die435:\n  description: \"WLCSP-64\"\n  size_source: \"http://www.st.com/resource/en/datasheet/DM00257211.pdf#page=188\"\n  body_size_x: 3.141\n  body_size_y: 3.127\n  pitch: 0.35\n  pad_diameter: 0.21\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 8\n  layout_y: 8\nST_WLCSP-64_Die436:\n  description: \"WLCSP-64\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32l152zd.pdf#page=143\"\n  body_size_x: 4.539\n  body_size_y: 4.911\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 8\n  layout_y: 8\nST_WLCSP-64_Die441:\n  description: \"WLCSP-64\"\n  size_source: \"http://www.st.com/resource/en/datasheet/DM00213872.pdf#page=167\"\n  body_size_x: 3.623\n  body_size_y: 3.651\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 8\n  layout_y: 8\nST_WLCSP-64_Die442:\n  description: \"WLCSP-64\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f091vb.pdf#page=109\"\n  body_size_x: 3.347\n  body_size_y: 3.585\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 8\n  layout_y: 8\nST_WLCSP-64_Die462:\n  description: \"WLCSP-64\"\n  size_source: \"http://www.st.com/resource/en/datasheet/DM00340475.pdf#page=189\"\n  body_size_x: 3.357\n  body_size_y: 3.657\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 8\n  layout_y: 8\nST_WLCSP-66_Die411:\n  description: \"WLCSP-66\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f207vg.pdf#page=154\"\n  body_size_x: 3.639\n  body_size_y: 3.971\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 9\n  layout_y: 9\n  row_skips: [[], [], [[4, 7]], [[4, 7]], [[4, 7]], [[4, 7]], [[4, 7]], [], []]\nST_WLCSP-66_Die432:\n  description: \"WLCSP-66\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f378vc.pdf#page=114\"\n  body_size_x: 3.767\n  body_size_y: 4.229\n  pitch: 0.4\n  pad_diameter: 0.24\n  mask_margin: 0.0325\n  paste_margin: 0.000001\n  layout_x: 8\n  layout_y: 9\n  row_skips: [[], [], [], [4, 5], [4, 5], [4, 5], [], [], []]\nST_WLCSP-72_Die415:\n  description: \"WLCSP-72\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32l476me.pdf#page=255\"\n  body_size_x: 4.4084\n  body_size_y: 3.7594\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 9\n  layout_y: 9\n  row_skips: [[], [], [], [[4, 7]], [[4, 7]], [[4, 7]], [], [], []]\nST_WLCSP-81_Die415:\n  description: \"WLCSP-81\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32l476me.pdf#page=252\"\n  body_size_x: 4.4084\n  body_size_y: 3.7594\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 9\n  layout_y: 9\nST_WLCSP-81_Die421:\n  description: \"WLCSP-81\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f446ze.pdf#page=192\"\n  body_size_x: 3.693\n  body_size_y: 3.815\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 9\n  layout_y: 9\nST_WLCSP-81_Die463:\n  description: \"WLCSP-81\"\n  size_source: \"http://www.st.com/resource/en/datasheet/DM00282249.pdf#page=175\"\n  body_size_x: 4.039\n  body_size_y: 3.951\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 9\n  layout_y: 9\nST_WLCSP-90_Die413:\n  description: \"WLCSP-90\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f405og.pdf#page=164\"\n  body_size_x: 4.223\n  body_size_y: 3.969\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 10\n  layout_y: 9\nST_WLCSP-100_Die422:\n  description: \"WLCSP-100\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f302vc.pdf#page=133\"\n  body_size_x: 4.201\n  body_size_y: 4.663\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.000001\n  layout_x: 10\n  layout_y: 10\nST_WLCSP-100_Die446:\n  description: \"WLCSP-100\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f303zd.pdf#page=162\"\n  body_size_x: 4.775\n  body_size_y: 5.041\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.000001\n  layout_x: 10\n  layout_y: 10\nST_WLCSP-100_Die452:\n  description: \"WLCSP-100\"\n  size_source: \"http://www.st.com/resource/en/datasheet/DM00330506.pdf#page=218\"\n  body_size_x: 4.201\n  body_size_y: 4.663\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.000001\n  layout_x: 10\n  layout_y: 10\nST_WLCSP-100_Die461:\n  description: \"WLCSP-100\"\n  size_source: \"http://www.st.com/resource/en/datasheet/DM00284211.pdf#page=259\"\n  body_size_x: 4.618\n  body_size_y: 4.142\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.000001\n  layout_x: 10\n  layout_y: 10\nST_WLCSP-104_Die437:\n  description: \"WLCSP-104\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32l152ze.pdf#page=127\"\n  body_size_x: 4.095\n  body_size_y: 5.094\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 9\n  layout_y: 12\n  row_skips: [[], [], [], [], [5], [5], [5], [5], [], [], [], []]\nST_WLCSP-143_Die419:\n  description: \"WLCSP-143\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f429ng.pdf#page=203\"\n  body_size_x: 4.521\n  body_size_y: 5.547\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 11\n  layout_y: 13\nST_WLCSP-143_Die449:\n  description: \"WLCSP-143\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f746zg.pdf#page=202\"\n  body_size_x: 4.539\n  body_size_y: 5.849\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 11\n  layout_y: 13\nST_WLCSP-144_Die470:\n  description: \"WLCSP-144\"\n  size_source: \"http://www.st.com/resource/en/datasheet/DM00366448.pdf#page=295\"\n  body_size_x: 5.24\n  body_size_y: 5.24\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 12\n  layout_y: 12\nST_WLCSP-168_Die434:\n  description: \"WLCSP-168\"\n  size_source: \"http://www.st.com/resource/en/datasheet/stm32f469ni.pdf#page=198\"\n  body_size_x: 4.891\n  body_size_y: 5.692\n  pitch: 0.4\n  pad_diameter: 0.22\n  mask_margin: 0.04\n  paste_margin: 0.000001\n  layout_x: 12\n  layout_y: 14\nST_WLCSP-180_Die451:\n  description: \"WLCSP-180\"\n  size_source: \"http://www.st.com/resource/en/datasheet/DM00273119.pdf#page=240\"\n  body_size_x: 5.537\n  body_size_y: 6.095\n  pitch: 0.4\n  pad_diameter: 0.225\n  mask_margin: 0.0325\n  paste_margin: 0.0125\n  layout_x: 13\n  layout_y: 14\n  row_skips: [[], [], [], [], [], [], [7], [7], [], [], [], [], [], []]\nWLCSP-16_1.409x1.409mm_P0.35mm:\n  description: \"WLCSP-16\"\n  size_source: 'http://www.latticesemi.com/view_document?document_id=213'\n  body_size_x: 1.409\n  body_size_y: 1.409\n  pitch: 0.35\n  pad_diameter: 0.2\n  layout_x: 4\n  layout_y: 4\nWLCSP-8_1.551x2.284mm_P0.5mm:\n  description: \"WLCSP-8\"\n  size_source: \"https://www.adestotech.com/wp-content/uploads/AT25SL321_112.pdf#page=75\"\n  body_size_x: 1.551\n  body_size_y: 2.284\n  pitch: 0.5\n  pad_diameter: 0.2\n  layout_x: 2\n  layout_y: 4\nWLCSP-4-X1-WLB0909-4_0.89x0.89mm_P0.5mm:\n  description: \"X1-WLB0909\"\n  size_source: 'https://www.diodes.com/assets/Datasheets/AP22913.pdf'\n  body_size_x: 0.89\n  body_size_y: 0.89\n  pitch: 0.5\n  pad_diameter: 0.235 # even though ball_diameter is 0.235 analog recommends a landing pad of 0.235\n  layout_x: 2\n  layout_y: 2\n"
  },
  {
    "path": "scripts/Packages/Package_BGA/ipc_7351b_bga_land_patterns.yaml",
    "content": "# IPC IPC-7351B  (sadly no openly accessible document available)\n# Page 89, Table 14-5 and 14-6\n\n# First level: ball type (collapsible is most common so use if unknown)\n# Second level: nominal ball diameter\n# Third level: land pattern diameter in nominal and min/max variation\n#       IPC-7351B section 14.4.2 requires the use of the max land size\n#       Furthermore, that section also suggests NSMD lands are preferred\n\n'collapsible':\n    0.75:\n        nominal: 0.55\n        max: 0.6\n        min: 0.5\n    0.65:\n        nominal: 0.5\n        max: 0.55\n        min: 0.45\n    0.6:\n        nominal: 0.45\n        max: 0.5\n        min: 0.4\n    0.55:\n        nominal: 0.4\n        max: 0.5\n        min: 0.4\n    0.5:\n        nominal: 0.4\n        max: 0.45\n        min: 0.35\n    0.45:\n        nominal: 0.35\n        max: 0.4\n        min: 0.3\n    0.4:\n        nominal: 0.3\n        max: 0.35\n        min: 0.25\n    0.35:\n        nominal: 0.28\n        max: 0.33\n        min: 0.23\n    0.3:\n        nominal: 0.25\n        max: 0.25\n        min: 0.2\n    0.25:\n        nominal: 0.2\n        max: 0.2\n        min: 0.17\n    0.2:\n        nominal: 0.17\n        max: 0.2\n        min: 0.14\n    0.17:\n        nominal: 0.15\n        max: 0.18\n        min: 0.12\n    0.15:\n        nominal: 0.13\n        max: 0.15\n        min: 0.1\n\n'non-collapsible':\n    0.75:\n        nominal: 0.85\n        max: 0.9\n        min: 0.8\n    0.6:\n        nominal: 0.7\n        max: 0.75\n        min: 0.65\n    0.55:\n        nominal: 0.65\n        max: 0.7\n        min: 0.6\n    0.5:\n        nominal: 0.55\n        max: 0.6\n        min: 0.5\n    0.45:\n        nominal: 0.5\n        max: 0.55\n        min: 0.45\n    0.4:\n        nominal: 0.45\n        max: 0.5\n        min: 0.4\n    0.3:\n        nominal: 0.33\n        max: 0.38\n        min: 0.28\n    0.25:\n        nominal: 0.28\n        max: 0.33\n        min: 0.23\n    0.2:\n        nominal: 0.21\n        max: 0.24\n        min: 0.18\n    0.17:\n        nominal: 0.18\n        max: 0.21\n        min: 0.15\n    0.15:\n        nominal: 0.16\n        max: 0.19\n        min: 0.13\n"
  },
  {
    "path": "scripts/Packages/Package_BGA/ipc_bga_generator.py",
    "content": "#!/usr/bin/env python3\n\nimport math\nimport os\nimport sys\nimport argparse\nimport yaml\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))\n\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\n\nfrom KicadModTree import *\nimport itertools\nfrom string import ascii_uppercase\n\ndef generateFootprint(config, fpParams, fpId):\n    createFp = False\n    \n    # use IPC-derived pad size if possible, then fall back to user-defined pads\n    if \"ball_type\" in fpParams and \"ball_diameter\" in fpParams:\n        try:\n            padSize = configuration[fpParams[\"ball_type\"]]\n            try:\n                padSize = configuration[fpParams[\"ball_type\"]][fpParams[\"ball_diameter\"]][\"max\"]\n                fpParams[\"pad_size\"] = [padSize, padSize]\n                createFp = True\n            except KeyError as e:\n                print(\"{}mm is an invalid ball diameter. See ipc_7351b_bga_land_patterns.yaml for valid values. No footprint generated.\".format(e))\n        except KeyError:\n            print(\"{} is an invalid ball type. See ipc_7351b_bga_land_patterns.yaml for valid values. No footprint generated.\".format(e))\n        \n        if \"pad_diameter\" in fpParams:\n            print(\"Pad size is being derived using IPC rules even though pad diameter is defined.\")\n    elif \"ball_type\" in fpParams and not \"ball_diameter\" in fpParams:\n        raise KeyError(\"Ball diameter is missing. No footprint generated.\")\n    elif \"ball_diameter\" in fpParams and not \"ball_type\" in fpParams:\n        raise KeyError(\"Ball type is missing. No footprint generated.\")\n    elif \"pad_diameter\" in fpParams:\n        fpParams[\"pad_size\"] = [fpParams[\"pad_diameter\"], fpParams[\"pad_diameter\"]]\n        print(\"Pads size is set by the footprint definition. This should only be done for manufacturer-specific footprints.\")\n        createFp = True\n    else:\n        print(\"The config file must include 'ball_type' and 'ball_diameter' or 'pad_diameter'. No footprint generated.\")\n\n    if createFp:\n        __createFootprintVariant(config, fpParams, fpId)\n\ndef __createFootprintVariant(config, fpParams, fpId):\n    pkgX = fpParams[\"body_size_x\"]\n    pkgY = fpParams[\"body_size_y\"]\n    layoutX = fpParams[\"layout_x\"]\n    layoutY = fpParams[\"layout_y\"]\n    \n    if \"additional_tags\" in fpParams:\n        additionalTag = \" \" + fpParams[\"additional_tags\"]\n    else:\n        additionalTag = \"\"\n    \n    if \"row_names\" in fpParams:\n        rowNames = fpParams[\"row_names\"]\n    else:\n        rowNames = config['row_names']\n    \n    if \"row_skips\" in fpParams:\n        rowSkips = fpParams[\"row_skips\"]\n    else:\n        rowSkips = []\n\n    # must be given pitch (equal in X and Y) or a unique pitch in both X and Y\n    if \"pitch\" in fpParams:\n        if \"pitch_x\" and \"pitch_y\" in fpParams:\n            raise KeyError('{}: Either pitch or both pitch_x and pitch_y must be given.'.format(fpId))\n        else:\n            pitchString = str(fpParams[\"pitch\"])\n            pitchX = fpParams[\"pitch\"]\n            pitchY = fpParams[\"pitch\"]\n    else:\n        if \"pitch_x\" and \"pitch_y\" in fpParams:\n            pitchString = str(fpParams[\"pitch_x\"]) + \"x\" + str(fpParams[\"pitch_y\"])\n            pitchX = fpParams[\"pitch_x\"]\n            pitchY = fpParams[\"pitch_y\"]\n        else:\n            raise KeyError('{}: Either pitch or both pitch_x and pitch_y must be given.'.format(fpId))\n\n    f = Footprint(fpId)\n    f.setAttribute(\"smd\")\n    if \"mask_margin\" in fpParams: f.setMaskMargin(fpParams[\"mask_margin\"])\n    if \"paste_margin\" in fpParams: f.setPasteMargin(fpParams[\"paste_margin\"])\n    if \"paste_ratio\" in fpParams: f.setPasteMarginRatio(fpParams[\"paste_ratio\"])\n\n    s1 = [1.0, 1.0]\n    s2 = [min(1.0, round(pkgX / 4.3, 2))] * 2\n\n    t1 = 0.15 * s1[0]\n    t2 = 0.15 * s2[0]\n\n    padShape = Pad.SHAPE_CIRCLE\n    if \"pad_shape\" in fpParams:\n        if fpParams[\"pad_shape\"] == \"rect\":\n            padShape = Pad.SHAPE_RECT\n        if fpParams[\"pad_shape\"] == \"roundrect\":\n            padShape = Pad.SHAPE_ROUNDRECT\n\n    chamfer = min(config['fab_bevel_size_absolute'], min(pkgX, pkgY) * config['fab_bevel_size_relative'])\n    \n    silkOffset = config['silk_fab_offset']\n    crtYdOffset = config['courtyard_offset']['bga']\n    \n    def crtYdRound(x):\n        # Round away from zero for proper courtyard calculation\n        neg = x < 0\n        if neg:\n            x = -x\n        x = math.ceil(x * 100) / 100.0\n        if neg:\n            x = -x\n        return x\n\n    xCenter = 0.0\n    xLeftFab = xCenter - pkgX / 2.0\n    xRightFab = xCenter + pkgX / 2.0\n    xChamferFab = xLeftFab + chamfer\n    xPadLeft = xCenter - pitchX * ((layoutX - 1) / 2.0)\n    xPadRight = xCenter + pitchX * ((layoutX - 1) / 2.0)\n    xLeftCrtYd = crtYdRound(xCenter - (pkgX / 2.0 + crtYdOffset))\n    xRightCrtYd = crtYdRound(xCenter + (pkgX / 2.0 + crtYdOffset))\n\n    yCenter = 0.0\n    yTopFab = yCenter - pkgY / 2.0\n    yBottomFab = yCenter + pkgY / 2.0\n    yChamferFab = yTopFab + chamfer\n    yPadTop = yCenter - pitchY * ((layoutY - 1) / 2.0)\n    yPadBottom = yCenter + pitchY * ((layoutY - 1) / 2.0)\n    yTopCrtYd = crtYdRound(yCenter - (pkgY / 2.0 + crtYdOffset))\n    yBottomCrtYd = crtYdRound(yCenter + (pkgY / 2.0 + crtYdOffset))\n    yRef = yTopFab - 1.0\n    yValue = yBottomFab + 1.0\n\n    xLeftSilk = xLeftFab - silkOffset\n    xRightSilk = xRightFab + silkOffset\n    xChamferSilk = xLeftSilk + chamfer\n    yTopSilk = yTopFab - silkOffset\n    yBottomSilk = yBottomFab + silkOffset\n    yChamferSilk = yTopSilk + chamfer\n\n    wFab = configuration['fab_line_width']\n    wCrtYd = configuration['courtyard_line_width']\n    wSilkS = configuration['silk_line_width']\n\n    # Text\n    f.append(Text(type=\"reference\", text=\"REF**\", at=[xCenter, yRef],\n                  layer=\"F.SilkS\", size=s1, thickness=t1))\n    f.append(Text(type=\"value\", text=fpId, at=[xCenter, yValue],\n                  layer=\"F.Fab\", size=s1, thickness=t1))\n    f.append(Text(type=\"user\", text=\"%R\", at=[xCenter, yCenter],\n                  layer=\"F.Fab\", size=s2, thickness=t2))\n\n    # Fab\n    f.append(PolygoneLine(polygone=[[xRightFab, yBottomFab],\n                                    [xLeftFab, yBottomFab],\n                                    [xLeftFab, yChamferFab],\n                                    [xChamferFab, yTopFab],\n                                    [xRightFab, yTopFab],\n                                    [xRightFab, yBottomFab]],\n                          layer=\"F.Fab\", width=wFab))\n\n    # Courtyard\n    f.append(RectLine(start=[xLeftCrtYd, yTopCrtYd],\n                      end=[xRightCrtYd, yBottomCrtYd],\n                      layer=\"F.CrtYd\", width=wCrtYd))\n\n    # Silk\n    f.append(PolygoneLine(polygone=[[xChamferSilk, yTopSilk],\n                                    [xRightSilk, yTopSilk],\n                                    [xRightSilk, yBottomSilk],\n                                    [xLeftSilk, yBottomSilk],\n                                    [xLeftSilk, yChamferSilk]],\n                          layer=\"F.SilkS\", width=wSilkS))\n\n    # Pads\n    balls = layoutX * layoutY\n    \n    if rowSkips == []:\n        for _ in range(layoutY):\n            rowSkips.append([])\n    for rowNum, row in zip(range(layoutY), rowNames):\n        rowSet = set(range(1, layoutX + 1))\n        for item in rowSkips[rowNum]:\n            try:\n                # If item is a range, remove that range\n                rowSet -= set(range(*item))\n                balls -= item[1] - item[0]\n            except TypeError:\n                # If item is an int, remove that int\n                rowSet -= {item}\n                balls -= 1\n        for col in rowSet:\n            f.append(Pad(number=\"{}{}\".format(row, col), type=Pad.TYPE_SMT,\n                         shape=padShape,\n                         at=[xPadLeft + (col-1) * pitchX, yPadTop + rowNum * pitchY],\n                         size=fpParams[\"pad_size\"],\n                         layers=Pad.LAYERS_SMT, \n                         radius_ratio=config['round_rect_radius_ratio']))\n\n    # If this looks like a CSP footprint, use the CSP 3dshapes library\n    packageType = 'CSP' if 'BGA' not in fpId and 'CSP' in fpId else 'BGA'\n\n    f.append(Model(filename=\"{}Package_{}.3dshapes/{}.wrl\".format(\n                  config['3d_model_prefix'], packageType, fpId)))\n\n    f.setDescription(\"{0}, {1}x{2}mm, {3} Ball, {4}x{5} Layout, {6}mm Pitch, {7}\".format(fpParams[\"description\"], pkgY, pkgX, balls, layoutX, layoutY, pitchString, fpParams[\"size_source\"]))\n    f.setTags(\"{} {} {}{}\".format(packageType, balls, pitchString, additionalTag))\n\n    outputDir = 'Package_{lib_name:s}.pretty/'.format(lib_name=packageType)\n    if not os.path.isdir(outputDir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(outputDir)\n    filename = '{outdir:s}{fpId:s}.kicad_mod'.format(outdir=outputDir, fpId=fpId)\n    \n    file_handler = KicadFileHandler(f)\n    file_handler.writeFile(filename)\n\ndef rowNameGenerator(seq):\n    for n in itertools.count(1):\n        for s in itertools.product(seq, repeat = n):\n            yield ''.join(s)\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('files', metavar='file', type=str, nargs='+',\n                        help='list of files holding information about what devices should be created.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    # parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../package_config_KLCv3.yaml')\n    parser.add_argument('--ipc_doc', type=str, nargs='?', help='IPC definition document', default='ipc_7351b_bga_land_patterns.yaml')\n    parser.add_argument('-v', '--verbose', action='count', help='set debug level')\n    args = parser.parse_args()\n    \n    if args.verbose:\n        DEBUG_LEVEL = args.verbose\n    \n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    # with open(args.series_config, 'r') as config_stream:\n        # try:\n            # configuration.update(yaml.safe_load(config_stream))\n        # except yaml.YAMLError as exc:\n            # print(exc)\n    \n    with open(args.ipc_doc, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    # generate dict of A, B .. Y, Z, AA, AB .. CY less easily-confused letters\n    rowNamesList = [x for x in ascii_uppercase if x not in [\"I\", \"O\", \"Q\", \"S\", \"X\", \"Z\"]]\n    configuration.update({'row_names': list(itertools.islice(rowNameGenerator(rowNamesList), 80))})\n\n    for filepath in args.files:\n        with open(filepath, 'r') as command_stream:\n            try:\n                cmd_file = yaml.safe_load(command_stream)\n            except yaml.YAMLError as exc:\n                print(exc)\n        for pkg in cmd_file:\n            print(\"generating part for parameter set {}\".format(pkg))\n            generateFootprint(configuration, cmd_file[pkg], pkg)\n"
  },
  {
    "path": "scripts/Packages/Package_BGA/test_ipc.yaml",
    "content": "# these test the IPC pad size generator and error handling\n\n# uses IPC pads with collapsible balls\nCollapsible_balls:\n  description: 'BGA-100'\n  size_source: ''\n  body_size_x: 6.0\n  body_size_y: 6.0\n  pitch: 0.55\n  ball_type: 'collapsible'\n  ball_diameter: 0.25\n  layout_x: 10\n  layout_y: 10\n\nNon-collapsible_balls:\n  description: 'BGA-100'\n  size_source: ''\n  body_size_x: 6.0\n  body_size_y: 6.0\n  pitch: 0.55\n  ball_type: 'non-collapsible'\n  ball_diameter: 0.25\n  layout_x: 10\n  layout_y: 10\n\nFixed_pad_size:\n  description: 'BGA-100'\n  size_source: ''\n  body_size_x: 6.0\n  body_size_y: 6.0\n  pitch: 0.55\n  pad_diameter: 0.21\n  layout_x: 10\n  layout_y: 10\n\n# warning as both fixed pad size and IPD ball info present\nDoubled_pad_size:\n  description: 'BGA-100'\n  size_source: ''\n  body_size_x: 6.0\n  body_size_y: 6.0\n  pitch: 0.55\n  pad_diameter: 0.22\n  ball_type: 'collapsible'\n  ball_diameter: 0.25\n  layout_x: 10\n  layout_y: 10\n\n# failure as ball diameter is not in the IPC table\n# can also change ball type to an illegal value\nInvalid_ball_size:\n  description: 'BGA-100'\n  size_source: ''\n  body_size_x: 6.0\n  body_size_y: 6.0\n  pitch: 0.55\n  ball_type: 'collapsible' # change this to an illegal value\n  ball_diameter: 0.1234 # not an IPC ball diameter\n  layout_x: 10\n  layout_y: 10\n\n# failure as ball_diameter is given but not ball_type\n# can also test condition where ball type is given by not diameter\nMissing_ball_type:\n  description: 'BGA-100'\n  size_source: ''\n  body_size_x: 6.0\n  body_size_y: 6.0\n  pitch: 0.55\n  ball_diameter: 0.25\n  layout_x: 10\n  layout_y: 10\n"
  },
  {
    "path": "scripts/Packages/Package_DIP/make_DIP_footprints.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_DIP import *\n\n\n\n\n\nif __name__ == '__main__':\n    # common settings\n    overlen_top=1.27\n    overlen_bottom=1.27\n    rm=2.54\n    ddrill=0.8\n    pad=[1.6,1.6]\n    pad_large=[2.4,1.6]\n    pad_smdsocket=[3.1,1.6]\n    pad_smdsocket_small=[1.6,1.6]\n\n    # narrow 7.62 DIPs\n    pins=[4,6,8,10,12,14,16,18,20,22,24,28]\n    pinrow_distance=7.62\n    package_width=6.35\n    socket_width=pinrow_distance+2.54\n    for p in pins:\n        makeDIP(p,rm,pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad,False,0,0,0)\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_large, False, 0,0,0, [\"LongPads\"])\n        socket_height = (p / 2 - 1) * rm + 2.54\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad, False, socket_width,socket_height,0, [\"Socket\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_large, False, socket_width,socket_height,0,  [\"Socket\",\"LongPads\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smdsocket, True, socket_width,socket_height,1.27, [\"SMDSocket\",\"LongPads\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smdsocket_small, True,socket_width, socket_height, 0, [\"SMDSocket\", \"SmallPads\"])\n\n    # narrow 7.62 DIPs\n    pins=[4,6,8,10,12,14,16,]\n    pinrow_distance=10.16\n    package_width=6.35\n    socket_width=pinrow_distance+2.54\n    for p in pins:\n        makeDIP(p,rm,pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad,False,0,0,0)\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_large, False, 0,0,0, [\"LongPads\"])\n\n    # mid 10.16 DIPs\n    pins=[22,24]\n    pinrow_distance=10.16\n    package_width=9.14\n    socket_width=pinrow_distance+2.54\n    for p in pins:\n        makeDIP(p,rm,pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad,False,0,0,0)\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_large, False, 0,0,0, [\"LongPads\"])\n        socket_height = (p / 2 - 1) * rm + 2.54\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad, False, socket_width,socket_height,0, [\"Socket\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_large, False, socket_width,socket_height,0,  [\"Socket\",\"LongPads\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smdsocket, True,\n            socket_width, socket_height, 1.27, [\"SMDSocket\", \"LongPads\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smdsocket_small, True,\n            socket_width, socket_height, 0, [\"SMDSocket\", \"SmallPads\"])\n\n    # mid 15.24 DIPs\n    pins=[24,28,32,40,42,48,64]\n    pinrow_distance=15.24\n    package_width=14.73\n    socket_width=pinrow_distance+2.54\n    for p in pins:\n        makeDIP(p,rm,pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad,False,0,0,0)\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_large, False, 0,0,0, [\"LongPads\"])\n        socket_height = (p / 2 - 1) * rm + 2.54\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad, False, socket_width,socket_height,0, [\"Socket\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_large, False, socket_width,socket_height,0,  [\"Socket\",\"LongPads\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smdsocket, True,\n            socket_width, socket_height, 1.27, [\"SMDSocket\", \"LongPads\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smdsocket_small, True,\n            socket_width, socket_height, 0, [\"SMDSocket\", \"SmallPads\"])\n\n    # large 22.86 DIPs\n    pins=[64]\n    pinrow_distance=22.86\n    package_width=22.35\n    socket_width=pinrow_distance+2.54\n    for p in pins:\n        makeDIP(p,rm,pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad,False,0,0,0)\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_large, False, 0,0,0, [\"LongPads\"])\n        socket_height = (p / 2 - 1) * rm + 2.54\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad, False, socket_width,socket_height,0, [\"Socket\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_large, False, socket_width,socket_height,0,  [\"Socket\",\"LongPads\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smdsocket, True,\n            socket_width, socket_height, 1.27, [\"SMDSocket\", \"LongPads\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smdsocket_small, True,\n            socket_width, socket_height, 0, [\"SMDSocket\", \"SmallPads\"])\n\n    # large 25.4 DIPs\n    pins=[40,64]\n    pinrow_distance=25.4\n    package_width=24.89\n    socket_width=pinrow_distance+2.54\n    for p in pins:\n        makeDIP(p,rm,pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad,False,0,0,0)\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_large, False, 0,0,0, [\"LongPads\"])\n        socket_height = (p / 2 - 1) * rm + 2.54\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad, False, socket_width,socket_height,0, [\"Socket\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_large, False, socket_width,socket_height,0,  [\"Socket\",\"LongPads\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smdsocket, True,\n            socket_width, socket_height, 1.27, [\"SMDSocket\", \"LongPads\"])\n        makeDIP(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smdsocket_small, True,\n            socket_width, socket_height, 0, [\"SMDSocket\", \"SmallPads\"])\n\n    # special SMD footprints\n    smd_pins=[4,6,8,10,12,14,16,18,20,22,24,32]\n    pad_smd = [2, 1.78]\n    smd_pinrow_distances=[7.62, 9.53, 11.48]\n    package_width=6.35\n    for p in smd_pins:\n        for prd in smd_pinrow_distances:\n            makeDIP(p, rm, prd, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, True,  0,0,0, [], \"Housings_DIP\", [0, 0, 0], [1, 1, 1], [0, 0, 0], 'SMDIP', 'surface-mounted (SMD) DIP', 'SMD DIP DIL PDIP SMDIP')\n    smd_pins=[4,6,8,10,12,14,16,18,20,22]\n    pad_smd = [1.5, 1.78]\n    smd_pinrow_distances=[9.53]\n    package_width=6.35\n    for p in smd_pins:\n        for prd in smd_pinrow_distances:\n            makeDIP(p, rm, prd, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, True,  0,0,0, ['Clearance8mm'], \"Housings_DIP\", [0, 0, 0], [1, 1, 1], [0, 0, 0], 'SMDIP', 'surface-mounted (SMD) DIP', 'SMD DIP DIL PDIP SMDIP')\n\n    smd_pins=[24,28,32,40,42,48,64]\n    pad_smd = [2, 1.78]\n    smd_pinrow_distances=[15.24]\n    package_width=14.73\n    for p in smd_pins:\n        for prd in smd_pinrow_distances:\n            makeDIP(p, rm, prd, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, True,  0,0,0, [], \"Housings_DIP\", [0, 0, 0], [1, 1, 1], [0, 0, 0], 'SMDIP', 'surface-mounted (SMD) DIP', 'SMD DIP DIL PDIP SMDIP')\n    smd_pins=[40]\n    pad_smd = [2, 1.78]\n    smd_pinrow_distances=[25.24]\n    package_width=24.89\n    for p in smd_pins:\n        for prd in smd_pinrow_distances:\n            makeDIP(p, rm, prd, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, True,  0,0,0, [], \"Housings_DIP\", [0, 0, 0], [1, 1, 1], [0, 0, 0], 'SMDIP', 'surface-mounted (SMD) DIP', 'SMD DIP DIL PDIP SMDIP')\n\n\n    # DIP-switches:\n    pins=[2,4,6,8,10,12,14,16,18,20,22,24]\n    pinrow_distance = 7.62\n    package_width = 9.78\n    switch_width=4.06\n    switch_height=1.27\n    overlen_top = 2.36\n    overlen_bottom = 2.36\n    package_width_narrow = 6.68\n    switch_width_narrow = 3.62\n    switch_height_narrow = 1.27\n    overlen_top_narrow = 2.05\n    overlen_bottom_narrow = 2.05\n    pad_smd=[2.44,1.12]\n    pinrow_distance_smd=8.61\n    switch_width_piano=1.8\n    switch_height_piano=1.5\n    package_width_piano=10.8\n    overlen_top_piano = 2.05\n    overlen_bottom_piano = 2.05\n\n    for p in pins:\n        makeDIPSwitch(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad, switch_width, switch_height, 'Slide', False, [])\n        makeDIPSwitch(p, rm, pinrow_distance, package_width_narrow, overlen_top_narrow, overlen_bottom_narrow, ddrill, pad, switch_width_narrow, switch_height_narrow, 'Slide', False, [\"LowProfile\"])\n        makeDIPSwitch(p, rm, pinrow_distance_smd, package_width_narrow, overlen_top_narrow, overlen_bottom_narrow, ddrill, pad_smd, switch_width_narrow, switch_height_narrow, 'Slide', True,[\"SMD\",\"LowProfile\"], 'Buttons_Switches_SMD')\n        makeDIPSwitch(p, rm, pinrow_distance, package_width_piano, overlen_top_piano, overlen_bottom_piano, ddrill, pad, switch_width_piano, switch_height_piano, 'Piano', False, [])\n\n    # Copal CVS DIP-switches (http://www.nidec-copal-electronics.com/e/catalog/switch/cvs.pdf):\n    pins = [2, 4, 6, 8, 16]\n    rm = 1\n    pinrow_distance = 5.9\n    package_width = 4.7\n    switch_width = 2\n    switch_height = 0.5\n    overlen_top = 1\n    overlen_bottom = 1\n    ddrill = 0\n    pad_smd = [1.2, 0.5]\n\n    for p in pins:\n        makeDIPSwitch(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, switch_width,\n                      switch_height, 'Slide', True, [\"Copal_CVS\"], \"Buttons_Switches_SMD\", [0, 0, 0], [1, 1, 1],\n                      [0, 0, 0], \"\", True, [0.7, 0.7], 0.2, 0)\n\n\n\n    # Omron A6H DIP-switches (https://www.omron.com/ecb/products/pdf/en-a6h.pdf):\n    pins = [4,8,12,16,20]\n    rm = 1.27\n    pinrow_distance = 6.15\n    package_width = 4.5\n    switch_width = 3.2\n    switch_height = 0.5\n    overlen_top = 1.27\n    overlen_bottom = 1.27\n    ddrill = 0\n    pad_smd = [1.25, 0.76]\n    \n    for p in pins:\n        makeDIPSwitch(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, switch_width,\n                      switch_height, 'Slide', True, [\"Omron_A6H\"], \"Buttons_Switches_SMD\", [0, 0, 0], [1, 1, 1],\n                      [0, 0, 0], \"\", True)\n\n    # Copal CHS DIP-switches (http://www.nidec-copal-electronics.com/e/catalog/switch/chs.pdf):\n    pins = [2, 4, 8, 12, 16, 20]\n    rm = 1.27\n    pinrow_distance = 5.08\n    pinrow_distanceB = 7.62\n    package_width = 5.4\n    switch_width = 3\n    switch_height = 0.5\n    overlen_top = 1.27\n    overlen_bottom = 1.27\n    ddrill = 0\n    pad_smd = [1.6, 0.76]\n    \n    for p in pins:\n        makeDIPSwitch(p, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, switch_width,\n                      switch_height, 'Slide', True, [\"Copal_CHS-A\"], \"Buttons_Switches_SMD\", [0, 0, 0], [1, 1, 1],\n                      [0, 0, 0], \"\", True)\n        makeDIPSwitch(p, rm, pinrow_distanceB, package_width, overlen_top, overlen_bottom, ddrill, pad_smd, switch_width,\n                      switch_height, 'Slide', True, [\"Copal_CHS-B\"], \"Buttons_Switches_SMD\", [0, 0, 0], [1, 1, 1],\n                      [0, 0, 0], \"\", True)\n\n    #\n    # Special DIP\n    #\n    # http://www.experimentalistsanonymous.com/diy/Datasheets/MN3005.pdf\n    #\n    # common settings\n    overlen_top=1.27\n    overlen_bottom=1.27\n    rm=2.54\n    ddrill=0.8\n    pad=[1.6,1.6]\n    pad_large=[2.4,1.6]\n    pad_smdsocket=[3.1,1.6]\n    pad_smdsocket_small=[1.6,1.6]\n\n    # narrow 7.62 DIPs\n    pins=[8]\n    pinrow_distance=7.62\n    package_width=6.35\n    socket_width=pinrow_distance+2.54\n    makeDIP(16, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad,       False, 0, 0, 0, prefix_name = '8', skip_pin = [3, 4, 5, 6, 11, 12, 13, 14], skip_count = True, right_cnt_start = 5)\n    socket_height = (p / 2 - 1) * rm + 2.54\n    makeDIP(16, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad,       False, socket_width, socket_height,0, [\"Socket\"],            prefix_name = '8', skip_pin = [3, 4, 5, 6, 11, 12, 13, 14], skip_count = True, right_cnt_start = 5)\n    makeDIP(16, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad_large, False, socket_width, socket_height,0, [\"Socket\",\"LongPads\"], prefix_name = '8', skip_pin = [3, 4, 5, 6, 11, 12, 13, 14], skip_count = True, right_cnt_start = 5)\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/Readme.md",
    "content": "# IPC gullwing generator\n\nThis generator uses IPC-7351B equations and fillet definitions to derive a footprint for gullwing style packages from the dimensions of the package. (The suggested footprint is generally ignored. It is only used to define the exposed pad if necessary to fulfill thermal or EMC requirements defined in the datasheet.)\nFillet size definitions can be changed by pointing to a personalized IPC parameter file. The script generates footprints in zero orientation version A (pin 1 at top left corner).\nPads are generated using rounded rectangle pads as suggested in preliminary releases of IPC-7351C.\n\nExamples of supported packages include: QFP, SOIC, SO.\n\n## Running the script\n\nThe script requires python 3.4 or newer. Run it with:\n`python3 ipc_gullwing_generator.py size_definitions/eqfp.yaml` (replace `eqfp.yaml` with the size definition file that contains your part.)\n\n### Optional script parameters\n\n* --global_config: the config file defining how the footprint will look like. (KLC) (default=`../../tools/global_config_files/config_KLCv3.0.yaml`)\n* --series_config: the config file defining series parameters (footprint naming). (default=`../package_config_KLCv3.yaml`)\n\n* --density: IPC density level (L,N,M) (default=`N`)\n* --ipc_doc: IPC definition document (default=`../ipc_definitions.yaml`)\n\n* --force_rectangle_pads: Force the generation of rectangle pads instead of rounded rectangle\n* --kicad4_compatible: Create footprints compatible with version 4 (avoids round-rect and custom pads).\n\n## Size definition format\n\nEvery file contains a header with parameters applied to all parts. These define the common footprint name prefix and the output library.\n\n``` yaml\nFileHeader:\n  library_Suffix: 'QFP' #resulting library name Package_QFP\n  device_type: 'EQFP' #footprint names will be of style ...EQFP-pincount_...\n```\n\n---\n\nEvery further entry in the script is assumed to be a package size definition. The top level parameter will give the internal parameter set name. It must be unique in this file and should be representative of the footprint as it will be used in error messages. (It also makes later maintenance easier if it is easy to determine which footprint was generated by which parameter set.)\n\n``` yaml\ninternal_package_name:\n  # parameter list (See below)\n```\n\n### Documentation and naming parameters\n- Size source to be added to footprint documentation field (`size_source`) {url}\n- Footprint name generation control\n  - Manufacturer name. Will be added as a prefix if given. (`manufacturer`) {string}\n  - Part number. Will be added as a prefix if given. (`part_number`) {string}\n  - Suffix: A custom suffix (added after pin pitch in default naming format). Can include parameters `pad_x` and `pad_y`.\n  - Custom naming (`custom_name_format`) {python format string}\n    - The full default format string is `{man:s}_{mpn:s}_{pkg:s}-{pincount:d}-1EP_{size_x:g}x{size_y:g}mm_P{pitch:g}mm{suffix:s}_EP{ep_size_x:g}x{ep_size_y:g}mm_Mask{mask_size_x:g}x{mask_size_y:g}mm{suffix2:s}{vias:s}` (The same parameters can be used in your custom format. Exposed pad parameters are not available for components without exposed pad.)\n\n_Note: Contributions intended for the official library shall not include the manufacturer or part number unless the footprint is specific to that manufacturer or part. Similarly avoid custom naming for official library contributions unless required to achieve the requested name (Example TI-specific naming)._\n\n### Package dimensions\n![dimension example](./documentation/dimension_system.svg)\n- Body size (`body_size_x`, `body_size_y`, `overall_height`) {dimension}\n- Lead dimensions:\n  - Overall size representing lead tip to lead tip dimension (`overall_size_x`, `overall_size_y`) {dimension}\n  - Lead width (`lead_width`) {dimension}\n  - Lead length distance between the lead bend and lead tip (`lead_len`) {dimension}\n- Lead pitch, currently equal for all sides (`pitch`) {float}\n\n### Pad count\n- Pad count (`num_pins_x`, `num_pins_y`) {int}\n  - `num_pins_x`=0 is used for generating SOIC-like packages.\n  - `num_pins_y`=0 is used to generate SOIC-like package footprints but with inverted pin numbering. (Mirrored numbering scheme. Some manufactures use this style in their datasheets. Make sure you are not looking at the bottom view before using this. Not supported for QFP and similar.)\n- Exclude pads by pad number (`exclude_pin_list`) {[`pad number`]}\n\n### Exposed pad handling:\n![exposed pad example](../documentation/ep_handling.svg)\n- Size of package exposed pad or slug (`EP_size_x`, `EP_size_y`) {dimension}\n- Size of the footprint pad [optional] (`EP_size_x_overwrite`, `EP_size_y_overwrite`) {float}\n   - Pad size is equal to nominal package pad size if not given.\n   - Use this to create a soldermask-defined pad.\n- Optional the size of the mask cutout (`EP_mask_x`, `EP_mask_y`) {float}\n   - Use to create soldermask-defined pads (in combination with `EP_size_x_overwrite`)\n- Paste is split into a regular grid with (`EP_num_paste_pads`) {[int (x), int (y)]}\n  - The optional paste coverage multiplier determines how much of the exposed copper area is covered by paste. (`EP_paste_coverage`) {float (0..1), default=0.65}\n\n### Rounding of exposed pad features\nIPC excludes exposed pads from the requirement for rounding its corners. By default the exposed pad does therefore not use rounded corners. Some datasheets do however suggest the use of rounded corners either specified to a specific value or they appear to be equal to the normal pads.\n\n![rounded exposed pad example](../documentation/ep_handling_rounded.svg)\n\n- Paste corner rounding is controlled by global config parameters `paste_radius_ratio` and\n`paste_maximum_radius` {float}\n- The round radius of the exposed pad can be directly set with `EP_round_radius` {float/\"pad\"}\n  - The string \"pad\" can be used to force the same radius for the exposed pad as for the normal pads.\n  - Alternatively the round radius ratio and max radius can be set using (`EP_round_radius_ratio`, `EP_maximum_radius`) {float}\n    - Both these can be set per-footprint or in the global config file.\n\n### Thermal vias\nA package with exposed pad can generate a version with thermal vias. This will be generated in addition to the normal version.\n\n![exposed pad example](../documentation/thermal_vias.svg)\n\n``` yaml\n  thermal_vias:\n    # thermal via version parameters\n```\n- Number of vias generated in the regular grid (`count`) {[int (x), int (y)]}\n- Final hole size (`drill`) {float}\n- Optional grid (`grid`) {[float (x), float (y)]}\n  - Auto-generated if not given (outermost pad will touch pad edge).\n- Paste coverage overwrite [optional] (`EP_paste_coverage`) {float (0..1)}\n  - Thermal via version might need higher paste coverage compared to non-via version to compensate solder lost due to wicking.\n- Paste generator can be set up to avoid placing paste on top of vias (`paste_avoid_via`) {bool}\n  - Clearance between via hole and paste (`paste_via_clearance`) {float}\n  - Can lead to math exceptions. Possible fixes:\n     - Reduce paste coverage (make sure you still have enough paste)\n     - Play with the via grid and number of paste pads (having an outer ring of paste pads often helps. This is only possible if there is space on the outside)\n     - If no fix is satisfactory then select avoid vias as false and increase paste coverage to combat solder loss.\n- Number paste pads\n  - Quantity of paste pads (`EP_num_paste_pads`) {[int (x), int (y)]}\n  - Alternative available if `paste_avoid_via` is true\n    - Number of paste pads between 4 vias (`paste_between_vias`) {[int (x), int (y)]}\n    - Number of additional paste pad rings outside the outermost vias [optional] (`paste_rings_outside`) {[int (x), int (y)]}\n\n\n## Dimension parameter format\nDimensions in datasheets are either given with minimum and maximum value (optionally including nominal) or with the nominal value plus a tolerance. Some values of the datasheet are given as reference value without tolerance. (Tolerances in this measurement are already included in other dimensions.) The script reflects this by offering the same options.\n\nAlways include the nominal dimension if the tolerance is asymmetrical as the resulting footprint will differ if it is not included.\n\n_Note: Contributions that are intended for the official KiCad library must use the same dimensioning format as the datasheet. (If min, nom and max are given then all 3 must be entered into the YAML file even if the tolerance is symmetrical. Similarly use nominal plus tolerance format if the datasheet is dimensioned this way.)_\n\n### String-based\n\nThe parameter can be given as a string in one of the following formats (white space characters are ignored).\n\n```yaml\nparameter_name: 1.2 # nominal only (reference dimension marked as such in datasheet)\nparameter_name: 1.1 .. 1.2 .. 1.3 # min .. nominal .. max\nparameter_name: 1.1 .. 1.3 # min .. max\nparameter_name: 1.2 +/-0.1 # nominal plus symmetrical tolerance\nparameter_name: 1.2 +0.1 -0.05 # nominal plus asymmetrical tolerance\n```\n\n### Dict-based\n\n```yaml\nparameter_name: # nominal only\n  nominal: 1.2\n  tolerance: 0 # optional to make it clear that this is the case\nparameter_name: # minimum maximum and nominal\n  minimum: 1.1\n  nominal: 1.2\n  maximum: 1.3\nparameter_name: # minimum maximum\n  minimum: 1.1\n  maximum: 1.3\nparameter_name: # nominal with symmetrical tolerance\n  nominal: 1.2\n  tolerance: 0.1\nparameter_name: # nominal with asymmetrical tolerance\n  nominal: 1.2\n  tolerance: [-0.05, 0.1] # order does not matter, the sign is important.\n```\n\n### Deprecated format\n\nSupport for this format will be dropped in the future. This format only supports min, nom, max dimensioning.\n\n```yaml\nparameter_name_min: 1.1\nparameter_name: 1.2\nparameter_name_max: 1.3\n```\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/ipc_gullwing_generator.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nimport argparse\nimport yaml\nimport math\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\n\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\nfrom ipc_pad_size_calculators import *\nfrom quad_dual_pad_border import add_dual_or_quad_pad_border\nfrom drawing_tools import nearestSilkPointOnOrthogonalLine\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"utils\"))\nfrom ep_handling_utils import getEpRoundRadiusParams\n\nipc_density = 'nominal'\nipc_doc_file = '../ipc_definitions.yaml'\n\nDEFAULT_PASTE_COVERAGE = 0.65\nDEFAULT_VIA_PASTE_CLEARANCE = 0.15\nDEFAULT_MIN_ANNULAR_RING = 0.15\n\ndef roundToBase(value, base):\n    return round(value/base) * base\n\nclass Gullwing():\n    def __init__(self, configuration):\n        self.configuration = configuration\n        with open(ipc_doc_file, 'r') as ipc_stream:\n            try:\n                self.ipc_defintions = yaml.safe_load(ipc_stream)\n\n                self.configuration['min_ep_to_pad_clearance'] = 0.2\n\n                #ToDo: find a settings file that can contain these.\n                self.configuration['paste_radius_ratio'] = 0.25\n                self.configuration['paste_maximum_radius'] = 0.25\n\n                if 'ipc_generic_rules' in self.ipc_defintions:\n                    self.configuration['min_ep_to_pad_clearance'] = self.ipc_defintions['ipc_generic_rules'].get('min_ep_to_pad_clearance', 0.2)\n\n            except yaml.YAMLError as exc:\n                print(exc)\n\n    def calcPadDetails(self, device_dimensions, EP_size, ipc_data, ipc_round_base):\n        # Zmax = Lmin + 2JT + √(CL^2 + F^2 + P^2)\n        # Gmin = Smax − 2JH − √(CS^2 + F^2 + P^2)\n        # Xmax = Wmin + 2JS + √(CW^2 + F^2 + P^2)\n\n        # Some manufacturers do not list the terminal spacing (S) in their datasheet but list the terminal lenght (T)\n        # Then one can calculate\n        # Stol(RMS) = √(Ltol^2 + 2*^2)\n        # Smin = Lmin - 2*Tmax\n        # Smax(RMS) = Smin + Stol(RMS)\n\n        manf_tol = {\n            'F': self.configuration.get('manufacturing_tolerance', 0.1),\n            'P': self.configuration.get('placement_tolerance', 0.05)\n        }\n\n        Gmin_x, Zmax_x, Xmax = ipc_gull_wing(\n                ipc_data, ipc_round_base, manf_tol,\n                device_dimensions['lead_width'],\n                device_dimensions['overall_size_x'],\n                lead_len=device_dimensions.get('lead_len'),\n                heel_reduction=device_dimensions.get('heel_reduction', 0)\n                )\n\n        Gmin_y, Zmax_y, Xmax_y_ignored = ipc_gull_wing(\n                ipc_data, ipc_round_base, manf_tol,\n                device_dimensions['lead_width'],\n                device_dimensions['overall_size_y'],\n                lead_len=device_dimensions.get('lead_len'),\n                heel_reduction=device_dimensions.get('heel_reduction', 0)\n                )\n\n        min_ep_to_pad_clearance = configuration['min_ep_to_pad_clearance']\n\n        heel_reduction_max = 0\n\n        if Gmin_x - 2*min_ep_to_pad_clearance < EP_size['x']:\n            heel_reduction_max = ((EP_size['x'] + 2*min_ep_to_pad_clearance - Gmin_x)/2)\n            #print('{}, {}, {}'.format(Gmin_x, EP_size['x'], min_ep_to_pad_clearance))\n            Gmin_x = EP_size['x'] + 2*min_ep_to_pad_clearance\n        if Gmin_y - 2*min_ep_to_pad_clearance < EP_size['y']:\n            heel_reduction = ((EP_size['y'] + 2*min_ep_to_pad_clearance - Gmin_y)/2)\n            if heel_reduction>heel_reduction_max:\n                heel_reduction_max = heel_reduction\n            Gmin_y = EP_size['y'] + 2*min_ep_to_pad_clearance\n\n        Pad = {}\n        Pad['left'] = {'center':[-(Zmax_x+Gmin_x)/4, 0], 'size':[(Zmax_x-Gmin_x)/2,Xmax]}\n        Pad['right'] = {'center':[(Zmax_x+Gmin_x)/4, 0], 'size':[(Zmax_x-Gmin_x)/2,Xmax]}\n        Pad['top'] = {'center':[0,-(Zmax_y+Gmin_y)/4], 'size':[Xmax,(Zmax_y-Gmin_y)/2]}\n        Pad['bottom'] = {'center':[0,(Zmax_y+Gmin_y)/4], 'size':[Xmax,(Zmax_y-Gmin_y)/2]}\n\n        return Pad\n\n    @staticmethod\n    def deviceDimensions(device_size_data):\n        dimensions = {\n            'body_size_x': TolerancedSize.fromYaml(device_size_data, base_name='body_size_x'),\n            'body_size_y': TolerancedSize.fromYaml(device_size_data, base_name='body_size_y'),\n            'lead_width': TolerancedSize.fromYaml(device_size_data, base_name='lead_width'),\n            'lead_len': TolerancedSize.fromYaml(device_size_data, base_name='lead_len')\n        }\n        dimensions['has_EP'] = False\n        if 'EP_size_x_min' in device_size_data and 'EP_size_x_max' in device_size_data or 'EP_size_x' in device_size_data:\n            dimensions['EP_size_x'] = TolerancedSize.fromYaml(device_size_data, base_name='EP_size_x')\n            dimensions['EP_size_y'] = TolerancedSize.fromYaml(device_size_data, base_name='EP_size_y')\n            dimensions['has_EP'] = True\n\n        if 'EP_mask_x' in device_size_data:\n            dimensions['EP_mask_x'] = TolerancedSize.fromYaml(device_size_data, base_name='EP_mask_x')\n            dimensions['EP_mask_y'] = TolerancedSize.fromYaml(device_size_data, base_name='EP_mask_y')\n\n        dimensions['heel_reduction'] = device_size_data.get('heel_reduction', 0)\n\n        if 'overall_size_x' in device_size_data or 'overall_size_y' in device_size_data:\n            if 'overall_size_x' in device_size_data:\n                dimensions['overall_size_x'] = TolerancedSize.fromYaml(device_size_data, base_name='overall_size_x')\n            else:\n                dimensions['overall_size_x'] = TolerancedSize.fromYaml(device_size_data, base_name='overall_size_y')\n\n            if 'overall_size_y' in device_size_data:\n                dimensions['overall_size_y'] = TolerancedSize.fromYaml(device_size_data, base_name='overall_size_y')\n            else:\n                dimensions['overall_size_y'] = TolerancedSize.fromYaml(device_size_data, base_name='overall_size_x')\n        else:\n            raise KeyError(\"Either overall size x or overall size y must be given (Outside to outside lead dimensions)\")\n\n        return dimensions\n\n    def generateFootprint(self, device_params, header):\n        dimensions = Gullwing.deviceDimensions(device_params)\n\n        if 'deleted_pins' in device_params:\n            if type(device_params['deleted_pins']) is int:\n                device_params['deleted_pins'] = [device_params['deleted_pins']]\n\n        if 'hidden_pins' in device_params:\n            if type(device_params['hidden_pins']) is int:\n                device_params['hidden_pins'] = [device_params['hidden_pins']]\n\n        if 'deleted_pins' in device_params and 'hidden_pins' in device_params:\n            print(\"A footprint may not have deleted pins and hidden pins.\")\n        else:\n            if dimensions['has_EP'] and 'thermal_vias' in device_params:\n                self.__createFootprintVariant(device_params, header, dimensions, True)\n\n            self.__createFootprintVariant(device_params, header, dimensions, False)\n\n    def __createFootprintVariant(self, device_params, header, dimensions, with_thermal_vias):\n        fab_line_width = self.configuration.get('fab_line_width', 0.1)\n        silk_line_width = self.configuration.get('silk_line_width', 0.12)\n\n        lib_name = self.configuration['lib_name_format_string'].format(category=header['library_Suffix'])\n\n        size_x = dimensions['body_size_x'].nominal\n        size_y = dimensions['body_size_y'].nominal\n\n        pincount_full = device_params['num_pins_x']*2 + device_params['num_pins_y']*2\n        \n        if 'hidden_pins' in device_params:\n            pincount_text = '{}-{}'.format(pincount_full - len(device_params['hidden_pins']), pincount_full)\n            pincount = pincount_full - len(device_params['hidden_pins'])\n        elif 'deleted_pins' in device_params:\n            pincount_text = '{}-{}'.format(pincount_full, pincount_full - len(device_params['deleted_pins']))\n            pincount = pincount_full - len(device_params['deleted_pins'])\n        else:\n            pincount_text = '{}'.format(pincount_full)\n            pincount = pincount_full\n\n        ipc_reference = 'ipc_spec_gw_large_pitch' if device_params['pitch'] >= 0.625 else 'ipc_spec_gw_small_pitch'\n        if device_params.get('force_small_pitch_ipc_definition', False):\n            ipc_reference = 'ipc_spec_gw_small_pitch'\n\n        used_density = device_params.get('ipc_density', ipc_density)\n        ipc_data_set = self.ipc_defintions[ipc_reference][used_density]\n        ipc_round_base = self.ipc_defintions[ipc_reference]['round_base']\n\n        pitch = device_params['pitch']\n\n        name_format = self.configuration['fp_name_format_string_no_trailing_zero_pincount_text']\n        EP_size = {'x':0, 'y':0}\n        EP_mask_size = {'x':0, 'y':0}\n\n        if dimensions['has_EP']:\n            name_format = self.configuration['fp_name_EP_format_string_no_trailing_zero_pincount_text']\n            if 'EP_size_x_overwrite' in device_params:\n                EP_size = {\n                    'x':device_params['EP_size_x_overwrite'],\n                    'y':device_params['EP_size_y_overwrite']\n                    }\n            else:\n                EP_size = {\n                    'x':dimensions['EP_size_x'].nominal,\n                    'y':dimensions['EP_size_y'].nominal\n                    }\n            if 'EP_mask_x' in dimensions:\n                name_format = self.configuration['fp_name_EP_custom_mask_format_string_no_trailing_zero_pincount_text']\n                EP_mask_size = {'x':dimensions['EP_mask_x'].nominal, 'y':dimensions['EP_mask_y'].nominal}\n        EP_size = Vector2D(EP_size)\n\n        pad_details = self.calcPadDetails(dimensions, EP_size, ipc_data_set, ipc_round_base)\n\n        if 'custom_name_format' in device_params:\n            name_format = device_params['custom_name_format']\n\n        suffix = device_params.get('suffix', '').format(pad_x=pad_details['left']['size'][0],\n            pad_y=pad_details['left']['size'][1])\n        suffix_3d = suffix if device_params.get('include_suffix_in_3dpath', 'True') == 'True' else \"\"\n        model3d_path_prefix = self.configuration.get('3d_model_prefix','${KISYS3DMOD}')\n\n        fp_name = name_format.format(\n            man=device_params.get('manufacturer',''),\n            mpn=device_params.get('part_number',''),\n            pkg=header['device_type'],\n            pincount=pincount_text,\n            size_y=size_y,\n            size_x=size_x,\n            pitch=device_params['pitch'],\n            ep_size_x = EP_size['x'],\n            ep_size_y = EP_size['y'],\n            mask_size_x = EP_mask_size['x'],\n            mask_size_y = EP_mask_size['y'],\n            suffix=suffix,\n            suffix2=\"\",\n            vias=self.configuration.get('thermal_via_suffix', '_ThermalVias') if with_thermal_vias else ''\n            ).replace('__','_').lstrip('_')\n\n        fp_name_2 = name_format.format(\n            man=device_params.get('manufacturer',''),\n            mpn=device_params.get('part_number',''),\n            pkg=header['device_type'],\n            pincount=pincount_text,\n            size_y=size_y,\n            size_x=size_x,\n            pitch=device_params['pitch'],\n            ep_size_x = EP_size['x'],\n            ep_size_y = EP_size['y'],\n            mask_size_x = EP_mask_size['x'],\n            mask_size_y = EP_mask_size['y'],\n            suffix=suffix_3d,\n            suffix2=\"\",\n            vias=''\n            ).replace('__','_').lstrip('_')\n\n        model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'\\\n            .format(\n                model3d_path_prefix=model3d_path_prefix, lib_name=lib_name,\n                fp_name=fp_name_2)\n        #print(fp_name)\n        #print(pad_details)\n\n        kicad_mod = Footprint(fp_name)\n\n        # init kicad footprint\n        kicad_mod.setDescription(\n            \"{manufacturer} {mpn} {package}, {pincount} Pin ({datasheet}), generated with kicad-footprint-generator {scriptname}\"\\\n            .format(\n                manufacturer = device_params.get('manufacturer',''),\n                package = header['device_type'],\n                mpn = device_params.get('part_number',''),\n                pincount = pincount,\n                datasheet = device_params['size_source'],\n                scriptname = os.path.basename(__file__).replace(\"  \", \" \")\n                ).lstrip())\n\n        kicad_mod.setTags(self.configuration['keyword_fp_string']\\\n            .format(\n                man=device_params.get('manufacturer',''),\n                package=header['device_type'],\n                category=header['library_Suffix']\n            ).lstrip())\n        kicad_mod.setAttribute('smd')\n\n        if 'custom_pad_layout' in device_params:\n            pad_radius = add_custom_pad_layout(kicad_mod, configuration, pad_details, device_params)\n        else:\n            pad_radius = add_dual_or_quad_pad_border(kicad_mod, configuration, pad_details, device_params)\n\n        EP_round_radius = 0\n        if dimensions['has_EP']:\n            pad_shape_details = getEpRoundRadiusParams(device_params, self.configuration, pad_radius)\n            EP_mask_size = EP_mask_size if EP_mask_size['x'] > 0 else None\n\n            if with_thermal_vias:\n                thermals = device_params['thermal_vias']\n                paste_coverage = thermals.get('EP_paste_coverage',\n                                               device_params.get('EP_paste_coverage', DEFAULT_PASTE_COVERAGE))\n\n                EP = ExposedPad(\n                    number=pincount+1, size=EP_size, mask_size=EP_mask_size,\n                    paste_layout=thermals.get('EP_num_paste_pads'),\n                    paste_coverage=paste_coverage,\n                    via_layout=thermals.get('count', 0),\n                    paste_between_vias=thermals.get('paste_between_vias'),\n                    paste_rings_outside=thermals.get('paste_rings_outside'),\n                    via_drill=thermals.get('drill', 0.3),\n                    via_grid=thermals.get('grid'),\n                    paste_avoid_via=thermals.get('paste_avoid_via', True),\n                    via_paste_clarance=thermals.get('paste_via_clearance', DEFAULT_VIA_PASTE_CLEARANCE),\n                    min_annular_ring=thermals.get('min_annular_ring', DEFAULT_MIN_ANNULAR_RING),\n                    bottom_pad_min_size=thermals.get('bottom_min_size', 0),\n                    **pad_shape_details\n                    )\n            else:\n                EP = ExposedPad(\n                    number=pincount+1, size=EP_size, mask_size=EP_mask_size,\n                    paste_layout=device_params.get('EP_num_paste_pads', 1),\n                    paste_coverage=device_params.get('EP_paste_coverage', DEFAULT_PASTE_COVERAGE),\n                    **pad_shape_details\n                    )\n\n            kicad_mod.append(EP)\n            EP_round_radius = EP.getRoundRadius()\n\n        body_edge = {\n            'left': -dimensions['body_size_x'].nominal/2,\n            'right': dimensions['body_size_x'].nominal/2,\n            'top': -dimensions['body_size_y'].nominal/2,\n            'bottom': dimensions['body_size_y'].nominal/2\n            }\n\n        bounding_box = {\n            'left': pad_details['left']['center'][0] - pad_details['left']['size'][0]/2,\n            'right': pad_details['right']['center'][0] + pad_details['right']['size'][0]/2,\n            'top': pad_details['top']['center'][1] - pad_details['top']['size'][1]/2,\n            'bottom': pad_details['bottom']['center'][1] + pad_details['bottom']['size'][1]/2\n        }\n\n        if device_params['num_pins_x'] == 0:\n            bounding_box['top'] = body_edge['top']\n            bounding_box['bottom'] = body_edge['bottom']\n            if EP_size['y'] > dimensions['body_size_y'].nominal:\n                bounding_box['top'] = -EP_size['y']/2\n                bounding_box['bottom'] = EP_size['y']/2\n\n        if device_params['num_pins_y'] == 0:\n            bounding_box['left'] = body_edge['left']\n            bounding_box['right'] = body_edge['right']\n            if EP_size['x'] > dimensions['body_size_x'].nominal:\n                bounding_box['left'] = -EP_size['x']/2\n                bounding_box['right'] = EP_size['x']/2\n\n\n        pad_width = pad_details['top']['size'][0]\n\n        # ############################ SilkS ##################################\n        silk_pad_offset = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n        silk_offset = configuration['silk_fab_offset']\n\n        right_pads_silk_bottom = (device_params['num_pins_y']-1)*device_params['pitch']/2\\\n            +pad_details['right']['size'][1]/2+silk_pad_offset\n        silk_bottom = body_edge['bottom']+silk_offset\n        if EP_size['y']/2 <= body_edge['bottom'] and right_pads_silk_bottom >= silk_bottom:\n            silk_bottom = max(silk_bottom, EP_size['y']/2+silk_pad_offset)\n\n        silk_bottom = max(silk_bottom, right_pads_silk_bottom)\n        silk_bottom = min(body_edge['bottom']+silk_pad_offset, silk_bottom)\n\n        bottom_pads_silk_right = (device_params['num_pins_x']-1)*device_params['pitch']/2\\\n            +pad_details['bottom']['size'][0]/2+silk_pad_offset\n        silk_right = body_edge['right']+silk_offset\n        if EP_size['x']/2 <= body_edge['right'] and bottom_pads_silk_right >= silk_right:\n            silk_right = max(silk_right, EP_size['x']/2+silk_pad_offset)\n        silk_right = max(silk_right, bottom_pads_silk_right)\n        silk_right = min(body_edge['right']+silk_pad_offset, silk_right)\n\n\n        min_lenght = configuration.get('silk_line_lenght_min', 0)\n        silk_corner_bottom_right = Vector2D(silk_right, silk_bottom)\n\n        silk_point_bottom_inside = nearestSilkPointOnOrthogonalLine(\n            pad_size=EP_size,\n            pad_position=[0, 0],\n            pad_radius=EP_round_radius,\n            fixed_point=silk_corner_bottom_right,\n            moving_point=Vector2D(0, silk_bottom),\n            silk_pad_offset=silk_pad_offset,\n            min_lenght=min_lenght)\n\n        if silk_point_bottom_inside is not None and device_params['num_pins_x'] > 0:\n            silk_point_bottom_inside = nearestSilkPointOnOrthogonalLine(\n                pad_size=pad_details['bottom']['size'],\n                pad_position=[\n                    pad_details['bottom']['center'][0]+(device_params['num_pins_x']-1)/2*pitch,\n                    pad_details['bottom']['center'][1]],\n                pad_radius=pad_radius,\n                fixed_point=silk_corner_bottom_right,\n                moving_point=silk_point_bottom_inside,\n                silk_pad_offset=silk_pad_offset,\n                min_lenght=min_lenght)\n\n        silk_point_right_inside = nearestSilkPointOnOrthogonalLine(\n            pad_size=EP_size,\n            pad_position=[0, 0],\n            pad_radius=EP_round_radius,\n            fixed_point=silk_corner_bottom_right,\n            moving_point=Vector2D(silk_right, 0),\n            silk_pad_offset=silk_pad_offset,\n            min_lenght=min_lenght)\n        if silk_point_right_inside is not None and device_params['num_pins_y'] > 0:\n            silk_point_right_inside = nearestSilkPointOnOrthogonalLine(\n                pad_size=pad_details['right']['size'],\n                pad_position=[\n                    pad_details['right']['center'][0],\n                    pad_details['right']['center'][1]+(device_params['num_pins_y']-1)/2*pitch],\n                pad_radius=pad_radius,\n                fixed_point=silk_corner_bottom_right,\n                moving_point=silk_point_right_inside,\n                silk_pad_offset=silk_pad_offset,\n                min_lenght=min_lenght)\n\n        if silk_point_bottom_inside is None and silk_point_right_inside is not None:\n            silk_corner_bottom_right['y'] = body_edge['bottom']\n            silk_corner_bottom_right = nearestSilkPointOnOrthogonalLine(\n                pad_size=pad_details['bottom']['size'],\n                pad_position=[\n                    pad_details['bottom']['center'][0]+(device_params['num_pins_x']-1)/2*pitch,\n                    pad_details['bottom']['center'][1]],\n                pad_radius=pad_radius,\n                fixed_point=silk_point_right_inside,\n                moving_point=silk_corner_bottom_right,\n                silk_pad_offset=silk_pad_offset,\n                min_lenght=min_lenght)\n\n        elif silk_point_right_inside is None and silk_point_bottom_inside is not None:\n            silk_corner_bottom_right['x'] = body_edge['right']\n            silk_corner_bottom_right = nearestSilkPointOnOrthogonalLine(\n                pad_size=pad_details['right']['size'],\n                pad_position=[\n                    pad_details['right']['center'][0],\n                    pad_details['right']['center'][1]+(device_params['num_pins_y']-1)/2*pitch],\n                pad_radius=pad_radius,\n                fixed_point=silk_point_bottom_inside,\n                moving_point=silk_corner_bottom_right,\n                silk_pad_offset=silk_pad_offset,\n                min_lenght=min_lenght)\n\n        poly_bottom_right = []\n        if silk_point_bottom_inside is not None:\n            poly_bottom_right.append(silk_point_bottom_inside)\n        poly_bottom_right.append(silk_corner_bottom_right)\n        if silk_point_right_inside is not None:\n            poly_bottom_right.append(silk_point_right_inside)\n\n        if len(poly_bottom_right) > 1 and silk_corner_bottom_right is not None:\n            kicad_mod.append(PolygoneLine(\n                polygone=poly_bottom_right,\n                width=configuration['silk_line_width'],\n                layer=\"F.SilkS\"))\n            kicad_mod.append(PolygoneLine(\n                polygone=poly_bottom_right,\n                width=configuration['silk_line_width'],\n                layer=\"F.SilkS\", x_mirror=0))\n            kicad_mod.append(PolygoneLine(\n                polygone=poly_bottom_right,\n                width=configuration['silk_line_width'],\n                layer=\"F.SilkS\", y_mirror=0))\n\n            if device_params['num_pins_y'] > 0:\n                if len(poly_bottom_right)>2:\n                    kicad_mod.append(PolygoneLine(\n                        polygone=poly_bottom_right,\n                        width=configuration['silk_line_width'],\n                        layer=\"F.SilkS\", y_mirror=0, x_mirror=0))\n                    kicad_mod.append(Line(\n                        start={'x': -silk_right, 'y': -right_pads_silk_bottom},\n                        end={'x': bounding_box['left'], 'y': -right_pads_silk_bottom},\n                        width=configuration['silk_line_width'],\n                        layer=\"F.SilkS\"))\n                elif silk_corner_bottom_right['y'] >= right_pads_silk_bottom and silk_point_bottom_inside is not None:\n                    kicad_mod.append(Line(\n                        start=-silk_point_bottom_inside,\n                        end={'x': bounding_box['left'], 'y': -silk_point_bottom_inside['y']},\n                        width=configuration['silk_line_width'],\n                        layer=\"F.SilkS\"))\n            else:\n                if len(poly_bottom_right)>2:\n                    poly_bottom_right[0]['x']=bottom_pads_silk_right\n                    kicad_mod.append(PolygoneLine(\n                        polygone=poly_bottom_right,\n                        width=configuration['silk_line_width'],\n                        layer=\"F.SilkS\", y_mirror=0, x_mirror=0))\n                    kicad_mod.append(Line(\n                        start={'x': -bottom_pads_silk_right, 'y': -silk_corner_bottom_right['y']},\n                        end={'x': -bottom_pads_silk_right, 'y': bounding_box['top']},\n                        width=configuration['silk_line_width'],\n                        layer=\"F.SilkS\"))\n                elif silk_corner_bottom_right['x'] >= bottom_pads_silk_right and silk_point_right_inside is not None:\n                    kicad_mod.append(Line(\n                        start=-silk_point_right_inside,\n                        end={'x': -silk_point_right_inside['x'], 'y': bounding_box['top']},\n                        width=configuration['silk_line_width'],\n                        layer=\"F.SilkS\"))\n\n        # # ######################## Fabrication Layer ###########################\n\n        fab_bevel_size = min(configuration['fab_bevel_size_absolute'], configuration['fab_bevel_size_relative']*min(size_x, size_y))\n\n        poly_fab = [\n            {'x': body_edge['left']+fab_bevel_size, 'y': body_edge['top']},\n            {'x': body_edge['right'], 'y': body_edge['top']},\n            {'x': body_edge['right'], 'y': body_edge['bottom']},\n            {'x': body_edge['left'], 'y': body_edge['bottom']},\n            {'x': body_edge['left'], 'y': body_edge['top']+fab_bevel_size},\n            {'x': body_edge['left']+fab_bevel_size, 'y': body_edge['top']},\n        ]\n\n        kicad_mod.append(PolygoneLine(\n            polygone=poly_fab,\n            width=configuration['fab_line_width'],\n            layer=\"F.Fab\"))\n\n        # # ############################ CrtYd ##################################\n\n        off = ipc_data_set['courtyard']\n        grid = configuration['courtyard_grid']\n\n        if device_params['num_pins_y'] == 0 or device_params['num_pins_x'] == 0:\n            cy1=roundToBase(bounding_box['top']-off, grid)\n\n            kicad_mod.append(RectLine(\n                start={\n                    'x':roundToBase(bounding_box['left']-off, grid),\n                    'y':cy1\n                    },\n                end={\n                    'x':roundToBase(bounding_box['right']+off, grid),\n                    'y':roundToBase(bounding_box['bottom']+off, grid)\n                    },\n                width=configuration['courtyard_line_width'],\n                layer='F.CrtYd'))\n\n        else:\n            cy1=roundToBase(bounding_box['top']-off, grid)\n            cy2=roundToBase(body_edge['top']-off, grid)\n            cy3=-roundToBase(\n                device_params['pitch']*(device_params['num_pins_y']-1)/2.0\n                + pad_width/2.0 + off, grid)\n\n\n\n            cx1=-roundToBase(\n                device_params['pitch']*(device_params['num_pins_x']-1)/2.0\n                + pad_width/2.0 + off, grid)\n            cx2=roundToBase(body_edge['left']-off, grid)\n            cx3=roundToBase(bounding_box['left']-off, grid)\n\n\n            crty_poly_tl = [\n                {'x':0, 'y':cy1},\n                {'x':cx1, 'y':cy1},\n                {'x':cx1, 'y':cy2},\n                {'x':cx2, 'y':cy2},\n                {'x':cx2, 'y':cy3},\n                {'x':cx3, 'y':cy3},\n                {'x':cx3, 'y':0}\n            ]\n            kicad_mod.append(PolygoneLine(polygone=crty_poly_tl,\n                layer='F.CrtYd', width=configuration['courtyard_line_width']))\n            kicad_mod.append(PolygoneLine(polygone=crty_poly_tl,\n                layer='F.CrtYd', width=configuration['courtyard_line_width'],\n                x_mirror=0))\n            kicad_mod.append(PolygoneLine(polygone=crty_poly_tl,\n                layer='F.CrtYd', width=configuration['courtyard_line_width'],\n                y_mirror=0))\n            kicad_mod.append(PolygoneLine(polygone=crty_poly_tl,\n                layer='F.CrtYd', width=configuration['courtyard_line_width'],\n                x_mirror=0, y_mirror=0))\n\n        # ######################### Text Fields ###############################\n\n        addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n            courtyard={'top': cy1, 'bottom': -cy1}, fp_name=fp_name, text_y_inside_position='center')\n\n        ##################### Output and 3d model ############################\n\n        kicad_mod.append(Model(filename=model_name))\n\n        output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n        if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n            os.makedirs(output_dir)\n        filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=fp_name)\n\n        file_handler = KicadFileHandler(kicad_mod)\n        file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints. See readme.md for details about the parameter file format.')\n    parser.add_argument('files', metavar='file', type=str, nargs='+',\n                        help='list of files holding information about what devices should be created.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../package_config_KLCv3.yaml')\n    parser.add_argument('--density', type=str, nargs='?', help='IPC density level (L,N,M)', default='N')\n    parser.add_argument('--ipc_doc', type=str, nargs='?', help='IPC definition document', default='../ipc_definitions.yaml')\n    parser.add_argument('--force_rectangle_pads', action='store_true', help='Force the generation of rectangle pads instead of rounded rectangle')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints compatible with version 4 (avoids round-rect and custom pads).')\n    args = parser.parse_args()\n\n    if args.density == 'L':\n        ipc_density = 'least'\n    elif args.density == 'M':\n        ipc_density = 'most'\n\n    ipc_doc_file = args.ipc_doc\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    if args.force_rectangle_pads or args.kicad4_compatible:\n        configuration['round_rect_max_radius'] = None\n        configuration['round_rect_radius_ratio'] = 0\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for filepath in args.files:\n        gw = Gullwing(configuration)\n\n        with open(filepath, 'r') as command_stream:\n            try:\n                cmd_file = yaml.safe_load(command_stream)\n            except yaml.YAMLError as exc:\n                print(exc)\n        header = cmd_file.pop('FileHeader')\n\n        for pkg in cmd_file:\n            print(\"generating part for parameter set {}\".format(pkg))\n            gw.generateFootprint(cmd_file[pkg], header)\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/eqfp.yaml",
    "content": "FileHeader:\n  library_Suffix: 'QFP'\n  device_type: 'EQFP'\n\nEQFP-144-1EP_20x20mm_P0.5mm_EP4x4mm:\n  size_source: 'https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/packaging/04r00482-02.pdf'\n  body_size_x:\n    nominal: 20\n  body_size_y:\n    nominal: 20\n  overall_size_x:\n    nominal: 22\n  overall_size_y:\n    nominal: 22\n  lead_width:\n    minimum: 0.17\n    nominal: 0.22\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 36\n  num_pins_y: 36\n\n  EP_size_x: 4\n  EP_size_y: 4\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.2, 1.2]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\nEQFP-144-1EP_20x20mm_P0.5mm_EP5x5mm:\n  size_source: 'https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/packaging/04r00476-02.pdf'\n  body_size_x:\n    nominal: 20\n  body_size_y:\n    nominal: 20\n  overall_size_x:\n    nominal: 22\n  overall_size_y:\n    nominal: 22\n  lead_width:\n    minimum: 0.17\n    nominal: 0.22\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 36\n  num_pins_y: 36\n\n  EP_size_x: 5\n  EP_size_y: 5\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.2, 1.2]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\nEQFP-144-1EP_20x20mm_P0.5mm_EP6.61x5.615mm:\n  size_source: 'https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/packaging/04r00485-02.pdf'\n  body_size_x:\n    nominal: 20\n  body_size_y:\n    nominal: 20\n  overall_size_x:\n    nominal: 22\n  overall_size_y:\n    nominal: 22\n  lead_width:\n    minimum: 0.17\n    nominal: 0.22\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 36\n  num_pins_y: 36\n\n  EP_size_x: 6.61\n  EP_size_y: 5.615\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [5, 4]\n\n  thermal_vias:\n    count: [5, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.3, 1.4]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\nEQFP-144-1EP_20x20mm_P0.5mm_EP7.2x6.35mm:\n  size_source: 'https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/packaging/04r00487-01.pdf'\n  body_size_x:\n    nominal: 20\n  body_size_y:\n    nominal: 20\n  overall_size_x:\n    nominal: 22\n  overall_size_y:\n    nominal: 22\n  lead_width:\n    minimum: 0.17\n    nominal: 0.22\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 36\n  num_pins_y: 36\n\n  EP_size_x: 7.2\n  EP_size_y: 6.35\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [6, 5]\n\n  thermal_vias:\n    count: [6, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.2, 1.2]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\nEQFP-144-1EP_20x20mm_P0.5mm_EP8.93x8.7mm:\n  size_source: 'https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/packaging/04r00479-02.pdf'\n  body_size_x:\n    nominal: 20\n  body_size_y:\n    nominal: 20\n  overall_size_x:\n    nominal: 22\n  overall_size_y:\n    nominal: 22\n  lead_width:\n    minimum: 0.17\n    nominal: 0.22\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 36\n  num_pins_y: 36\n\n  EP_size_x: 8.93\n  EP_size_y: 8.7\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [7, 7]\n\n  thermal_vias:\n    count: [7, 7]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.2, 1.2]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/hsoic.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'HSOIC'\n\nTexas_R-PDSO-G8_EP2.95x4.9mm_Mask2.4x3.1mm:\n  size_source: 'http://www.ti.com/lit/ds/symlink/lmr14030.pdf#page=28, http://www.ti.com/lit/ml/msoi002j/msoi002j.pdf'\n  custom_name_format: 'Texas_R-PDSO-G{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm_Mask{mask_size_x:g}x{mask_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 3.8\n    maximum: 4\n  body_size_y:\n    minimum: 4.8\n    maximum: 5\n\n  overall_size_x:\n    minimum: 5.8\n    maximum: 6.2\n  lead_width:\n    minimum: 0.31\n    maximum: 0.51\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\n\n  EP_size_x:\n    minimum: 1.65\n    maximum: 2.4\n  EP_size_x_overwrite: 2.95\n  EP_mask_x: 2.4\n\n  EP_size_y:\n    minimum: 2.65\n    maximum: 3.1\n  EP_size_y_overwrite: 4.9\n  EP_mask_y: 3.1\n\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 3]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 3]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    grid: [1.3, 1.3]\n    # bottom_pad_size:\n    paste_avoid_via: False\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/hsop.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'HSOP'\n\nHSOP-8-1EP_3.9x4.9mm_P1.27mm_EP2.41x3.1mm_ThermalVias:\n  size_source: 'https://www.st.com/resource/en/datasheet/l5973d.pdf'\n  body_size_x:\n    nominal: 3.9\n    tolerance: 0.1\n  body_size_y:\n    nominal: 4.9\n    tolerance: 0.1\n  overall_size_x:\n    nominal: 6\n    tolerance: 0.2\n  lead_width:\n    nominal: 0.42\n    tolerance: [0.04, 0.05]\n  lead_len:\n    nominal: 0.65\n    tolerance: 0.15\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\n\n  EP_size_x:\n    nominal: 2.41\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 3.1\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    # grid: [1.5, 1.5]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nHSOP-8-1EP_3.9x4.9mm_P1.27mm_EP2.3x2.3mm_ThermalVias:\n  size_source: 'https://www.st.com/resource/en/datasheet/l7980.pdf'\n  body_size_x:\n    nominal: 3.9\n    tolerance: 0.1\n  body_size_y:\n    nominal: 4.9\n    tolerance: 0.1\n  overall_size_x:\n    nominal: 6\n    tolerance: 0.2\n  lead_width:\n    minimum: 0.31\n    maximum: 0.51\n  lead_len:\n    minimum: 0.40\n    maximum: 1.27\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\n\n  EP_size_x:\n    nominal: 2.3\n  EP_size_y:\n    nominal: 2.3\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    # grid: [1.5, 1.5]\n    # bottom_pad_size:\n    paste_avoid_via: False\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/htsop.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'HTSOP'\n\nHTSOP-8-1EP_3.9x4.9mm_P1.27mm_EP2.4x3.2mm:\n  size_source: 'https://media.digikey.com/pdf/Data%20Sheets/Rohm%20PDFs/BD9G341EFJ.pdf'\n  body_size_x:\n    nominal: 3.9\n    tolerance: 0.1\n  body_size_y:\n    nominal: 4.9\n    tolerance: 0.1\n  overall_size_x:\n    nominal: 6\n    tolerance: 0.2\n  lead_width:\n    nominal: 0.42\n    tolerance: [0.04, 0.05]\n  lead_len:\n    nominal: 0.65\n    tolerance: 0.15\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\n\n  EP_size_x: 2.4\n  EP_size_y: 3.2\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    # grid: [1.5, 1.5]\n    # bottom_pad_size:\n    paste_avoid_via: False\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/htssop.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'HTSSOP'\n\n\nHTSSOP-16-1EP_4.4x5mm_P0.65mm_EP3x3mm:\n  size_source: 'https://www.st.com/resource/en/datasheet/stp08cp05.pdf#page=20'\n  body_size_x:\n    minimum: 4.3\n    nominal: 4.4\n    maximum: 4.5\n  body_size_y:\n    minimum: 4.9\n    nominal: 5\n    maximum: 5.1\n  body_height:\n    maximum: 1.2\n  overall_size_x:\n    minimum: 6.2\n    nominal: 6.4\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 8\n\n\n  EP_size_x:\n    nominal: 3\n  EP_size_y:\n    nominal: 3\n  EP_num_paste_pads: [2, 2]\n\n\nHTSSOP-16-1EP_4.4x5mm_P0.65mm_EP3.4x5mm_Mask2.46x2.31mm_ThermalVias:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  body_size_x:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_y:\n    minimum: 4.9\n    maximum: 5.1\n  overall_size_x:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 8\n\n\n  EP_size_x:\n    nominal: 3.4\n  EP_size_y:\n    nominal: 5\n  EP_mask_x: 2.46\n  EP_mask_y: 2.31\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [1, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.5, 1.5]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nHTSSOP-20-1EP_4.4x6.5mm_P0.65mm_EP3.4x6.5mm_Mask2.4x3.7mm:\n  size_source: 'http://www.ti.com/lit/ds/symlink/bq24006.pdf'\n  body_size_x:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_y:\n    minimum: 6.4\n    maximum: 6.6\n  overall_size_x:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 10\n\n\n  EP_size_x:\n    nominal: 3.4\n  EP_size_y:\n    nominal: 6.5\n  EP_mask_x: 2.4\n  EP_mask_y: 3.7\n  EP_num_paste_pads: [1, 2]\n\nHTSSOP-20-1EP_4.4x6.5mm_P0.65mm_EP2.85x4mm:\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0108.PDF U20E-1'\n  body_size_x:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_y:\n    minimum: 6.4\n    maximum: 6.6\n  body_height:\n    maximum: 1.1\n  overall_size_x:\n    minimum: 6.25\n    maximum: 6.5\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.7\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 10\n\n\n  EP_size_x:\n    minimum: 2.6\n    maximum: 3.1   \n  EP_size_y:\n    minimum: 3.8\n    maximum: 4.2\n  EP_num_paste_pads: [1, 2]\n\nHTSSOP-24-1EP_4.4x7.8mm_P0.65mm_EP3.2x5mm:\n  size_source: 'https://www.st.com/resource/en/datasheet/stp16cp05.pdf#page=25'\n  body_size_x:\n    minimum: 4.3\n    nominal: 4.4\n    maximum: 4.5\n  body_size_y:\n    minimum: 7.7\n    nominal: 7.8\n    maximum: 7.9\n  body_height:\n    maximum: 1.2\n  overall_size_x:\n    minimum: 6.2\n    nominal: 6.4\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 12\n\n\n  EP_size_x:\n    minimum: 3\n    nominal: 3.2\n    maximum: 3.4\n  EP_size_y:\n    minimum: 4.8\n    nominal: 5\n    maximum: 5.2\n  EP_num_paste_pads: [2, 3]\n\n\nHTSSOP-24-1EP_4.4x7.8mm_P0.65mm_EP3.4x7.8mm_Mask2.4x4.68mm_ThermalVias:\n  size_source: 'http://www.ti.com/lit/ds/symlink/tps703.pdf'\n  body_size_x:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_y:\n    minimum: 7.7\n    maximum: 7.9\n  overall_size_x:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 12\n\n\n  EP_size_x: 3.4\n  EP_size_y: 7.8\n  EP_mask_x: 2.4\n  EP_mask_y: 4.68\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 6]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [1, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.3, 1.3]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nHTSSOP-28-1EP_4.4x9.7mm_P0.65mm_EP2.85x5.4mm:\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0108.PDF'\n  body_size_x: 4.3 .. 4.5\n  body_size_y: 9.6 .. 9.8\n  overall_height:\n    maximum: 1.1\n  overall_size_x: 6.25 .. 6.5\n  lead_width: 0.19 .. 0.3\n  lead_len: 0.5 .. 0.7\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 14\n  EP_size_x: 2.6 .. 3.1\n  EP_size_y: 5.2 .. 5.6\n  thermal_vias:\n    count: [2, 4]\n    drill: 0.3\n    paste_avoid_via: false\n    EP_num_paste_pads: [1, 3]\n\nHTSSOP-44_6.1x14.0mm_P0.5mm_TopEP4.14x7.01mm:\n  size_source: 'http://www.ti.com/lit/ds/symlink/tpa3251.pdf#page=38'\n  custom_name_format: 'HTSSOP-{pincount}_{size_x:g}x{size_y:g}mm_P{pitch}mm_TopEP4.14x7.01mm'\n  body_size_x:\n    minimum: 6.0\n    maximum: 6.2\n  body_size_y:\n    minimum: 13.9\n    maximum: 14.1\n  overall_size_y:\n    minimum: 7.9\n    maximum: 8.3\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.635\n  num_pins_y: 22\n  num_pins_x: 0\n  #top_heatsink:\n    #x: 4.14\n    #y: 7.01\n\nTexas_PWP_R-PDSO-G14:\n# HTSSOP-14-1EP_4.4x5.0mm_P0.65mm_EP3.4x5.0mm_Mask3.0x3.1mm:\n  size_source: 'http://www.ti.com/lit/ds/symlink/lm5161.pdf#page=34'\n  #                    HTSSOP-14-        1EP_4.4x5.0                        mm_P0.65   mm_EP3.4x5.0                    mm_Mask3.0x3.1mm:\n  custom_name_format: 'HTSSOP-{pincount}-1EP_{size_x:g}x{size_y:g}mm_P{pitch}mm_EP{ep_size_x:g}x{ep_size_y:g}mm_Mask{mask_size_x:g}x{mask_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 4.3\n    nominal: 4.4\n    maximum: 4.5\n  body_size_y:\n    minimum: 4.9\n    nominal: 5.0\n    maximum: 5.1\n  overall_size_x:\n    minimum: 6.2\n    nominal: 6.4\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 7\n\n\n  EP_size_x: 3.4\n  EP_size_y: 5.0\n  EP_mask_x: 3.0\n  EP_mask_y: 3.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 5]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.3, 1.3]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nTexas_PWP_R-PDSO-G20:\n# HTSSOP-20-1EP_4.4x6.5mm_P0.65mm_EP3.4x6.5mm_Mask2.75x3.43mm:\n  size_source: 'http://www.ti.com/lit/ds/symlink/tlc5971.pdf#page=37&zoom=160,-90,3'\n  #                    HTSSOP-20-        1EP_4.4x6.5                        mm_P0.65   mm_EP3.4x6.5                    mm_Mask2.75x3.43mm:\n  custom_name_format: 'HTSSOP-{pincount}-1EP_{size_x:g}x{size_y:g}mm_P{pitch}mm_EP{ep_size_x:g}x{ep_size_y:g}mm_Mask{mask_size_x:g}x{mask_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_y:\n    minimum: 6.4\n    maximum: 6.6\n  overall_size_x:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 10\n\n\n  EP_size_x: 3.4\n  EP_size_y: 6.5\n  EP_mask_x: 2.75\n  EP_mask_y: 3.43\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 5]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.3, 1.3]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nTexas_PWP0020T:\n# HTSSOP-20-1EP_4.4x6.5mm_P0.65mm_EP3.4x6.5mm_Mask2.96x2.96mm:\n  size_source: 'https://www.ti.com/lit/ds/symlink/tps2663.pdf#page=49'\n  #                    HTSSOP-20-        1EP_4.4x6.5                        mm_P0.65   mm_EP3.4x6.5                    mm_Mask2.96x2.96mm:\n  custom_name_format: 'HTSSOP-{pincount}-1EP_{size_x:g}x{size_y:g}mm_P{pitch}mm_EP{ep_size_x:g}x{ep_size_y:g}mm_Mask{mask_size_x:g}x{mask_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_y:\n    minimum: 6.4\n    maximum: 6.6\n  overall_size_x:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 10\n  \n  EP_size_x: 2.16 .. 2.96\n  EP_size_x_overwrite: 3.4\n  EP_size_y: 2.21 .. 2.96\n  EP_size_y_overwrite: 6.5\n  EP_mask_x: 2.96\n  EP_mask_y: 2.96\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 1]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 5]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.3, 1.3]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nTexas_DAP_R-PDSO-G38:\n  # HTSSOP-38-1EP_6.1x12.5mm_P0.65mm_EP5.2x12.5mm_Mask3.39x6.35mm\n  size_source: 'http://www.ti.com/lit/ds/symlink/tlc5951.pdf#page=47&zoom=140,-67,15'\n  #                    HTSSOP-38-        1EP_6.1x12.5             mm_P0.65   mm_EP5.2x12.5                   mm_Mask3.39x6.35mm\n  custom_name_format: 'HTSSOP-{pincount}-1EP_{size_x:g}x{size_y:g}mm_P{pitch}mm_EP{ep_size_x:g}x{ep_size_y:g}mm_Mask{mask_size_x:g}x{mask_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 6.0\n    maximum: 6.2\n  body_size_y:\n    minimum: 12.4\n    maximum: 12.6\n  overall_size_x:\n    minimum: 7.9\n    maximum: 8.3\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 19\n\n\n  EP_size_x: 5.2\n  EP_size_y: 12.5\n  EP_mask_x: 3.39\n  EP_mask_y: 6.35\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 3]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [4, 10]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 3]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.3, 1.3]\n    # bottom_pad_size:\n    paste_avoid_via: False\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/hvssop.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'HVSSOP'\n\nHVSSOP-10-1EP_3x3mm_P0.5mm_EP1.57x1.88mm:\n  size_source: 'https://www.ti.com/lit/ds/symlink/bq24090.pdf'\n\n  body_size_x:\n    nominal: 3\n    tolerance: 0.100\n  body_size_y:\n    nominal: 3\n    tolerance: 0.100\n  overall_height:\n    maximum: 1.1\n\n  overall_size_x:\n    minimum: 4.75\n    maximum: 5.05\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.4\n    maximum: 0.7\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 5\n\n  EP_size_x:\n    nominal: 1.57\n  EP_size_y:\n    nominal: 1.88\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    EP_num_paste_pads: [2, 2]\n    paste_avoid_via: False"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/infineon.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'PG-DSO'\n\nInfineon_PG-DSO-8-27:\n  size_source: 'https://www.infineon.com/cms/en/product/packages/PG-DSO/PG-DSO-8-27'\n  manufacturer: Infineon\n  custom_name_format: '{man}_PG-DSO-{pincount}-27_{size_x:g}x{size_y:g}mm_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n\n  body_size_x: 3.9 +/-0.1\n  body_size_y: 4.9 +/-0.1\n  overall_height:\n    maximum: 1.7\n\n  overall_size_x: 6.0 +/-0.2\n  lead_width: 0.41 +/-0.09\n  lead_len: 0.64 +/-0.25\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x: 2.65 +/-0.2\n  EP_size_y: 3.0 +/-0.2\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    # grid: [1.3, 1.3]\n    # bottom_pad_size:\n    paste_avoid_via: False\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/lqfp.yaml",
    "content": "FileHeader:\n  library_Suffix: 'QFP'\n  device_type: 'LQFP'\n\nLQFP-32_5x5mm_P0.5mm:\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT401-1.pdf'\n  body_size_x:\n    minimum: 4.9\n    maximum: 5.1\n  body_size_y:\n    minimum: 4.9\n    maximum: 5.1\n  overall_size_x:\n    minimum: 6.85\n    maximum: 7.15\n  overall_size_y:\n    minimum: 6.85\n    maximum: 7.15\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n\nLQFP-32_7x7mm_P0.8mm:\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT358-1.pdf'\n  body_size_x:\n    minimum: 6.9\n    maximum: 7.1\n  body_size_y:\n    minimum: 6.9\n    maximum: 7.1\n  overall_size_x:\n    minimum: 8.85\n    maximum: 9.15\n  overall_size_y:\n    minimum: 8.85\n    maximum: 9.15\n  lead_width:\n    minimum: 0.3\n    maximum: 0.4\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.8\n  num_pins_x: 8\n  num_pins_y: 8\n\nLQFP-36_7x7mm_P0.65mm:\n  size_source: 'https://www.onsemi.com/pub/Collateral/561AV.PDF'\n  # ipc_density: 'least'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 7\n    tolerance: 0.1\n  body_size_y:\n    nominal: 7\n    tolerance: 0.1\n  overall_size_x:\n    nominal: 9\n    tolerance: 0.2\n  overall_size_y:\n    nominal: 9\n    tolerance: 0.2\n  lead_width:\n    nominal: 0.3\n    tolerance: 0.1\n  lead_len:\n    nominal: 0.5\n    tolerance: 0.2\n  pitch: 0.65\n  num_pins_x: 9\n  num_pins_y: 9\n\nLQFP-44_10x10mm_P0.8mm:\n  size_source: 'https://www.nxp.com/files-static/shared/doc/package_info/98ASS23225W.pdf?&fsrch=1'\n  body_size_x:\n    nominal: 10\n  body_size_y:\n    nominal: 10\n  overall_size_x:\n    nominal: 12\n  overall_size_y:\n    nominal: 12\n  lead_width:\n    minimum: 0.3\n    maximum: 0.45\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.8\n  num_pins_x: 11\n  num_pins_y: 11\n\nLQFP-48_7x7mm_P0.5mm:\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2358-16.pdf'\n  body_size_x:\n    nominal: 7\n  body_size_y:\n    nominal: 7\n  overall_size_x:\n    nominal: 9\n  overall_size_y:\n    nominal: 9\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n\nLQFP-48-1ep:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  body_size_x:\n    nominal: 7\n    tolerance: 0\n    # minimum:\n    # maximum:\n  body_size_y:\n    nominal: 7\n    tolerance: 0\n  overall_size_x:\n    nominal: 9\n    tolerance: 0\n  overall_size_y:\n    nominal: 9\n    tolerance: 0\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n\n  EP_size_x_min: 3.5\n  EP_size_x: 3.6\n  EP_size_x_max: 3.7\n  EP_size_y_min: 3.5\n  EP_size_y: 3.6\n  EP_size_y_max: 3.7\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\nLQFP-52_10x10mm_P0.65mm:\n  size_source: 'https://www.nxp.com/docs/en/package-information/98ARL10526D.pdf'\n  # ipc_density: 'least'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 10\n  body_size_y:\n    nominal: 10\n  overall_size_x:\n    nominal: 12\n  overall_size_y:\n    nominal: 12\n  lead_width:\n    nominal: 0.325\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 13\n  num_pins_y: 13\n\nLQFP-52-1EP_10x10mm_P0.65mm_EP4.8x4.8mm:\n  size_source: 'https://www.onsemi.com/pub/Collateral/848H-01.PDF'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 10\n    tolerance: 0\n  body_size_y:\n    nominal: 10\n    tolerance: 0\n  overall_size_x:\n    nominal: 12\n    tolerance: 0\n  overall_size_y:\n    nominal: 12\n    tolerance: 0\n  lead_width:\n    minimum: 0.22\n    maximum: 0.4\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 13\n  num_pins_y: 13\n\n  EP_size_x: 4.8\n  EP_size_y: 4.8\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\nLQFP-52_14x14mm_P1mm:\n  size_source: 'http://www.holtek.com/documents/10179/116711/HT1632Cv170.pdf'\n  body_size_x:\n    nominal: 14\n    minimum: 13.9\n    maximum: 14.1\n  body_size_y:\n    nominal: 14\n    minimum: 13.9\n    maximum: 14.1\n  overall_size_x:\n    nominal: 16\n    minimum: 15.8\n    maximum: 16.2\n  overall_size_y:\n    nominal: 16\n    minimum: 15.8\n    maximum: 16.2\n  lead_width:\n    minimum: 0.39\n    maximum: 0.48\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 1\n  num_pins_x: 13\n  num_pins_y: 13\n\nLQFP-64-1EP_10x10mm_P0.5mm_EP6.5x6.5mm:\n  size_source: 'https://www.nxp.com/files-static/shared/doc/package_info/98ARH98426A.pdf'\n  # ipc_density: 'least'\n  # force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 10\n  body_size_y:\n    nominal: 10\n  overall_size_x:\n    nominal: 12\n  overall_size_y:\n    nominal: 12\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n\n  EP_size_x: 6.5\n  EP_size_y: 6.5\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [5, 5]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.2, 1.2]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\nLQFP-64-1EP_10x10mm_P0.5mm_EP5.0x5.0mm:\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/adv7611.pdf'\n  # ipc_density: 'least'\n  # force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 10\n    minimum: 9.8\n    maximum: 10.2\n  body_size_y:\n    nominal: 10\n    minimum: 9.8\n    maximum: 10.2\n  overall_size_x:\n    nominal: 12\n    minimum: 11.8\n    maximum: 12.2\n  overall_size_y:\n    nominal: 12\n    minimum: 11.8\n    maximum: 12.2\n  lead_width:\n    nominal: 0.22\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    nominal: 0.6\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n\n  EP_size_x:\n    nominal: 5.0\n    minimum: 4.9\n    maximum: 5.1\n  EP_size_y:\n    nominal: 5.0\n    minimum: 4.9\n    maximum: 5.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [5, 5]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.2, 1.2]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\nLQFP-64_7x7mm_P0.4mm:\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT414-1.pdf'\n  body_size_x:\n    minimum: 6.9\n    maximum: 7.1\n  body_size_y:\n    minimum: 6.9\n    maximum: 7.1\n  overall_size_x:\n    minimum: 8.85\n    maximum: 9.15\n  overall_size_y:\n    minimum: 8.85\n    maximum: 9.15\n  lead_width:\n    minimum: 0.13\n    maximum: 0.23\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.4\n  num_pins_x: 16\n  num_pins_y: 16\n\nLQFP-64_10x10mm_P0.5mm:\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/ad7606_7606-6_7606-4.pdf'\n  body_size_x:\n    minimum: 9.8\n    nominal: 10\n    maximum: 10.2\n  body_size_y:\n    minimum: 9.8\n    nominal: 10\n    maximum: 10.2\n  overall_size_x:\n    minimum: 11.8\n    nominal: 12\n    maximum: 12.2\n  overall_size_y:\n    minimum: 11.8\n    nominal: 12\n    maximum: 12.2\n  lead_width:\n    minimum: 0.17\n    nominal: 0.22\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n\nLQFP-64_14x14mm_P0.8mm:\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT791-1.pdf'\n  body_size_x:\n    minimum: 13.9\n    maximum: 14.1\n  body_size_y:\n    minimum: 13.9\n    maximum: 14.1\n  overall_size_x:\n    minimum: 15.85\n    maximum: 16.15\n  overall_size_y:\n    minimum: 15.85\n    maximum: 16.15\n  lead_width:\n    minimum: 0.3\n    maximum: 0.45\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.8\n  num_pins_x: 16\n  num_pins_y: 16\n\nLQFP-80_10x10mm_P0.4mm:\n  size_source: 'https://www.renesas.com/eu/en/package-image/pdf/outdrawing/q80.10x10.pdf'\n  body_size_x:\n    nominal: 10\n  body_size_y:\n    nominal: 10\n  overall_size_x:\n    nominal: 12\n  overall_size_y:\n    nominal: 12\n  lead_width:\n    minimum: 0.13\n    nominal: 0.16\n    maximum: 0.23\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n  pitch: 0.4\n  num_pins_x: 20\n  num_pins_y: 20\n\nLQFP-80_12x12mm_P0.5mm:\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT315-1.pdf'\n  body_size_x:\n    minimum: 11.9\n    maximum: 12.1\n  body_size_y:\n    minimum: 11.9\n    maximum: 12.1\n  overall_size_x:\n    minimum: 13.85\n    maximum: 14.15\n  overall_size_y:\n    minimum: 13.85\n    maximum: 14.15\n  lead_width:\n    minimum: 0.13\n    maximum: 0.27\n  lead_len:\n    minimum: 0.3\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 20\n  num_pins_y: 20\n\nLQFP-80_14x14mm_P0.65mm:\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/AD9852.pdf'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    minimum: 13.8\n    nominal: 14\n    maximum: 14.2\n  body_size_y:\n    minimum: 13.8\n    nominal: 14\n    maximum: 14.2\n  overall_size_x:\n    minimum: 15.8\n    nominal: 16\n    maximum: 16.2\n  overall_size_y:\n    minimum: 15.8\n    nominal: 16\n    maximum: 16.2\n  lead_width:\n    minimum: 0.22\n    nominal: 0.32\n    maximum: 0.38\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 20\n  num_pins_y: 20\n\nLQFP-100_14x14mm_P0.5mm:\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT407-1.pdf'\n  body_size_x:\n    minimum: 13.9\n    maximum: 14.1\n  body_size_y:\n    minimum: 13.9\n    maximum: 14.1\n  overall_size_x:\n    minimum: 15.75\n    maximum: 16.25\n  overall_size_y:\n    minimum: 15.75\n    maximum: 16.25\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 25\n  num_pins_y: 25\n\nLQFP-128_14x14mm_P0.4mm:\n  size_source: 'https://www.renesas.com/eu/en/package-image/pdf/outdrawing/q128.14x14.pdf'\n  body_size_x:\n    nominal: 14\n  body_size_y:\n    nominal: 14\n  overall_size_x:\n    nominal: 16\n  overall_size_y:\n    nominal: 16\n  lead_width:\n    minimum: 0.13\n    nominal: 0.16\n    maximum: 0.23\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n  pitch: 0.4\n  num_pins_x: 32\n  num_pins_y: 32\n\nLQFP-128_14x20mm_P0.5mm:\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT425-1.pdf'\n  body_size_x:\n    minimum: 13.9\n    maximum: 14.1\n  body_size_y:\n    minimum: 19.9\n    maximum: 20.1\n  overall_size_x:\n    minimum: 15.85\n    maximum: 16.15\n  overall_size_y:\n    minimum: 21.85\n    maximum: 22.15\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 26\n  num_pins_y: 38\n\nLQFP-144_20x20mm_P0.5mm:\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=425'\n  body_size_x:\n    nominal: 20\n  body_size_y:\n    nominal: 20\n  overall_size_x:\n    nominal: 22\n  overall_size_y:\n    nominal: 22\n  lead_width:\n    minimum: 0.17\n    nominal: 0.22\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 36\n  num_pins_y: 36\n\nLQFP-160_24x24mm_P0.5mm:\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT435-1.pdf'\n  body_size_x:\n    minimum: 23.9\n    maximum: 24.1\n  body_size_y:\n    minimum: 23.9\n    maximum: 24.1\n  overall_size_x:\n    minimum: 25.85\n    maximum: 26.15\n  overall_size_y:\n    minimum: 25.85\n    maximum: 26.15\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 40\n  num_pins_y: 40\n\nLQFP-176_20x20mm_P0.4mm:\n  size_source: 'https://www.onsemi.com/pub/Collateral/566DB.PDF'\n  body_size_x:\n    nominal: 20\n    tolerance: 0.1\n  body_size_y:\n    nominal: 20\n    tolerance: 0.1\n  overall_size_x:\n    nominal: 22\n    tolerance: 0.2\n  overall_size_y:\n    nominal: 22\n    tolerance: 0.2\n  lead_width:\n    nominal: 0.15\n    tolerance: [0.04, 0.05]\n  lead_len:\n    nominal: 0.5\n    tolerance: 0.2\n  pitch: 0.4\n  num_pins_x: 44\n  num_pins_y: 44\n\nLQFP-176_24x24mm_P0.5mm:\n  size_source: 'https://www.st.com/resource/en/datasheet/stm32f207vg.pdf#page=163'\n  body_size_x:\n    minimum: 23.9\n    maximum: 24.1\n  body_size_y:\n    minimum: 23.9\n    maximum: 24.1\n  overall_size_x:\n    minimum: 25.9\n    maximum: 26.1\n  overall_size_y:\n    minimum: 25.9\n    maximum: 26.1\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 44\n  num_pins_y: 44\n\nLQFP-208_28x28mm_P0.5mm:\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT459-1.pdf'\n  body_size_x:\n    minimum: 27.9\n    maximum: 28.1\n  body_size_y:\n    minimum: 27.9\n    maximum: 28.1\n  overall_size_x:\n    minimum: 29.85\n    maximum: 30.15\n  overall_size_y:\n    minimum: 29.85\n    maximum: 30.15\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 52\n  num_pins_y: 52\n\nLQFP-216_24x24mm_P0.4mm:\n  size_source: 'https://www.onsemi.com/pub/Collateral/561BE.PDF'\n  body_size_x:\n    nominal: 24\n    tolerance: 0\n  body_size_y:\n    nominal: 24\n    tolerance: 0\n  overall_size_x:\n    nominal: 26\n    tolerance: 0\n  overall_size_y:\n    nominal: 26\n    tolerance: 0\n  lead_width:\n    minimum: 0.13\n    maximum: 0.23\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.4\n  num_pins_x: 54\n  num_pins_y: 54\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/mqfp.yaml",
    "content": "FileHeader:\n  library_Suffix: 'QFP'\n  device_type: 'MQFP'\n\nMQFP-44_10x10mm_P0.8mm:\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/ad7722.pdf'\n  body_size_x:\n    minimum: 9.8\n    nominal: 10\n    maximum: 10.2\n  body_size_y:\n    minimum: 9.8\n    nominal: 10\n    maximum: 10.2\n  overall_size_x:\n    minimum: 13.65\n    nominal: 13.9\n    maximum: 14.15\n  overall_size_y:\n    minimum: 13.65\n    nominal: 13.9\n    maximum: 14.15\n  lead_width:\n    minimum: 0.3\n    maximum: 0.45\n  lead_len:\n    minimum: 0.73\n    nominal: 0.88\n    maximum: 1.03\n  pitch: 0.8\n  num_pins_x: 11\n  num_pins_y: 11\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/msop.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'MSOP'\n\nMSOP-8_3x3mm_P0.65mm:\n  size_source: 'https://www.jedec.org/system/files/docs/mo-187F.pdf variant AA'\n  force_small_pitch_ipc_definition: True\n  body_size_x: 3 +/-0.2\n  body_size_y: 3 +/-0.2\n  overall_size_x: 4.9 +/-0.25\n  lead_width: 0.22 .. 0.38\n  lead_len: 0.4 .. 0.6 .. 0.8\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4\n\nMSOP-8-1EP_3x3mm_P0.65mm_EP1.68x1.88mm:\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/4440fb.pdf#page=13'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 3\n    tolerance: 0.102\n  body_size_y:\n    nominal: 3\n    tolerance: 0.102\n  overall_height:\n    maximum: 1.1\n\n  overall_size_x:\n    nominal: 4.9\n    tolerance: 0.152\n  lead_width:\n    minimum: 0.22\n    maximum: 0.38\n  lead_len:\n    nominal: 0.53\n    tolerance: 0.152\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x:\n    nominal: 1.68\n    tolerance: 0\n  EP_size_y:\n    nominal: 1.88\n    tolerance: 0\n  # EP_mask_x: 2.46\n  # EP_mask_y: 2.31\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1.1, 1.3]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nMSOP-8-1EP_3x3mm_P0.65mm_EP1.73x1.85mm:\n  size_source: 'http://www.ti.com/lit/ds/symlink/lm25085.pdf#page=32'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 3\n    tolerance: 0.1\n  body_size_y:\n    nominal: 3\n    tolerance: 0.1\n  overall_height:\n    maximum: 1.09\n\n  overall_size_x:\n    nominal: 4.9\n    tolerance: 0.15\n  lead_width:\n    nominal: 0.3\n    tolerance: [-0.05, 0.1]\n  lead_len:\n    nominal: 0.53\n    tolerance: 0.12\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x:\n    nominal: 1.73\n    tolerance: 0.15\n  EP_size_y:\n    nominal: 1.85\n    tolerance: 0.15\n  # EP_mask_x: 2.46\n  # EP_mask_y: 2.31\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1.1, 1.3]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nMSOP-8-1EP_3x3mm_P0.65mm_Mask1.73x2.36mm:\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/mic5355_6.pdf#page=15'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 3\n    tolerance: 0.1\n  body_size_y:\n    nominal: 3.0\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.94\n    tolerance: 0.1\n\n  overall_size_x:\n    nominal: 4.9\n    tolerance: 0\n  lead_width:\n    nominal: 0.33\n    tolerance: [-0.1, 0.03]\n  lead_len:\n    nominal: 0.53\n    tolerance: 0.1\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x:\n    nominal: 1.73\n    tolerance: 0\n  EP_size_x_overwrite: 2.5\n  EP_mask_x: 1.73\n  EP_size_y:\n    nominal: 2.36\n    tolerance: 0\n  EP_size_y_overwrite: 3\n  EP_mask_y: 2.36\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nMSOP-8-1EP_3x3mm_P0.65mm_EP1.95x2.15mm:\n  size_source: 'http://www.st.com/resource/en/datasheet/pm8834.pdf'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  overall_height:\n    nominal: 1.1\n\n  overall_size_x:\n    minimum: 4.75\n    nominal: 4.9\n    maximum: 5.05\n  lead_width:\n    minimum: 0.25\n    nominal : 0.33\n    maximum: 0.41 # given as 0.7 but that can not be true. (larger than pitch)\n  lead_len:\n    minimum: 0.4\n    nominal : 0.55\n    maximum: 0.7\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x:\n    minimum: 1.63\n    nominal: 1.73\n    maximum: 1.73\n  EP_size_x_overwrite: 1.95\n\n  EP_size_y:\n    minimum: 2.08\n    nominal: 2.18\n    maximum: 2.28\n  EP_size_y_overwrite: 2.15\n  # EP_mask_x: 2.46\n  # EP_mask_y: 2.31\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1.1, 1.3]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n#####################################################################################################\n\nMSOP-10-1EP_3x3mm_P0.5mm_EP1.68x1.88mm:\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/3805fg.pdf#page=18'\n\n  body_size_x:\n    nominal: 3\n    tolerance: 0.102\n  body_size_y:\n    nominal: 3\n    tolerance: 0.102\n  overall_height:\n    maximum: 1.1\n\n  overall_size_x:\n    nominal: 4.9\n    tolerance: 0.152\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    nominal: 0.53\n    tolerance: 0.152\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 5\n\n  EP_size_x:\n    nominal: 1.68\n    tolerance: 0\n  # EP_size_x_overwrite:\n  # EP_mask_x:\n  EP_size_y:\n    nominal: 1.88\n    tolerance: 0\n  # EP_size_y_overwrite:\n  # EP_mask_y:\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1.1, 1.3]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nMSOP-10-1EP_3x3mm_P0.5mm_EP1.73x1.98mm:\n  size_source: 'www.allegromicro.com/~/media/Files/Datasheets/A4952-3-Datasheet.ashx?la=en#page=10'\n\n  body_size_x:\n    nominal: 3\n    tolerance: 0.1\n  body_size_y:\n    nominal: 3\n    tolerance: 0.1\n  overall_height:\n    # calculated using toleranced size class\n    # (0.86 +/- 0.05) + (0.05 ... 0.15)\n    # min_rms: 0.8892893218813452, max_rms: 1.0307106781186548\n    minimum: 0.89\n    maximum: 1.03\n\n  overall_size_x:\n    nominal: 4.88\n    tolerance: 0.2\n  lead_width:\n    minimum: 0.18\n    maximum: 0.27\n  lead_len:\n    nominal: 0.53\n    tolerance: 0.1\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 5\n\n  EP_size_x:\n    nominal: 1.73\n    tolerance: 0\n  # EP_size_x_overwrite:\n  # EP_mask_x:\n  EP_size_y:\n    nominal: 1.98\n    tolerance: 0\n  # EP_size_y_overwrite:\n  # EP_mask_y:\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1, 1.2]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n#####################################################################################################\n\nMSOP-12-1EP_3x4mm_P0.65mm_EP1.65x2.85mm:\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/3652fe.pdf#page=24'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 3\n    tolerance: 0.102\n  body_size_y:\n    nominal: 4 # rounded to avoid changes to the symbol datasheet: 4.039\n    tolerance: 0.102\n  overall_height:\n    maximum: 1.1\n\n  overall_size_x:\n    nominal: 4.9\n    tolerance: 0.152\n  lead_width:\n    minimum: 0.22\n    maximum: 0.38\n  lead_len:\n    nominal: 0.53\n    tolerance: 0.152\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 6\n\n  EP_size_x:\n    nominal: 1.651\n    tolerance: 0.102\n  EP_size_x_overwrite: 1.65 # avoid changes to symbol\n  # EP_mask_x:\n  EP_size_y:\n    nominal: 2.845\n    tolerance: 0.102\n  EP_size_y_overwrite: 2.85 # avoid changes to symbol\n  # EP_mask_y:\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nMSOP-12-1EP_3x4mm_P0.65mm:\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/6957fb.pdf#page=36'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 3\n    tolerance: 0.102\n  body_size_y:\n    nominal: 4 # rounded to avoid changes to the symbol datasheet: 4.039\n    tolerance: 0.102\n  overall_height:\n    maximum: 1.1\n\n  overall_size_x:\n    nominal: 4.9\n    tolerance: 0.152\n  lead_width:\n    minimum: 0.22\n    maximum: 0.38\n  lead_len:\n    nominal: 0.53\n    tolerance: 0.152\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 6\n\n######################################################################################################\n\nMSOP-16-1EP_3x4mm_P0.5mm_EP1.65x2.85mm:\n  size_source: 'http://cds.linear.com/docs/en/datasheet/37551fd.pdf#page=23'\n  body_size_x:\n    nominal: 3\n    tolerance: 0.102\n  body_size_y:\n    nominal: 4 # rounded to avoid changes to the symbol datasheet: 4.039\n    tolerance: 0.102\n  overall_height:\n    maximum: 1.1\n\n  overall_size_x:\n    nominal: 4.9\n    tolerance: 0.152\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    nominal: 0.53\n    tolerance: 0.152\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 8\n\n  EP_size_x:\n    nominal: 1.651\n    tolerance: 0.102\n  EP_size_x_overwrite: 1.65 # avoid changes to symbol\n  # EP_mask_x:\n  EP_size_y:\n    nominal: 2.845\n    tolerance: 0.102\n  EP_size_y_overwrite: 2.85 # avoid changes to symbol\n  # EP_mask_y:\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n\nMSOP-16-1EP_3x4mm_P0.5mm:\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/436412f.pdf#page=22'\n  body_size_x:\n    nominal: 3\n    tolerance: 0.102\n  body_size_y:\n    nominal: 4 # rounded to avoid changes to the symbol datasheet: 4.039\n    tolerance: 0.102\n  overall_height:\n    maximum: 1.1\n\n  overall_size_x:\n    nominal: 4.9\n    tolerance: 0.152\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    nominal: 0.53\n    tolerance: 0.152\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 8\n\n# By: JEFO\n# Email: jacob.overgaard.andersen@gmail.com\nMSOP-16_3x4mm_P0.5mm:\n  size_source: 'http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-msop/05081669_A_MS16.pdf'\n  body_size_x:\n    nominal: 3\n    tolerance: 0.102\n  body_size_y:\n    nominal: 4.039\n    tolerance: 0.102\n  overall_size_x:\n    nominal: 4.9\n    tolerance: 0.152\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    nominal: 0.53\n    tolerance: 0.152\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 8\n  overall_height:\n    maximum: 1.10\n\n\n# By: JEFO\n# Email: jacob.overgaard.andersen@gmail.com\nMSOP-16-1EP_3x4mm_P0.5mm_EP1.65x2.85mm:\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-msop/05081667_F_MSE16.pdf'\n  body_size_x:\n    nominal: 3\n    tolerance: 0.102\n  body_size_y:\n    nominal: 4.039\n    tolerance: 0.102\n  overall_size_x:\n    nominal: 4.9\n    tolerance: 0.152\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    nominal: 0.53\n    tolerance: 0.152\n  overall_height:\n    maximum: 1.10\n  EP_size_x:\n    nominal: 1.651\n    tolerance: 0.102\n  EP_size_y:\n    nominal: 2.845\n    tolerance: 0.102\n  EP_paste_coverage: 0.7\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.25\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    paste_avoid_via: False\n  \n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 8\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/pqfp.yaml",
    "content": "FileHeader:\n  library_Suffix: 'QFP'\n  device_type: 'PQFP'\n\nPQFP-100_14x20mm_P0.65mm:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 14\n    tolerance: 0\n    # minimum:\n    # maximum:\n  body_size_y:\n    nominal: 20\n    tolerance: 0\n  overall_size_x:\n    nominal: 17.2\n    tolerance: 0\n  overall_size_y:\n    nominal: 23.2\n    tolerance: 0\n  lead_width:\n    minimum: 0.22\n    maximum: 0.4\n  lead_len:\n    minimum: 0.73\n    maximum: 1.03\n  pitch: 0.65\n  num_pins_x: 20\n  num_pins_y: 30\n\nPQFP-144_28x28mm_P0.65mm:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 28\n  body_size_y:\n    nominal: 28\n  overall_size_x:\n    nominal: 31.2\n  overall_size_y:\n    nominal: 31.2\n  lead_width:\n    minimum: 0.22\n    maximum: 0.4\n  lead_len:\n    minimum: 0.73\n    maximum: 1.03\n  pitch: 0.65\n  num_pins_x: 36\n  num_pins_y: 36\n\nPQFP-160_28x28mm_P0.65mm:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  force_small_pitch_ipc_definition: True\n  body_size_x:\n    nominal: 28\n  body_size_y:\n    nominal: 28\n  overall_size_x:\n    nominal: 31.2\n  overall_size_y:\n    nominal: 31.2\n  lead_width:\n    minimum: 0.22\n    maximum: 0.4\n  lead_len:\n    minimum: 0.73\n    maximum: 1.03\n  pitch: 0.65\n  num_pins_x: 40\n  num_pins_y: 40\n\nPQFP_208:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  body_size_x:\n    nominal: 28\n  body_size_y:\n    nominal: 28\n  overall_size_x:\n    nominal: 30.6\n  overall_size_y:\n    nominal: 30.6\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 52\n  num_pins_y: 52\n\nPQFP_240:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  body_size_x:\n    nominal: 32.1\n  body_size_y:\n    nominal: 32.1\n  overall_size_x:\n    nominal: 34.6\n  overall_size_y:\n    nominal: 34.6\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 60\n  num_pins_y: 60\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/sc-74.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'SC-74'\n\nSC-74-6_1.50mmx2.90mm_P0.95mm:\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT457.pdf'\n  body_size_x:\n    minimum: 1.3\n    maximum: 1.7\n  body_size_y:\n    minimum: 2.7\n    maximum: 3.1\n  overall_size_x:\n    minimum: 2.5\n    maximum: 3.0\n  overall_height:\n    minimum: 0.9\n    maximum: 1.1\n  lead_width:\n    minimum: 0.25\n    maximum: 0.40\n  lead_len:\n    minimum: 0.2\n    maximum: 0.6\n  pitch: 0.95\n  num_pins_x: 0\n  num_pins_y: 3\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/so.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'SO'\n\nSO-8_5.3x6.2mm_P1.27mm:\n  size_source: 'https://www.ti.com/lit/ml/msop001a/msop001a.pdf'\n  body_size_x: 5.00 .. 5.60\n  body_size_y: 5.90 .. 6.50\n  overall_height: 2.00\n  overall_size_x: 7.40 .. 8.20\n  lead_width: 0.35 .. 0.51\n  lead_len: 0.55 .. 0.95\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\nSO-14_3.9x8.65mm_P1.27mm:\n  size_source: 'https://www.st.com/resource/en/datasheet/l6491.pdf'\n  body_size_x: 3.80 .. 4.00\n  body_size_y: 8.55 .. 8.75\n  overall_height: 1.75\n  overall_size_x: 5.80 .. 6.20\n  lead_width: 0.33 .. 0.51\n  lead_len: 0.4 .. 1.27\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 7\n\nSO-14_5.3x10.2mm_P1.27mm:\n  size_source: 'https://www.ti.com/lit/ml/msop002a/msop002a.pdf'\n  body_size_x: 5.00 .. 5.60\n  body_size_y: 9.90 .. 10.50\n  overall_height: 2.00\n  overall_size_x: 7.40 .. 8.20\n  lead_width: 0.35 .. 0.51\n  lead_len: 0.55 .. 1.05\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 7\n\nSO-16_3.9x9.9mm_P1.27mm:\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT109-1.pdf'\n  body_size_x:\n    nominal: 3.9\n    minimum: 3.8\n    maximum: 4.0\n  body_size_y:\n    nominal: 9.9\n    minimum: 9.8\n    maximum: 10.0\n  overall_height: 1.75\n  overall_size_x:\n    minimum: 5.8\n    maximum: 6.2\n  lead_width:\n    minimum: 0.36\n    maximum: 0.49\n  lead_len:\n    minimum: 0.4\n    maximum: 1.0\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 8\n\nSO-16_5.3x10.2mm_P1.27mm:\n  size_source: 'https://www.ti.com/lit/ml/msop002a/msop002a.pdf'\n  body_size_x: 5.00 .. 5.60\n  body_size_y: 9.90 .. 10.50\n  overall_height: 2.00\n  overall_size_x: 7.40 .. 8.20\n  lead_width: 0.35 .. 0.51\n  lead_len: 0.55 .. 1.05\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 8\n\nSO-20_5.3x12.6mm_P1.27mm:\n  size_source: 'https://www.ti.com/lit/ml/msop002a/msop002a.pdf'\n  body_size_x: 5.00 .. 5.60\n  body_size_y: 12.30 .. 12.90\n  overall_height: 2.00\n  overall_size_x: 7.40 .. 8.20\n  lead_width: 0.35 .. 0.51\n  lead_len: 0.55 .. 1.05\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 10\n\nSO-24_5.3x15mm_P1.27mm:\n  size_source: 'https://www.ti.com/lit/ml/msop002a/msop002a.pdf'\n  body_size_x: 5.00 .. 5.60\n  body_size_y: 14.70 .. 15.30\n  overall_height: 2.00\n  overall_size_x: 7.40 .. 8.20\n  lead_width: 0.35 .. 0.51\n  lead_len: 0.55 .. 1.05\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 12\n\nSO-8_4.0x5.0mm_P1.27mm:\n  size_source: 'https://www.nxp.com/docs/en/data-sheet/PCF8523.pdf'\n  body_size_x:\n    minimum: 3.8\n    maximum: 4.0\n    # alternatively one can also specify the tolerance instead of minimum and maximum values.\n    # If minimum and maximum values are given then the nominal value is optional.\n    # It should only be included if it is given in the datasheet.\n    # (If it is in the datasheet then it must be included.)\n  body_size_y:\n    minimum: 4.8\n    maximum: 5.0\n  overall_size_x:\n    minimum: 5.8\n    maximum: 6.2\n  lead_width:\n    minimum: 0.36\n    maximum: 0.49\n  lead_len:\n    minimum: 0.4\n    maximum: 1.0\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\nSO-4_4.4x3.9mm_P2.54mm:\n  size_source: 'https://toshiba.semicon-storage.com/info/docget.jsp?did=10047&prodName=TLP3123'\n  body_size_x:\n    nominal: 4.4\n    tolerance: 0.25\n  body_size_y:\n    nominal: 3.9\n    tolerance: 0.25\n  overall_size_x:\n    nominal: 7.0\n    tolerance: 0.4\n  lead_width:\n    nominal: 0.4\n    tolerance: 0.1\n  lead_len:\n    nominal: 0.6\n    tolerance: 0.3\n  pitch: 2.54\n  num_pins_x: 0\n  num_pins_y: 2\n\nTexas_PowerPAD_SO-20-1EP_7.52x12.83mm_P1.27mm:\n  size_source: 'http://www.ti.com/lit/ds/symlink/opa569.pdf, http://www.ti.com/lit/an/slma004b/slma004b.pdf'\n  #custom_name_format: Texas_PowerPAD_SO-{pincount:d}-1EP_{size_x:.2g}x{size_y:.2g}mm_P{pitch:.2g}mm\n  body_size_x:\n    minimum: 7.45\n    maximum: 7.59\n  body_size_y:\n    minimum: 12.7\n    maximum: 12.95\n  overall_size_x:\n    minimum: 10.16\n    maximum: 10.65\n  overall_height:\n    nominal: 2.65\n    tolerance: 0\n  lead_width:\n    minimum: 0.35\n    maximum: 0.51\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 10\n\n  # EP_size from OPA569 datasheet\n  # _overwrite from PowerPad app note slma004b.pdf\n  # mask size from OPA569 datasheet Figure 16: 3.56 mm x 4.47 mm\n  # Thermal vias from OPA569 datasheet Figure 16: 3x8=24pcs 13mil\n  EP_size_x:\n    minimum: 2.72\n    maximum: 3.81\n  EP_size_x_overwrite: 6.045 # 0.238\"\n  EP_mask_x: 3.56\n  EP_size_y:\n    minimum: 3.49\n    maximum: 4.32\n  EP_size_y_overwrite: 12.09 # 0.476\"\n  EP_mask_y: 4.47\n\n  thermal_vias:\n    count: [3, 8]\n    # x-pitch 0.026\" = 0.66 mm\n    # y-pitch 0.039\"/2 = 0.495 mm\n    drill: 0.33 # 0.013\"\n    min_annular_ring: 0.08 # (0.495 spacing - 0.33 drill)/2 =  0.08 mm max ring\n    paste_via_clearance: 0.1\n    EP_paste_coverage: 0.75\n    grid: [0.66, 0.495]\n    paste_avoid_via: False\n    EP_num_paste_pads: [2, 2]\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/soic.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'SOIC'\n\nSOIC-4_4.55x3.7mm_P2.54mm:\n  custom_name_format: 'SOIC-4_4.55x3.7mm_P2.54mm' #does not take into account the excluded pins\n  size_source: 'https://toshiba.semicon-storage.com/info/docget.jsp?did=11791&prodName=TLP185'\n  body_size_x:\n    minimum: 4.4\n    nominal: 4.55\n    maximum: 4.8\n  body_size_y:\n    minimum: 3.45\n    nominal: 3.7\n    maximum: 3.95\n  overall_size_x:\n    minimum: 6.6\n    nominal: 7.0\n    maximum: 7.4\n  lead_width:\n    nominal: 0.4\n  lead_len:\n    nominal: 0.5\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 3\n  hidden_pins: [2, 5]\n\nSOIC-4_4.55x2.6mm_P1.27mm:\n  size_source: 'https://toshiba.semicon-storage.com/info/docget.jsp?did=12884&prodName=TLP291'\n  body_size_x:\n    minimum: 4.4\n    nominal: 4.55\n    maximum: 4.8\n  body_size_y:\n    minimum: 2.45\n    nominal: 2.6\n    maximum: 2.85\n  overall_size_x:\n    minimum: 6.6\n    nominal: 7.0\n    maximum: 7.4\n  lead_width:\n    minimum: 0.37\n    maximum: 0.39\n  lead_len:\n    nominal: 0.5\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 2\n\nSOIC-8_3.9x4.9mm_P1.27mm:\n  size_source: 'JEDEC MS-012AA, https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/soic_narrow-r/r_8.pdf'\n  body_size_x: # from JEDEC\n    nominal: 3.9\n    tolerance: 0.1\n  body_size_y:\n    minimum: 4.8\n    maximum: 5.0\n  overall_height:\n    minimum: 1.35\n    maximum: 1.75\n\n  overall_size_x: # from JEDEC (agrees with linked datasheet)\n    nominal: 6\n    tolerance: 0.2\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width: # from JEDEC (agrees with linked datasheet)\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\nSOIC-8-1EP_3.9x4.9mm_P1.27mm_EP2.29x3.0mm:\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/ada4898-1_4898-2.pdf#page=29'\n  body_size_x:\n    minimum: 3.8\n    nominal: 3.9\n    maximum: 4.0\n  body_size_y:\n    minimum: 4.8\n    nominal: 4.9\n    maximum: 5.0\n  overall_height:\n    minimum: 1.25\n    maximum: 1.65\n\n  overall_size_x:\n    minimum: 5.8\n    nominal: 6.0\n    maximum: 6.2\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width:\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x:\n    nominal: 2.29\n    tolerance: 0 # no tolerance given\n  #EP_size_x_overwrite:\n  #EP_mask_x:\n\n  EP_size_y:\n    nominal: 3.0 # 2.29+2*0.356 = 3.002 rounded to 3.0\n    tolerance: 0 # no tolerance given\n  #EP_size_y_overwrite:\n  #EP_mask_y:\n\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1.3, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nSOIC-8-1EP_3.9x4.9mm_P1.27mm_EP2.41x3.81mm:\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/ada4898-1_4898-2.pdf#page=29'\n  body_size_x:\n    minimum: 3.8\n    nominal: 3.9\n    maximum: 4.0\n  body_size_y:\n    minimum: 4.8\n    nominal: 4.9\n    maximum: 5.0\n  overall_height:\n    minimum: 1.25\n    maximum: 1.65\n\n  overall_size_x:\n    minimum: 5.8\n    nominal: 6.0\n    maximum: 6.2\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width:\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x:\n    nominal: 2.41\n    tolerance: 0 # no tolerance given\n  # EP_size_x_overwrite: 2.41\n  #EP_mask_x:\n\n  EP_size_y:\n    nominal: 3.81 # 3.098+2*0.356\n    tolerance: 0 # no tolerance given\n  # EP_size_y_overwrite: 3.1\n  #EP_mask_y:\n\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1.4, 1.4]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nSOIC-8-1EP_3.9x4.9mm_P1.27mm_EP2.41x3.1mm:\n  size_source: 'http://www.ti.com/lit/ds/symlink/lm5017.pdf#page=31'\n  body_size_x:\n    minimum: 3.8\n    maximum: 4.0\n  body_size_y:\n    minimum: 4.8\n    maximum: 5.0\n  overall_height:\n    maximum: 1.7\n\n  overall_size_x:\n    minimum: 5.8\n    maximum: 6.2\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width:\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x:\n    minimum: 2.11\n    maximum: 2.71\n  EP_size_x_overwrite: 2.95\n  EP_mask_x: 2.71\n\n  EP_size_y:\n    minimum: 2.8\n    maximum: 3.4\n  EP_size_y_overwrite: 4.9\n  EP_mask_y: 3.4\n\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1.3, 1.3]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nSOIC-8-1EP_3.9x4.9mm_P1.27mm_EP2.41x3.3mm:\n  size_source: 'http://www.allegromicro.com/~/media/Files/Datasheets/A4950-Datasheet.ashx#page=8'\n  body_size_x:\n    nominal: 3.9\n    tolerance: 0.1\n  body_size_y:\n    nominal: 4.9\n    tolerance: 0.1\n  overall_height:\n    maximum: 1.7\n\n  overall_size_x:\n    nominal: 6.0\n    tolerance: 0.2\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width:\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x:\n    nominal: 2.41\n    tolerance: 0 # no tolerance given\n  # EP_size_x_overwrite: 2.41\n  #EP_mask_x:\n\n  EP_size_y:\n    nominal: 3.3\n    tolerance: 0 # no tolerance given\n  # EP_size_y_overwrite: 3.1\n  #EP_mask_y:\n\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1.4, 1.2]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nSOIC-8-1EP_3.9x4.9mm_P1.27mm_EP2.514x3.2mm:\n  size_source: 'https://www.renesas.com/eu/en/www/doc/datasheet/hip2100.pdf#page=13'\n  body_size_x:\n    minimum: 3.8 # rounded from 3.811\n    maximum: 4.0 # rounded from 3.99\n  body_size_y:\n    minimum: 4.8\n    maximum: 5.0 # rounded from 4.98\n  overall_height:\n    minimum: 1.43\n    maximum: 1.68\n\n  overall_size_x:\n    minimum: 5.84\n    maximum: 6.2\n  lead_len:\n    minimum: 0.41\n    maximum: 0.89\n  lead_width:\n    minimum: 0.35\n    maximum: 0.49\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x:\n    nominal: 2.514 # only maximum given but that is not supported by the script\n    tolerance: 0\n  # EP_size_x_overwrite:\n  #EP_mask_x:\n\n  EP_size_y:\n    nominal: 3.2 # only maximum given but that is not supported by the script\n    tolerance: 0\n  # EP_size_y_overwrite:\n  #EP_mask_y:\n\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1.4, 1.0]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n    \n       \nSOIC-8-1EP_3.9x4.9mm_P1.27mm_EP2.62x3.51mm:\n  size_source: 'https://www.monolithicpower.com/en/documentview/productdocument/index/version/2/document_type/Datasheet/lang/en/sku/MP2303A/document_id/494#page=14'\n  body_size_x:\n    minimum: 3.8\n    maximum: 4.0\n  body_size_y:\n    minimum: 4.8\n    maximum: 5.0\n  overall_height:\n    minimum: 1.3\n    maximum: 1.7\n\n  overall_size_x:\n    minimum: 5.8\n    maximum: 6.2\n  lead_len:\n    minimum: 0.41\n    maximum: 1.27\n  lead_width:\n    minimum: 0.33\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x:\n    minimum: 2.26\n    maximum: 2.56\n\n  EP_size_y:\n    minimum: 3.15\n    maximum: 3.45\n\n  EP_size_x_overwrite: 2.62\n  EP_size_y_overwrite: 3.51\n\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1.4, 1.0]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n    \n    \nSOIC-8_5.23x5.23mm_P1.27mm:\n  size_source: 'http://www.winbond.com/resource-files/w25q32jv%20revg%2003272018%20plus.pdf#page=68'\n  body_size_x:\n    minimum: 5.13\n    nominal: 5.23\n    maximum: 5.33\n  body_size_y:\n    minimum: 5.13\n    nominal: 5.23\n    maximum: 5.33\n  overall_height:\n    minimum: 1.75\n    nominal: 1.95\n    maximum: 2.16\n\n  overall_size_x:\n    minimum: 7.7\n    nominal: 7.9\n    maximum: 8.1\n  lead_len:\n    minimum: 0.5\n    nominal: 0.65\n    maximum: 0.8\n  lead_width:\n    minimum: 0.35\n    nominal: 0.42\n    maximum: 0.48\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\nSOIC-8_5.275x5.275mm_P1.27mm:\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/20005045C.pdf#page=23'\n  body_size_x:\n    minimum: 5.15\n    maximum: 5.4\n  body_size_y:\n    minimum: 5.15\n    maximum: 5.4\n  overall_size_x:\n    minimum: 7.7\n    maximum: 8.1\n  overall_height:\n    minimum: 1.75\n    maximum: 2.16\n  lead_width:\n    minimum: 0.35\n    maximum: 0.5\n  lead_len:\n    minimum: 0.5\n    maximum: 0.8\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\nSOIC-8_7.5x5.85mm_P1.27mm:\n  size_source: 'http://www.ti.com/lit/ml/mpds382b/mpds382b.pdf'\n  body_size_x:\n    minimum: 7.4\n    maximum: 7.6\n  body_size_y:\n    minimum: 5.75\n    maximum: 5.95\n  overall_height:\n    maximum: 2.8\n  overall_size_x:\n    nominal: 11.5\n    tolerance: 0.25\n  lead_len:\n    minimum: 0.5\n    maximum: 1.0\n  lead_width:\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\nSOIC-14_3.9x8.7mm_P1.27mm:\n  #round to two significant digits to comply with old name\n  custom_name_format: SOIC-{pincount:d}_{size_x:.2g}x{size_y:.2g}mm_P{pitch:g}mm\n  size_source: 'JEDEC MS-012AB, https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/soic_narrow-r/r_14.pdf'\n  body_size_x: # from JEDEC\n    nominal: 3.9\n    tolerance: 0.1\n  body_size_y:\n    minimum: 8.55\n    maximum: 8.75\n  overall_height:\n    maximum: 1.75\n\n  overall_size_x: # from JEDEC (agrees with linked datasheet)\n    nominal: 6\n    tolerance: 0.2\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width: # from JEDEC (agrees with linked datasheet)\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 7\n\nSOIC-14W_7.5x9.0mm_P1.27mm:\n  custom_name_format: SOIC-{pincount:d}W_{size_x:g}x{size_y:g}mm_P{pitch:g}mm\n  size_source: 'JEDEC MS-013AF, https://www.analog.com/media/en/package-pcb-resources/package/54614177245586rw_14.pdf'\n  body_size_x: # from JEDEC (agrees with linked datasheet)\n    nominal: 7.5\n    tolerance: 0.1\n  body_size_y:\n    minimum: 8.8\n    maximum: 9.2\n  overall_height:\n    minimum: 2.35\n    maximum: 2.65\n\n  overall_size_x: # from JEDEC\n    nominal: 10.3\n    tolerance: 0.33\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width: # from JEDEC (agrees with linked datasheet)\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 7\n\nSOIC-16_3.9x9.9mm_P1.27mm:\n  size_source: 'JEDEC MS-012AC, https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/soic_narrow-r/r_16.pdf'\n  body_size_x: # from JEDEC\n    nominal: 3.9\n    tolerance: 0.1\n  body_size_y:\n    minimum: 9.8\n    maximum: 10\n  overall_height:\n    maximum: 1.75\n\n  overall_size_x: # from JEDEC (agrees with linked datasheet)\n    nominal: 6\n    tolerance: 0.2\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width: # from JEDEC (agrees with linked datasheet)\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 8\n\nSOIC-16_4.55x10.3mm_P1.27mm:\n  size_source: 'https://toshiba.semicon-storage.com/info/docget.jsp?did=12858&prodName=TLP291-4'\n  body_size_x:\n    minimum: 4.4\n    nominal: 4.55\n    maximum: 4.8\n  body_size_y:\n    minimum: 10.15\n    nominal: 10.3\n    maximum: 10.55\n  overall_size_x:\n    minimum: 6.6\n    nominal: 7.0\n    maximum: 7.4\n  lead_width:\n    minimum: 0.39\n    maximum: 0.41\n  lead_len:\n    nominal: 0.5\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 8\n\nSOIC-16W_7.5x10.3mm_P1.27mm:\n  custom_name_format: SOIC-{pincount:d}W_{size_x:g}x{size_y:g}mm_P{pitch:g}mm\n  size_source: 'JEDEC MS-013AA, https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/soic_wide-rw/rw_16.pdf'\n  body_size_x: # from JEDEC (agrees with linked datasheet)\n    nominal: 7.5\n    tolerance: 0.1\n  body_size_y:\n    minimum: 10.1\n    maximum: 10.5\n  overall_height:\n    minimum: 2.35\n    maximum: 2.65\n\n  overall_size_x: # from JEDEC\n    nominal: 10.3\n    tolerance: 0.33\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width: # from JEDEC (agrees with linked datasheet)\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 8\n\nSOIC-16W_7.5x12.8mm_P1.27mm:\n  #round to two significant digits to comply with old name\n  custom_name_format: SOIC-{pincount:d}W_{size_x:.2g}x{size_y:.3g}mm_P{pitch:g}mm\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ri_soic_ic/ri_16_1.pdf'\n  body_size_x:\n    minimum: 7.4\n    maximum: 7.6\n  body_size_y:\n    minimum: 12.6\n    maximum: 13\n  overall_height:\n    minimum: 2.35\n    maximum: 2.65\n\n  overall_size_x: # from JEDEC\n    nominal: 10.3\n    tolerance: 0.33\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width: # from JEDEC (agrees with linked datasheet)\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 8\n\nSOIC-18W_7.5x11.6mm_P1.27mm:\n  #round to two significant digits to comply with old name\n  custom_name_format: SOIC-{pincount:d}W_{size_x:.2g}x{size_y:.3g}mm_P{pitch:g}mm\n  size_source: 'JEDEC MS-013AB, https://www.analog.com/media/en/package-pcb-resources/package/33254132129439rw_18.pdf'\n  body_size_x: # from JEDEC (agrees with linked datasheet)\n    nominal: 7.5\n    tolerance: 0.1\n  body_size_y:\n    minimum: 11.35\n    maximum: 11.75\n  overall_height:\n    minimum: 2.35\n    maximum: 2.65\n\n  overall_size_x: # from JEDEC\n    nominal: 10.3\n    tolerance: 0.33\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width: # from JEDEC (agrees with linked datasheet)\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 9\n\nSOIC-20W_7.5x12.8mm_P1.27mm:\n  #round to two significant digits to comply with old name\n  custom_name_format: SOIC-{pincount:d}W_{size_x:.2g}x{size_y:.3g}mm_P{pitch:g}mm\n  size_source: 'JEDEC MS-013AC, https://www.analog.com/media/en/package-pcb-resources/package/233848rw_20.pdf'\n  body_size_x: # from JEDEC (agrees with linked datasheet)\n    nominal: 7.5\n    tolerance: 0.1\n  body_size_y:\n    minimum: 12.6\n    maximum: 13.0\n  overall_height:\n    minimum: 2.35\n    maximum: 2.65\n\n  overall_size_x: # from JEDEC\n    nominal: 10.3\n    tolerance: 0.33\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width: # from JEDEC (agrees with linked datasheet)\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 10\n\nSOIC-24W_7.5x15.4mm_P1.27mm:\n  #round to two significant digits to comply with old name\n  custom_name_format: SOIC-{pincount:d}W_{size_x:.2g}x{size_y:.3g}mm_P{pitch:g}mm\n  size_source: 'JEDEC MS-013AD, https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/soic_wide-rw/RW_24.pdf'\n  body_size_x: # from JEDEC (agrees with linked datasheet)\n    nominal: 7.5\n    tolerance: 0.1\n  body_size_y:\n    minimum: 15.2\n    maximum: 15.6\n  overall_height:\n    minimum: 2.35\n    maximum: 2.65\n\n  overall_size_x: # from JEDEC\n    nominal: 10.3\n    tolerance: 0.33\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width: # from JEDEC (agrees with linked datasheet)\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 12\n\nSOIC-28W_7.5x17.9mm_P1.27mm:\n  #round to two significant digits to comply with old name\n  custom_name_format: SOIC-{pincount:d}W_{size_x:.2g}x{size_y:.3g}mm_P{pitch:g}mm\n  size_source: 'JEDEC MS-013AE, https://www.analog.com/media/en/package-pcb-resources/package/35833120341221rw_28.pdf'\n  body_size_x: # from JEDEC (agrees with linked datasheet)\n    nominal: 7.5\n    tolerance: 0.1\n  body_size_y:\n    minimum: 17.7\n    maximum: 18.1\n  overall_height:\n    minimum: 2.35\n    maximum: 2.65\n\n  overall_size_x: # from JEDEC\n    nominal: 10.3\n    tolerance: 0.33\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n  lead_width: # from JEDEC (agrees with linked datasheet)\n    minimum: 0.31\n    maximum: 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 14\n\nSOIC-28W_7.5x18.7mm_P1.27mm:\n  #round to two significant digits to comply with old name\n  custom_name_format: SOIC-{pincount:d}W_{size_x:.2g}x{size_y:.3g}mm_P{pitch:g}mm\n  size_source: 'https://www.akm.com/akm/en/file/datasheet/AK5394AVS.pdf#page=23'\n  body_size_x:\n    nominal: 7.5\n    tolerance: 0.2\n  body_size_y:\n    nominal: 18.7\n    tolerance: 0.3\n  overall_height:\n    nominal: 2.2\n    tolerance: 0.1\n\n  overall_size_x:\n    nominal: 10.4\n    tolerance: 0.3\n  lead_len:\n    nominal: 0.75\n    tolerance: 0.2\n  lead_width:\n    nominal: 0.4\n    tolerance: 0.1\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 14\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/soj.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'SOJ'\n\nSOJ-36_23.49x10.16mm_P1.27mm:\n  size_source: 'http://www.issi.com/WW/pdf/61-64C5128AL.pdf'\n  body_size_x:\n    minimum: 10.03\n    maximum: 10.29\n  body_size_y:\n    minimum: 23.36\n    maximum: 23.62\n  overall_size_x:\n    minimum:  10.31\n    maximum:  10.33\n  lead_width:\n    minimum: 0.38\n    maximum: 0.51\n  lead_len:\n    minimum: 0.825\n    maximum: 0.95\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 18\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/sop.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'SOP'\n\nSOP-8-1EP_4.57x4.57mm_P1.27mm_EP4.57x4.45mm:\n  size_source: 'https://ww2.minicircuits.com/case_style/XX112.pdf'\n  body_size_x:\n    nominal: 4.57\n    tolerance: 0.254\n  body_size_y:\n    nominal: 4.57\n    tolerance: 0.254\n  overall_size_x:\n    nominal: 10.16\n    tolerance: 0.254\n  lead_width:\n    nominal: 0.38\n    tolerance: 0.254\n  lead_len:\n    nominal: 1.78\n    tolerance: 0.254\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x:\n    nominal: 4.57\n    tolerance: 0.254\n  EP_size_y:\n    # not directly given in datasheet. EP edge coincides with pads. (3*1.27+0.64 = 4.45)\n    nominal: 4.45\n    tolerance: 0.254\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.51\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.70\n    grid: [2.54, 1.27]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nSOP-4_3.8x4.1mm_P2.54mm:\n  size_source: 'http://www.ixysic.com/home/pdfs.nsf/www/CPC1017N.pdf/$file/CPC1017N.pdf'\n  body_size_x:\n    nominal: 3.8 #rounded to avoid changing the symbol (given as 3.81)\n    tolerance: 0.025\n  body_size_y:\n    nominal: 4.1 #rounded to avoid changing the symbol (givne as 4.089)\n    tolerance: 0.025\n  overall_height:\n    # calculated from (2.03 +/-0.025) + (0.64 +/-0.04)\n    nominal: 2.094\n    tolerance: 0.047\n\n  overall_size_x:\n    nominal: 6.096\n    tolerance: 0.102\n  lead_width:\n    nominal: 0.381\n    tolerance: 0 # not given\n  lead_len:\n    nominal: 0.559\n    tolerance: 0.127\n\n  pitch: 2.54\n  num_pins_x: 0\n  num_pins_y: 2\n\nSOP-4_4.4x2.6mm_P1.27mm:\n  size_source: 'http://www.vishay.com/docs/83510/tcmt1100.pdf'\n  body_size_x:\n    nominal: 4.4\n    tolerance: 0 # only typical size given\n  body_size_y:\n    nominal: 2.6\n    tolerance: 0.2\n  overall_height:\n    # calculated from (2.0 +/-0.1) + (0.1 +/-0.1)\n    nominal: 2.1\n    tolerance: 0.14\n\n  overall_size_x:\n    nominal: 7\n    tolerance: 0.3\n  lead_width:\n    nominal: 0.4\n    tolerance: 0.1\n  lead_len:\n    nominal: 0.6\n    tolerance: [-0.3, 0.2]\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 2\n\nSOP-8_3.76x4.96mm_P1.27mm:\n  size_source: 'https://ww2.minicircuits.com/case_style/XX211.pdf'\n  body_size_x:\n    nominal: 3.76 # max (4.14) - tolerance, rounded to 2 digits (+10um)\n    tolerance: 0.381\n  body_size_y:\n    nominal: 4.96 # max (5.33) - tolerance, rounded to 2 digits (+10um)\n    tolerance: 0.381\n  overall_height:\n    maximum: 1.96\n  overall_size_x:\n    minimum: 5.59\n    maximum: 6.35\n  lead_width:\n    nominal: 0.43\n    tolerance: 0.127\n  lead_len:\n    nominal: 0.76\n    tolerance: 0.381\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\nSOP-8_3.9x4.9mm_P1.27mm:\n  size_source: 'http://www.macronix.com/Lists/Datasheet/Attachments/7534/MX25R3235F,%20Wide%20Range,%2032Mb,%20v1.6.pdf#page=79'\n  body_size_x:\n    minimum: 3.80\n    maximum: 4.00\n  body_size_y:\n    minimum: 4.77\n    maximum: 5.03\n  overall_height:\n    minimum: 1.45 # not specified, min.A1(0.10) + min.A2(1.35) gives this value \n    maximum: 1.75 \n  overall_size_x:\n    minimum: 5.80\n    maximum: 6.20\n  lead_width:\n    minimum: 0.36\n    maximum: 0.51\n  lead_len:\n    minimum: 0.46\n    maximum: 0.86\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\nSOP-8_5.28x5.23mm_P1.27mm:\n  size_source: 'http://www.macronix.com/Lists/Datasheet/Attachments/7534/MX25R3235F,%20Wide%20Range,%2032Mb,%20v1.6.pdf#page=80'\n  body_size_x:\n    minimum: 5.18\n    maximum: 5.38\n  body_size_y:\n    minimum: 5.13\n    maximum: 5.33\n  overall_height:\n    minimum: 1.75\n    maximum: 2.16\n  overall_size_x:\n    minimum: 7.70\n    maximum: 8.10\n  lead_width:\n    minimum: 0.36\n    maximum: 0.51\n  lead_len:\n    minimum: 0.50\n    maximum: 0.80\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\nSOP-8_6.62x9.15mm_P2.54mm:\n  size_source: 'http://www.ti.com/lit/ds/symlink/iso1050.pdf'\n  body_size_x:\n    minimum: 6.37\n    maximum: 6.87\n  body_size_y:\n    minimum: 8.75\n    maximum: 9.55\n  overall_height:\n    maximum: 4.85\n\n  overall_size_x:\n    minimum: 10.1\n    maximum: 10.7\n  lead_width:\n    minimum: 0.355\n    maximum: 0.555\n  lead_len:\n    minimum: 1.15\n    maximum: 1.45\n\n  pitch: 2.54\n  num_pins_x: 0\n  num_pins_y: 4\n\nSOP-16_4.4.55x10.3mm_P1.27mm:\n  size_source: 'https://toshiba.semicon-storage.com/info/docget.jsp?did=12855&prodName=TLP290-4'\n  body_size_x:\n    nominal: 4.55\n    tolerance: [-0.15, 0.25]\n  body_size_y:\n    nominal: 10.3\n    tolerance: [-0.15, 0.25]\n  overall_height:\n    nominal: 2.1\n    tolerance: 0.14\n\n  overall_size_x:\n    nominal: 7\n    tolerance: 0.4\n  lead_width:\n    nominal: 0.4\n    tolerance: 0.1\n  lead_len:\n    minimum: 0.5\n    maximum: 0.5\n    # Only minimum given in the datasheet.\n    # With 0 tolerance we already get longer pads than suggested by the datasheet -> should be ok\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 8\n\nSOP-18_7.0x12.5mm_P1.27mm:\n  size_source: 'https://toshiba.semicon-storage.com/info/docget.jsp?did=30523'\n  body_size_x:\n    nominal: 7\n    tolerance: 0.2\n  body_size_y:\n    nominal: 12.5\n    tolerance: 0.2\n  overall_height:\n    maximum: 2.45\n\n  overall_size_x:\n    nominal: 10.3\n    tolerance: 0.3\n  lead_width:\n    nominal: 0.4\n    tolerance: 0.1\n  lead_len:\n    nominal: 0.7\n    tolerance: 0.2\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 9\n  \nSTC_SOP-16_3.9x9.9mm_P1.27mm:\n  size_source: 'https://www.stcmicro.com/datasheet/STC15F2K60S2-en.pdf#page=156'\n  manufacturer: 'STC'\n  body_size_x: # E1\n    minimum: 3.80\n    nominal: 3.90\n    maximum: 4.00\n  body_size_y: # D\n    minimum: 9.80\n    nominal: 9.90\n    maximum: 10.00\n  overall_height: # A\n    minimum: 1.35\n    nominal: 1.60\n    maximum: 1.75\n  overall_size_x: # E\n    minimum: 5.80\n    nominal: 6.00\n    maximum: 6.20\n  lead_len: # L\n    minimum: 0.45\n    nominal: 0.60\n    maximum: 0.80\n  lead_width: # b\n    minimum: 0.35\n    nominal: 0.40\n    maximum: 0.45\n\n  pitch: 1.27 # e\n  num_pins_x: 0\n  num_pins_y: 8\n\nSOP-16_3.9x9.9mm_P1.27mm:\n  size_source: 'https://www.diodes.com/assets/Datasheets/PAM8403.pdf'\n  body_size_x: # E1\n    minimum: 3.80\n    maximum: 4.00\n  body_size_y: # D\n    minimum: 9.80\n    maximum: 10.00\n  overall_height: # A\n    minimum: 1.35\n    maximum: 1.75\n  overall_size_x: # E\n    minimum: 5.80\n    maximum: 6.30\n  lead_len: # L\n    minimum: 0.40\n    maximum: 1.27\n  lead_width: # b\n    minimum: 0.33\n    maximum: 0.51\n\n  pitch: 1.27 # e\n  num_pins_x: 0\n  num_pins_y: 8\n\nSOP-20_7.5x12.8mm_P1.27mm:\n  size_source: 'https://www.holtek.com/documents/10179/116723/sop20-300.pdf'\n  body_size_x:\n    nominal: 7.50\n  body_size_y:\n    nominal: 12.80\n  overall_height:\n    maximum: 2.65\n\n  overall_size_x:\n    nominal: 10.30\n\n  lead_width:\n    minimum: 0.31\n    maximum: 0.51\n  lead_len:\n    minimum: 0.40\n    maximum: 1.27\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 10\n\nSOP-24_7.5x15.4mm_P1.27mm:\n  size_source: 'http://www.issi.com/WW/pdf/31FL3218.pdf#page=14'\n  body_size_x:\n    minimum: 7.4\n    nominal: 7.5\n    maximum: 7.6\n  body_size_y:\n    minimum: 15.2\n    nominal: 15.4\n    maximum: 15.6\n  overall_height:\n    maximum: 2.65\n\n  overall_size_x:\n    minimum: 10.1\n    nominal: 10.3\n    maximum: 10.61\n  lead_width:\n    minimum: 0.27\n    maximum: 0.48\n  lead_len:\n    minimum: 0.4\n    maximum: 1.27\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 12\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/sot.yaml",
    "content": "FileHeader:\n  library_Suffix: 'TO_SOT_SMD'\n  device_type: 'SOT'\n\nSOT-23-5:\n  size_source: 'https://www.jedec.org/sites/default/files/docs/Mo-178c.PDF variant AA'\n  custom_name_format: 'SOT-23-5'\n  body_size_x: 1.6\n  body_size_y: 2.9\n  overall_size_x: 2.8\n  lead_width: 0.3 .. 0.5\n  lead_len: 0.3 .. 0.45 .. 0.6\n  pitch: 0.95\n  num_pins_x: 0\n  num_pins_y: 3\n  deleted_pins: [5]\n\nSOT-23-6:\n  size_source: 'https://www.jedec.org/sites/default/files/docs/Mo-178c.PDF variant AB'\n  custom_name_format: 'SOT-23-6'\n  body_size_x: 1.6\n  body_size_y: 2.9\n  overall_size_x: 2.8\n  lead_width: 0.3 .. 0.5\n  lead_len: 0.3 .. 0.45 .. 0.6\n  pitch: 0.95\n  num_pins_x: 0\n  num_pins_y: 3\n  \nSOT-23-8:\n  size_source: 'https://www.jedec.org/sites/default/files/docs/Mo-178c.PDF variant BA'\n  custom_name_format: 'SOT-23-8'\n  body_size_x: 1.6\n  body_size_y: 2.9\n  overall_size_x: 2.8\n  lead_width: 0.22 .. 0.38\n  lead_len: 0.3 .. 0.45 .. 0.6\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/sso.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'SSO'\n\nSSO-8-N7_9.78x6.4mm_P2.54mm:\n  size_source: 'https://b2b-api.panasonic.eu/file_stream/pids/fileversion/2787'\n  body_size_y:\n    nominal: 9.78\n    tolerance: 0.1\n  body_size_x:\n    nominal: 6.4\n    tolerance: 0.1\n  overall_size_x:\n    nominal: 9.62 # 7.62 + 1 + 1 +/- 0.1\n    tolerance: 0.1\n  lead_width:\n    nominal: 1.2 # refers to fatter part of the lead, not the 0.5 at the lead ends\n    tolerance: 0.1\n  lead_len:\n    nominal: 1\n    tolerance: 0.1 # refers to area that can contact pad\n  pitch: 2.54\n  num_pins_y: 4\n  num_pins_x: 0\n  hidden_pins: [7]\n\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/ssop.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'SSOP'\n\nSSOP-20_5.3x7.2mm_P0.65mm:\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/40001800C.pdf'\n  body_size_x:\n    minimum: 5.0\n    maximum: 5.6\n  body_size_y:\n    minimum: 6.9\n    maximum: 7.5\n  overall_size_x:\n    minimum: 7.4\n    maximum: 8.2\n  lead_width:\n    minimum: 0.22\n    maximum: 0.38\n  lead_len:\n    minimum: 0.55\n    maximum: 0.95\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 10\n\nSSOP-16_5.3x6.2mm_P0.65mm:\n  size_source: 'https://assets.nexperia.com/documents/data-sheet/74HC_HCT165.pdf#page=14'\n  body_size_x:\n    minimum: 5.2\n    maximum: 5.4\n  body_size_y:\n    minimum: 6.0\n    maximum: 6.4\n  overall_size_x:\n    minimum: 7.6\n    maximum: 7.9\n  lead_width:\n    minimum: 0.25\n    maximum: 0.38\n  lead_len:\n    minimum: 0.63\n    maximum: 1.03\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 8\n\nSSOP-8_3.9x5.05mm_P1.27mm:\n  size_source: 'http://www.fujitsu.com/downloads/MICRO/fsa/pdf/products/memory/fram/MB85RS16-DS501-00014-6v0-E.pdf'\n  body_size_x:\n    minimum: 3.60\n    maximum: 4.20\n  body_size_y:\n    minimum: 4.80\n    maximum: 5.30\n  overall_size_x:\n    minimum: 5.80\n    maximum: 6.20\n  lead_width:\n    minimum: 0.36\n    maximum: 0.52\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\nSSOP-8_5.25x5.24mm_P1.27mm:\n  size_source: 'http://www.fujitsu.com/ca/en/Images/MB85RS2MT-DS501-00023-1v0-E.pdf'\n  body_size_x:\n    minimum: 5.20\n    maximum: 5.30\n  body_size_y:\n    minimum: 5.14\n    maximum: 5.34\n  overall_size_x:\n    minimum: 7.70\n    maximum: 8.25\n  lead_width:\n    minimum: 0.38\n    maximum: 0.48\n  lead_len:\n    minimum: 0.55\n    maximum: 0.85\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n\nSSOP-32_11.3x20.5mm_P1.27mm:\n  size_source: 'http://www.issi.com/WW/pdf/61-64C5128AL.pdf'\n  body_size_x:\n    minimum: 11.18\n    maximum: 11.43\n  body_size_y:\n    minimum: 20.24\n    maximum: 20.75\n  overall_size_x:\n    minimum: 13.79\n    maximum: 14.45\n  lead_width:\n    minimum: 0.33\n    maximum: 0.51\n  lead_len:\n    minimum: 0.38\n    maximum: 1.27\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 16\n\nSSOP-48_5.3x12.8mm_P0.5mm:\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-ssop/05081887_A_G48.pdf'\n  body_size_x:\n    minimum: 5.00\n    maximum: 5.60\n  body_size_y:\n    minimum: 12.50\n    maximum: 13.10\n  overall_size_x:\n    minimum: 7.40\n    maximum: 8.20\n  lead_width:\n    minimum: 0.20\n    maximum: 0.315\n  lead_len:\n    minimum: 0.55\n    maximum: 0.95\n  pitch: 0.50\n  num_pins_x: 0\n  num_pins_y: 24\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/test_hidden_deleted_pins.yaml",
    "content": "# hidden and deleted pins are defined and described by IPC 7351B naming convention\n# http://ohm.bu.edu/~pbohn/__Engineering_Reference/pcb_layout/pcbmatrix/IPC-7x51%20&%20PCBM%20Land%20Pattern%20Naming%20Convention.pdf\n# hidden pins remove a pin location and pin number (for example, going from pad 1 to pad 3 with pin 2 missing from the package)\n# deleted pins remove a pin location but not pin number (for example, pin 2 is missing from the package but the footprint has pad 2)\n# deleted pins do not support custom numbering schemes https://github.com/pointhi/kicad-footprint-generator/pull/371\n\nFileHeader:\n  library_Suffix: 'TO_SOT_SMD'\n  device_type: 'SOT'\n\n# test add_quad_pad_border() in quad_dual_pad_border.py\nLQFP-48_7x7mm_P0.5mm:\n  size_source: '~'\n  body_size_x: 7\n  body_size_y: 7\n  overall_size_x: 9\n  overall_size_y: 9\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.45 .. 0.75\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n\n# test add_quad_pad_border() in quad_dual_pad_border.py with hidden pins\nLQFP-48_7x7mm_P0.5mm_hidden:\n  size_source: '~'\n  body_size_x: 7\n  body_size_y: 7\n  overall_size_x: 9\n  overall_size_y: 9\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.45 .. 0.75\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n  hidden_pins: [1,15,24,30,31,44]\n\n# test add_quad_pad_border() in quad_dual_pad_border.py with deleted pins\nLQFP-48_7x7mm_P0.5mm_deleted:\n  size_source: '~'\n  body_size_x: 7\n  body_size_y: 7\n  overall_size_x: 9\n  overall_size_y: 9\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.45 .. 0.75\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n  deleted_pins: [1,15,24,30,31,44]\n\n# test add_dual_pad_border_y() in quad_dual_pad_border.py\nSOT-23-6:\n  size_source: '~'\n  custom_name_format: 'SOT-23-6'\n  body_size_x: 1.6\n  body_size_y: 2.9\n  overall_size_x: 2.8\n  lead_width: 0.3 .. 0.5\n  lead_len: 0.3 .. 0.45 .. 0.6\n  pitch: 0.95\n  num_pins_x: 0\n  num_pins_y: 3\n\n# test add_dual_pad_border_y() in quad_dual_pad_border.py with hidden pins\n# manually-made footprint merged at https://github.com/KiCad/kicad-footprints/pull/2298\nSOIC-14-16_3.9x9.9mm_P1.27mm:\n  size_source: '~'\n  body_size_x: 3.8 .. 4.0\n  body_size_y: 9.8 .. 10\n  overall_height:\n    maximum: 1.75\n\n  overall_size_x: 6 +/-0.2\n  lead_len: 0.4 .. 1.27\n  lead_width: 0.31 .. 0.51\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 8\n  hidden_pins: [2, 13]\n\n# test add_dual_pad_border_y() in quad_dual_pad_border.py with deleted pins\nSOT-23-5:\n  size_source: '~'\n  custom_name_format: 'SOT-23-5'\n  body_size_x: 1.6\n  body_size_y: 2.9\n  overall_size_x: 2.8\n  lead_width: 0.3 .. 0.5\n  lead_len: 0.3 .. 0.45 .. 0.6\n  pitch: 0.95\n  num_pins_x: 0\n  num_pins_y: 3\n  deleted_pins: 5\n\n# test add_dual_pad_border_x() in quad_dual_pad_border.py\nSOT-23-6R:\n  size_source: '~'\n  custom_name_format: 'SOT-23-6R'\n  body_size_x: 1.6\n  body_size_y: 2.9\n  overall_size_x: 2.8\n  lead_width: 0.3 .. 0.5\n  lead_len: 0.3 .. 0.45 .. 0.6\n  pitch: 0.95\n  num_pins_x: 3\n  num_pins_y: 0\n\n# test add_dual_pad_border_x() in quad_dual_pad_border.py with hidden pins\nSOT-23-6R_hidden:\n  size_source: '~'\n  custom_name_format: 'SOT-23-6R_Hidden'\n  body_size_x: 1.6\n  body_size_y: 2.9\n  overall_size_x: 2.8\n  lead_width: 0.3 .. 0.5\n  lead_len: 0.3 .. 0.45 .. 0.6\n  pitch: 0.95\n  num_pins_x: 3\n  num_pins_y: 0\n  hidden_pins: [5]\n\n# test add_dual_pad_border_x() in quad_dual_pad_border.py with deleted pins\nSOT-23-6R_deleted:\n  size_source: '~'\n  custom_name_format: 'SOT-23-6R_Deleted'\n  body_size_x: 1.6\n  body_size_y: 2.9\n  overall_size_x: 2.8\n  lead_width: 0.3 .. 0.5\n  lead_len: 0.3 .. 0.45 .. 0.6\n  pitch: 0.95\n  num_pins_x: 3\n  num_pins_y: 0\n  deleted_pins: [5]\n\n# test footprint with removed pins on both sides\nSOT-23:\n  size_source: '~'\n  custom_name_format: 'SOT-23'\n  body_size_x: 1.6\n  body_size_y: 2.9\n  overall_size_x: 2.8\n  lead_width: 0.3 .. 0.5\n  lead_len: 0.3 .. 0.45 .. 0.6\n  pitch: 0.95\n  num_pins_x: 0\n  num_pins_y: 3\n  deleted_pins: [2, 4, 6]\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/test_so.yaml",
    "content": "#######################################################\n#\n# Size definitions used for testing silk screen\n# and courtyard creation.\n#\n\nFileHeader:\n  library_Suffix: 'SO'\n  device_type: 'HTSSOP'\n\ntest_original_fp:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  custom_name_format: \"test_original_fp\"\n  body_size_x:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_y:\n    minimum: 4.9\n    maximum: 5.1\n  overall_size_x:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 8\n\n\n  EP_size_x: 3.4\n  EP_size_y: 5\n  EP_mask_x: 2.46\n  EP_mask_y: 2.31\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\ntest_large_ep:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  custom_name_format: \"test_large_ep\"\n  body_size_x:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_y:\n    minimum: 4.9\n    maximum: 5.1\n  overall_size_x:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 8\n\n\n  EP_size_x: 3.4\n  EP_size_y: 6\n  EP_mask_x: 2.46\n  EP_mask_y: 2.31\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\ntest_long_body_no_ep:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  custom_name_format: \"test_long_body_no_ep\"\n  body_size_x:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_y:\n    minimum: 5.9\n    maximum: 6.1\n  overall_size_x:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 8\n\ntest_long_body:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  custom_name_format: \"test_long_body\"\n  body_size_x:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_y:\n    minimum: 5.9\n    maximum: 6.1\n  overall_size_x:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 8\n\n\n  EP_size_x: 3.4\n  EP_size_y: 6\n  EP_mask_x: 2.46\n  EP_mask_y: 2.31\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\ntest_no_ep:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  custom_name_format: \"test_no_ep\"\n  body_size_x:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_y:\n    minimum: 4.9\n    maximum: 5.1\n  overall_size_x:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 8\n\ntest_no_ep2:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  custom_name_format: \"test_no_ep2\"\n  body_size_x:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_y:\n    minimum: 5.4\n    maximum: 5.6\n  overall_size_x:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 8\n\n\ntest_original_fpy:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  custom_name_format: \"test_original_fpy\"\n  body_size_y:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_x:\n    minimum: 4.9\n    maximum: 5.1\n  overall_size_y:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_y: 0\n  num_pins_x: 8\n\n\n  EP_size_y: 3.4\n  EP_size_x: 5\n  EP_mask_y: 2.46\n  EP_mask_x: 2.31\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\ntest_large_epy:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  custom_name_format: \"test_large_epy\"\n  body_size_y:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_x:\n    minimum: 4.9\n    maximum: 5.1\n  overall_size_y:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_y: 0\n  num_pins_x: 8\n\n\n  EP_size_y: 3.4\n  EP_size_x: 6\n  EP_mask_y: 2.46\n  EP_mask_x: 2.31\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\ntest_long_body_no_epy:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  custom_name_format: \"test_long_body_no_epy\"\n  body_size_y:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_x:\n    minimum: 5.9\n    maximum: 6.1\n  overall_size_y:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_y: 0\n  num_pins_x: 8\n\ntest_long_bodyy:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  custom_name_format: \"test_long_bodyy\"\n  body_size_y:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_x:\n    minimum: 5.9\n    maximum: 6.1\n  overall_size_y:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_y: 0\n  num_pins_x: 8\n\n\n  EP_size_y: 3.4\n  EP_size_x: 6\n  EP_mask_y: 2.46\n  EP_mask_x: 2.31\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\ntest_no_epy:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  custom_name_format: \"test_no_epy\"\n  body_size_y:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_x:\n    minimum: 4.9\n    maximum: 5.1\n  overall_size_y:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_y: 0\n  num_pins_x: 8\n\ntest_no_epy2:\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/LTC7810.pdf'\n  custom_name_format: \"test_no_epy2\"\n  body_size_y:\n    minimum: 4.3\n    maximum: 4.5\n  body_size_x:\n    minimum: 5.4\n    maximum: 5.6\n  overall_size_y:\n    minimum: 6.2\n    maximum: 6.6\n  lead_width:\n    minimum: 0.19\n    maximum: 0.30\n  lead_len:\n    minimum: 0.5\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_y: 0\n  num_pins_x: 8\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/tqfp.yaml",
    "content": "FileHeader:\n  library_Suffix: 'QFP'\n  device_type: 'TQFP'\n\nTQFP-48_7x7mm_P0.5mm:\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/48L_TQFP_7x7x1_0mm_PT_C04-00300d.pdf'\n  body_size_x: 7.00 # basic\n  body_size_y: 7.00 # basic\n  overall_height: 1.00 .. 1.20 # min calculated from A1_min + A2_min\n  overall_size_x: 9.00 # basic\n  overall_size_y: 9.00 # basic\n  lead_width: 0.17 .. 0.22 .. 0.27\n  lead_len: 0.45 .. 0.60 .. 0.75\n  pitch: 0.50\n  num_pins_x: 12\n  num_pins_y: 12\n\nTQFP-48-1EP_7x7mm_P0.5mm_EP5.0x5.0mm:\n  size_source: 'https://www.trinamic.com/fileadmin/assets/Products/ICs_Documents/TMC2100_datasheet_Rev1.08.pdf (page 45)'\n  body_size_x:\n    nominal: 7\n    tolerance: 0\n  body_size_y:\n    nominal: 7\n    tolerance: 0\n  overall_size_x:\n    nominal: 9\n    tolerance: 0\n  overall_size_y:\n    nominal: 9\n    tolerance: 0\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n\n  EP_size_x:\n    minimum: 4.9\n    nominal: 5.0\n    maximum: 5.1\n  EP_size_y:\n    minimum: 4.9\n    nominal: 5.0\n    maximum: 5.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    #EP_paste_coverage: 0.65\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\nTQFP_64:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  body_size_x:\n    nominal: 10\n  body_size_y:\n    nominal: 10\n  overall_size_x:\n    nominal: 12\n  overall_size_y:\n    nominal: 12\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n\nTQFP_100:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  body_size_x:\n    nominal: 14\n  body_size_y:\n    nominal: 14\n  overall_size_x:\n    nominal: 16\n  overall_size_y:\n    nominal: 16\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 25\n  num_pins_y: 25\n\nTQFP-100-1EP_14x14mm_P0.5mm_EP5.0x5.0mm:\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/tqfp_edsv/sv_100_4.pdf'\n  body_size_x:\n    nominal: 14\n  body_size_y:\n    nominal: 14\n  overall_size_x:\n    nominal: 16\n  overall_size_y:\n    nominal: 16\n  overall_height:\n    minimum: 1\n    maximum: 1.2\n  lead_width:\n    minimum: 0.17\n    nominal: 0.22\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    nominal: 0.60\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 25\n  num_pins_y: 25\n\n  EP_size_x:\n    nominal: 5.0\n  EP_size_y:\n    nominal: 5.0\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  # EP_size_limit_x: 3.6  #for relatively large EP pads (increase clearance)\n  # EP_size_limit_y: 3.6  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    #EP_paste_coverage: 0.65\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\n\nTQFP_144:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  body_size_x:\n    nominal: 20\n  body_size_y:\n    nominal: 20\n  overall_size_x:\n    nominal: 22\n  overall_size_y:\n    nominal: 22\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 36\n  num_pins_y: 36\n\nTQFP_176:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  body_size_x:\n    nominal: 24\n  body_size_y:\n    nominal: 24\n  overall_size_x:\n    nominal: 26\n  overall_size_y:\n    nominal: 26\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 44\n  num_pins_y: 44\n\nTQFP_176:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  body_size_x:\n    nominal: 24\n  body_size_y:\n    nominal: 24\n  overall_size_x:\n    nominal: 26\n  overall_size_y:\n    nominal: 26\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 44\n  num_pins_y: 44\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/tsop-i.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'TSOP-I'\n\nTSOP-I-32_11.80x8.00mm_P0.50mm:\n  size_source: 'http://www.issi.com/WW/pdf/61-64C5128AL.pdf'\n  body_size_x:\n    minimum: 11.70\n    maximum: 11.90\n  body_size_y:\n    minimum: 7.90\n    maximum: 8.10\n  overall_size_x:\n    minimum: 13.10\n    maximum: 13.70\n  lead_width:\n    minimum: 0.16\n    maximum: 0.27\n  lead_len:\n    minimum: 0.30\n    maximum: 0.70\n  pitch: 0.50\n  num_pins_x: 0\n  num_pins_y: 16\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/tsop-ii.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'TSOP-II'\n\nTSOP-II-44_10.16x18.41mm_P0.80mm:\n  size_source: 'http://www.issi.com/WW/pdf/61-64C5128AL.pdf'\n  body_size_x:\n    minimum: 10.03\n    maximum: 10.29\n  body_size_y:\n    minimum: 18.28\n    maximum: 18.54\n  overall_size_x:\n    minimum: 11.56\n    maximum: 11.96\n  lead_width:\n    minimum: 0.30\n    maximum: 0.45\n  lead_len:\n    minimum: 0.40\n    maximum: 0.69\n  pitch: 0.80\n  num_pins_x: 0\n  num_pins_y: 22\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/tsot.yaml",
    "content": "FileHeader:\n  library_Suffix: 'TO_SOT_SMD'\n  device_type: 'TSOT'\n  \nTSOT-23-5:\n  size_source: 'https://www.jedec.org/sites/default/files/docs/MO-193D.pdf variant AB'\n  custom_name_format: 'TSOT-23-5'\n  body_size_x: 1.6\n  body_size_y: 2.9\n  overall_size_x: 2.8\n  lead_width: 0.3 .. 0.5\n  lead_len: 0.3 .. 0.45 .. 0.6\n  pitch: 0.95\n  num_pins_x: 0\n  num_pins_y: 3\n  deleted_pins: [5]\n\nTSOT-23-6:\n  size_source: 'https://www.jedec.org/sites/default/files/docs/MO-193D.pdf variant AA'\n  custom_name_format: 'TSOT-23-6'\n  body_size_x: 1.6\n  body_size_y: 2.9\n  overall_size_x: 2.8\n  lead_width: 0.3 .. 0.5\n  lead_len: 0.3 .. 0.45 .. 0.6\n  pitch: 0.95\n  num_pins_x: 0\n  num_pins_y: 3\n  \nTSOT-23-8:\n  size_source: 'https://www.jedec.org/sites/default/files/docs/MO-193D.pdf variant BA'\n  custom_name_format: 'TSOT-23-8'\n  body_size_x: 1.6\n  body_size_y: 2.9\n  overall_size_x: 2.8\n  lead_width: 0.22 .. 0.38\n  lead_len: 0.3 .. 0.45 .. 0.6\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/tssop.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'TSSOP'\n\n##############################################################################\n# TSSOP Variations - 0.40 PITCH\n# BODY WIDTH (E1) = 4.40 NOM\n##############################################################################\n\nTSSOP-24_4.4x5mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var CA https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 5.0 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 12\n\nTSSOP-32_4.4x6.5mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var CB https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 6.5 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 16\n\nTSSOP-36_4.4x7.8mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var CC https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 7.8 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 18\n\nTSSOP-48_4.4x9.7mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var CD https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 9.7 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 24\n\n##############################################################################\n# TSSOP Variations - 0.40 PITCH\n# BODY WIDTH (E1) = 6.10 NOM\n##############################################################################\n\nTSSOP-36_6.1x7.8mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var FA https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 7.8 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 18\n\nTSSOP-48_6.1x9.7mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var FB https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 9.7 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 24\n\nTSSOP-52_6.1x11mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var FC https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 11.0 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 26\n\nTSSOP-56_6.1x12.5mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var FD https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 12.5 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 28\n\nTSSOP-64_6.1x14mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var FE https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 14.0 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 32\n\nTSSOP-80_6.1x17mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var FF https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 17.0 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 40\n\n##############################################################################\n# TSSOP Variations - 0.40 PITCH\n# BODY WIDTH (E1) = 8.00 NOM\n##############################################################################\n\nTSSOP-48_8x9.7mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var JA https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 9.7 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 24\n\nTSSOP-52_8x11mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var JB https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 11.0 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 26\n\nTSSOP-56_8x12.5mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var JC https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 12.5 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 28\n\nTSSOP-60_8x12.5mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var JC-1 https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 12.5 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 30\n\nTSSOP-64_8x14mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var JD https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 14.0 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 32\n\nTSSOP-68_8x14mm_P0.4mm:\n  size_source: 'JEDEC MO-153 Var JD-1 https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 14.0 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.13 .. 0.23\n  lead_len: 0.6 +/-0.15\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 34\n\n##############################################################################\n# TSSOP Variations - 0.50 PITCH\n# BODY WIDTH (E1) = 4.40 NOM\n##############################################################################\n\nTSSOP-20_4.4x5mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var BA https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 5.0 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 10\n\nTSSOP-24_4.4x6.5mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var BB https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 6.5 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 12\n\nTSSOP-28_4.4x7.8mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var BC https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 7.8 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 14\n\nTSSOP-30_4.4x7.8mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var BC-1 https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 7.8 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 15\n\nTSSOP-36_4.4x9.7mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var BD https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 9.7 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 18\n\nTSSOP-38_4.4x9.7mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var BD https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 9.7 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 19\n\nTSSOP-44_4.4x11mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var BE https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 11.0 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 22\n\nTSSOP-50_4.4x12.5mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var BF https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 12.5 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 25\n\n##############################################################################\n# TSSOP Variations - 0.50 PITCH\n# BODY WIDTH (E1) = 6.10 NOM\n##############################################################################\n\nTSSOP-28_6.1x7.8mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var EA https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 7.8 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 14\n\nTSSOP-36_6.1x9.7mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var EB https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 9.7 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 18\n\nTSSOP-40_6.1x11mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var EC https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 11.0 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 20\n\nTSSOP-44_6.1x11mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var EC-1 https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 11.0 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 22\n\nTSSOP-48_6.1x12.5mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var ED https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 12.5 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 24\n\nTSSOP-56_6.1x14mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var EE https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 14.0 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 28\n\nTSSOP-64_6.1x17mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var EF https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 17.0 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.27\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 32\n\n##############################################################################\n# TSSOP Variations - 0.50 PITCH\n# BODY WIDTH (E1) = 8.00 NOM\n##############################################################################\n\nTSSOP-36_8x9.7mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var HA https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 9.7 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 18\n\nTSSOP-40_8x11mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var HB https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 11.0 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 20\n\nTSSOP-48_8x12.5mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var HC https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 12.5 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 24\n\nTSSOP-56_8x14mm_P0.5mm:\n  size_source: 'JEDEC MO-153 Var HD https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 14.0 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 28\n\n##############################################################################\n# TSSOP Variations - 0.65 PITCH\n# BODY WIDTH (E1) = 4.40 NOM\n##############################################################################\n\nTSSOP-8_4.4x3mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var AA https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 3.0 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4\n\nTSSOP-16_4.4x5mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var AB https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 5.0 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 8\n\nTSSOP-16-1EP_4.4x5mm_P0.65mm_EP3x3mm:\n  size_source: 'Allegro A4954 https://www.allegromicro.com/-/media/Files/Datasheets/A4954-Datasheet.ashx'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 5.0 +/-0.1\n  overall_size_x: 6.4 +/-0.2\n  body_height: 1.2\n  lead_width: 0.19 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 8\n  EP_size_x:\n    nominal: 3\n  EP_size_y:\n    nominal: 3\n  EP_num_paste_pads: [2, 2]\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.3\n    paste_avoid_via: false\n    EP_num_paste_pads: [2, 2]\n\nTSSOP-14_4.4x5mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var AB-1 https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 5.0 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 7\n\nTSSOP-20_4.4x6.5mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var AC https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 6.5 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 10\n\nTSSOP-24_4.4x7.8mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var AD https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 7.8 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 12\n\nTSSOP-24-1EP_4.4x7.8mm_P0.65mm_EP3.2x5mm:\n  size_source: 'https://www.st.com/resource/en/datasheet/led1642gw.pdf#page=37'\n  \n  body_size_x:\n    minimum: 4.30 \n    nominal: 4.40 \n    maximum: 4.50 \n  body_size_y:\n    minimum: 7.70\n    nominal: 7.80\n    maximum: 7.90\n\n  overall_size_x: \n    minimum: 6.30\n    nominal: 6.40\n    maximum: 6.50\n\n  body_height: 1.20\n\n  lead_width: 0.19 .. 0.30\n\n  lead_len: \n    minimum: 0.45\n    nominal: 0.60\n    maximum: 0.75\n\n  pitch: 0.65\n\n  num_pins_x: 0\n  num_pins_y: 12\n\n  EP_size_x:\n    minimum: 3.00\n    nominal: 3.20\n    maximum: 3.40\n  EP_size_y:\n    minimum: 4.80\n    nominal: 5.00\n    maximum: 5.20\n  EP_num_paste_pads: [2, 3]\n\nTSSOP-28_4.4x9.7mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var AE https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 4.4 +/-0.1\n  body_size_y: 9.7 +/-0.1\n  overall_size_x: 6.4\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 14\n\n##############################################################################\n# TSSOP Variations - 0.65 PITCH\n# BODY WIDTH (E1) = 6.10 NOM\n##############################################################################\n\nTSSOP-24_6.1x7.8mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var DA https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 7.8 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 12\n\nTSSOP-28_6.1x9.7mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var DB https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 9.7 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 14\n\nTSSOP-30_6.1x9.7mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var DB-1 https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 9.7 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 15\n\nTSSOP-32_6.1x11mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var DC https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 11.0 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 16\n\nTSSOP-36_6.1x12.5mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var DD https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 12.5 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 18\n\nTSSOP-38_6.1x12.5mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var DD-1 https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 12.5 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 19\n\nTSSOP-40_6.1x14mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var DE https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 6.1 +/-0.1\n  body_size_y: 14.0 +/-0.1\n  overall_size_x: 8.1\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 20\n\n##############################################################################\n# TSSOP Variations - 0.65 PITCH\n# BODY WIDTH (E1) = 8.0 NOM\n##############################################################################\n\nTSSOP-28_8x9.7mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var GA https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 9.7 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 14\n\nTSSOP-32_8x11mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var GB https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 11.0 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 16\n\nTSSOP-36_8x12.5mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var GC https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 12.5 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 18\n\nTSSOP-40_8x14mm_P0.65mm:\n  size_source: 'JEDEC MO-153 Var GD https://www.jedec.org/document_search?search_api_views_fulltext=MO-153'\n  body_size_x: 8.0 +/-0.1\n  body_size_y: 14.0 +/-0.1\n  overall_size_x: 10.0\n  body_height: 1.2\n  lead_width: 0.17 .. 0.30\n  lead_len: 0.6 +/-0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 20\n\n##############################################################################\n# TSSOP Variations - 4.0 PITCH\n# BODY WIDTH (E1) = 5.0 NOM\n##############################################################################\n\nTSSOP-4_4.4x5.0mm_P4.0mm:\n  size_source: 'https://www.onsemi.com/pub/Collateral/MDB8S-D.PDF#page=4'\n  body_size_x: 4.25 .. 4.55\n  body_size_y: 4.85 .. 5.15\n  overall_size_x: 6.3 .. 6.7\n  body_height: 1.75\n  lead_width: 0.6 .. 0.7\n  lead_len: 0.5 .. 0.7\n  pitch: 4.0\n  num_pins_x: 0\n  num_pins_y: 2\n\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/vqfp.yaml",
    "content": "FileHeader:\n  library_Suffix: 'QFP'\n  device_type: 'VQFP'\n\nVQFP_80:\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  body_size_x:\n    nominal: 14\n    tolerance: 0\n    # minimum: \n    # maximum:\n  body_size_y:\n    nominal: 14\n  overall_size_x:\n    nominal: 16\n  overall_size_y:\n    nominal: 16\n  lead_width:\n    minimum: 0.22\n    maximum: 0.379\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.65\n  num_pins_x: 20\n  num_pins_y: 20\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nVQFP_100:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  body_size_x:\n    nominal: 14\n  body_size_y:\n    nominal: 14\n  overall_size_x:\n    nominal: 16\n  overall_size_y:\n    nominal: 16\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.5\n  num_pins_x: 25\n  num_pins_y: 25\n\nVQFP_128:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  body_size_x:\n    nominal: 14\n  body_size_y:\n    nominal: 14\n  overall_size_x:\n    nominal: 16\n  overall_size_y:\n    nominal: 16\n  lead_width:\n    minimum: 0.13\n    maximum: 0.23\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.4\n  num_pins_x: 32\n  num_pins_y: 32\n\nVQFP_176:\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  body_size_x:\n    nominal: 20\n  body_size_y:\n    nominal: 20\n  overall_size_x:\n    nominal: 22\n  overall_size_y:\n    nominal: 22\n  lead_width:\n    minimum: 0.13\n    maximum: 0.23\n  lead_len:\n    minimum: 0.45\n    maximum: 0.75\n  pitch: 0.4\n  num_pins_x: 44\n  num_pins_y: 44\n"
  },
  {
    "path": "scripts/Packages/Package_Gullwing__QFP_SOIC_SO/size_definitions/vssop.yaml",
    "content": "FileHeader:\n  library_Suffix: 'SO'\n  device_type: 'VSSOP'\n\nVSSOP-10_3x3mm_P0.5mm:\n  size_source: 'http://www.ti.com/lit/ds/symlink/ads1115.pdf'\n  body_size_x:\n    minimum: 2.90\n    maximum: 3.10\n  body_size_y:\n    minimum: 2.90\n    maximum: 3.10\n  overall_size_y:\n    minimum: 4.85 #Datasheet value is 4.75 and 5.05 but this generate a 4.3 pin separation\n    maximum: 5.15 #by adding 0.1 in both pin separation is correct. \n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.4\n    maximum: 0.7\n  pitch: 0.5\n  num_pins_y: 5\n  num_pins_x: 0\n\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/Readme.md",
    "content": "# IPC Footprint Generator for No Lead Packages\n\nThis generator uses IPC-7351B equations and fillet definitions to derive a footprint for no-lead style packages from the dimensions of the package. (The suggested footprint is generally ignored. It is only used to define the exposed pad if necessary to fulfill thermal or EMC requirements defined in the datasheet.)\nFillet size definitions can be changed by pointing to a personalized IPC parameter file. The script generates footprints in zero orientation version A (pin 1 at top left corner).\nPads are generated using rounded rectangle pads as suggested in preliminary releases of IPC-7351C.\n\nExamples of supported packages include: DFN, QFN, SON, LGA.\n\n## Running the Script\n\nThe script requires python 3.4 or newer. Run it with:\n`python3 ipc_noLead_generator.py size_definitions/dfn.yaml` (replace `dfn.yaml` with the size definition file that contains your part.)\n\n### Optional Script Parameters\n\n* --global_config: the config file defining how the footprint will look like. (KLC) (default=`../../tools/global_config_files/config_KLCv3.0.yaml`)\n* --series_config: the config file defining series parameters (footprint naming). (default=`../package_config_KLCv3.yaml`)\n\n* --density: IPC density level (L,N,M) (default=`N`)\n* --ipc_doc: IPC definition document (default=`../ipc_definitions.yaml`)\n\n* --force_rectangle_pads: Force the generation of rectangle pads instead of rounded rectangle\n* --kicad4_compatible: Create footprints compatible with version 4 (avoids round-rect and custom pads).\n\n## Size Definition Format\n\n\nThe size definition file contains one entry per package size definition. The top level parameter will give the internal parameter set name. It must be unique in this file and should be representative of the footprint as it will be used in error messages. (It also makes later maintenance easier if it is easy to determine which footprint was generated by which parameter set.)\n\n``` yaml\ninternal_package_name:\n  # parameter list (See below)\n```\n\n### Documentation and Naming Parameters\n- Size source to be added to footprint documentation field (`size_source`) {url}\n- Footprint library name (`library`) {string}\n- Footprint name generation control\n  - Device type added as prefix. Example QFN. (`device_type`) {string}\n  - Selection of an alternative name format. Example for LGA footprints. (`use_name_format`) {enum(`LGA`, `not LGA`)}\n  - Manufacturer name. Will be added as a prefix if given. (`manufacturer`) {string}\n  - Part number. Will be added as a prefix if given. (`part_number`) {string}\n  - Suffix: A custom suffix (added after pin pitch in default naming format). Can include parameters `pad_x` and `pad_y`.\n  - Custom naming (`custom_name_format`) {python format string}\n    - The full default format string is `{man:s}_{mpn:s}_{pkg:s}-{pincount:d}-1EP_{size_x:g}x{size_y:g}mm_P{pitch:g}mm{suffix:s}_EP{ep_size_x:g}x{ep_size_y:g}mm_Mask{mask_size_x:g}x{mask_size_y:g}mm{suffix2:s}{vias:s}` (The same parameters can be used in your custom format. Exposed pad parameters are not available for components without exposed pad.)\n\n_Note: Contributions intended for the official library shall not include the manufacturer or part number unless the footprint is specific to that manufacturer or part. Similarly avoid custom naming for official library contributions unless required to achieve the requested name (Example TI-specific naming)._\n\n### Package Dimensions\n![dimension example](./documentation/dimension_system.svg)\n- Body size (`body_size_x`, `body_size_y`, `overall_height`) {dimension}\n- Lead dimensions:\n  - Lead width (`lead_width`) {dimension}\n  - Lead length (`lead_len`) {dimension}\n    - Optional for specifying different length for horizontal and vertical leads (`lead_len_H`, `lead_len_V`) {dimension}\n- Lead pitch, currently equal for all sides (`pitch`) {float}\n\n#### Pull Back Leads\nBy default the leads are assumed to extend to the body edge. On some packages the leads are inset within the package body and these are called \"pull back\" leads. A typical example are packages that are called LGA by manufacturers.\nThese packages need to select the pull back option for the IPC class (`ipc_class: 'qfn_pull_back'`) and need to be able to specify where the lead is.\n\n![dimension example for pull back leads](./documentation/dimension_system_pull_back.svg)\n\n- Most manufacturers give the lead pull back distance (`lead_to_edge`) {dimension}\n   - Alternatively the center position can be given (`lead_center_pos_x` and `lead_center_pos_y`) {dimension}\n   - Another alternative is to give the center to center dimenions for leads. (`lead_center_to_center_x` and `lead_center_to_center_y`) {dimension}\n- Some manufacturers give the body to inner edge dimension instead of the lead length (`body_to_inside_lead_edge`) {dimenions}\n\n### Pad Count\n- Pad count (`num_pins_x`, `num_pins_y`) {int}\n  - `num_pins_x`=0 is used for generating DFN-like packages.\n  - `num_pins_y`=0 is used to generate DFN-like package footprints but with inverted pin numbering. (Mirrored numbering scheme. Some manufactures use this style in their datasheets. Make sure you are not looking at the bottom view before using this. Not supported for QFN and similar.)\n\n### Exposed pad Handling:\n![exposed pad example](../documentation/ep_handling.svg)\n- Size of package exposed pad or slug (`EP_size_x`, `EP_size_y`) {dimension}\n- Size of the footprint pad [optional] (`EP_size_x_overwrite`, `EP_size_y_overwrite`) {float}\n   - Pad size is equal to nominal package pad size if not given.\n   - Use this to create a soldermask-defined pad.\n- Optional the size of the mask cutout (`EP_mask_x`, `EP_mask_y`) {float}\n   - Use to create soldermask-defined pads (in combination with `EP_size_x_overwrite`)\n- Paste is split into a regular grid with (`EP_num_paste_pads`) {[int (x), int (y)]}\n  - The optional paste coverage multiplier determines how much of the exposed copper area is covered by paste. (`EP_paste_coverage`) {float (0..1), default=0.65}\n\n### Rounding of Exposed Pad Corners\nIPC excludes exposed pads from the requirement for rounding its corners. By default the exposed pad does therefore not use rounded corners. Some datasheets do however suggest the use of rounded corners either specified to a specific value or they appear to be equal to the normal pads.\n\n![rounded exposed pad example](../documentation/ep_handling_rounded.svg)\n\n- Paste corner rounding is controlled by global config parameters `paste_radius_ratio` and\n`paste_maximum_radius` {float}\n- The round radius of the exposed pad can be directly set with `EP_round_radius` {float/\"pad\"}\n  - The string \"pad\" can be used to force the same radius for the exposed pad as for the normal pads.\n  - Alternatively the round radius ratio and max radius can be set using (`EP_round_radius_ratio`, `EP_maximum_radius`) {float}\n    - Both these can be set per-footprint or in the global config file.\n\n### Thermal Vias\nA package with exposed pad can generate a version with thermal vias. This will be generated in addition to the normal version.\n\n![exposed pad example](../documentation/thermal_vias.svg)\n\n``` yaml\n  thermal_vias:\n    # thermal via version parameters\n```\n- Number of vias generated in the regular grid (`count`) {[int (x), int (y)]}\n- Final hole size (`drill`) {float}\n- Optional grid (`grid`) {[float (x), float (y)]}\n  - Auto-generated if not given (outermost pad will touch pad edge).\n- Paste coverage overwrite [optional] (`EP_paste_coverage`) {float (0..1)}\n  - Thermal via version might need higher paste coverage compared to non-via version to compensate solder lost due to wicking.\n- Paste generator can be set up to avoid placing paste on top of vias (`paste_avoid_via`) {bool}\n  - Clearance between via hole and paste (`paste_via_clearance`) {float}\n  - Can lead to math exceptions. Possible fixes:\n     - Reduce paste coverage (make sure you still have enough paste)\n     - Play with the via grid and number of paste pads (having an outer ring of paste pads often helps. This is only possible if there is space on the outside)\n     - If no fix is satisfactory then select avoid vias as false and increase paste coverage to combat solder loss.\n- Number paste pads\n  - Quantity of paste pads (`EP_num_paste_pads`) {[int (x), int (y)]}\n  - Alternative available if `paste_avoid_via` is true\n    - Number of paste pads between 4 vias (`paste_between_vias`) {[int (x), int (y)]}\n    - Number of additional paste pad rings outside the outermost vias [optional] (`paste_rings_outside`) {[int (x), int (y)]}\n\n\n## Dimension Parameter Format\nDimensions in datasheets are either given with minimum and maximum value (optionally including nominal) or with the nominal value plus a tolerance. Some values of the datasheet are given as reference value without tolerance. (Tolerances in this measurement are already included in other dimensions.) The script reflects this by offering the same options.\n\nAlways include the nominal dimension if the tolerance is asymmetrical as the resulting footprint will differ if it is not included.\n\n_Note: Contributions that are intended for the official KiCad library must use the same dimensioning format as the datasheet. (If min, nom and max are given then all 3 must be entered into the YAML file even if the tolerance is symmetrical. Similarly use nominal plus tolerance format if the datasheet is dimensioned this way.)_\n\n### String-based\n\nThe parameter can be given as a string in one of the following formats (white space characters are ignored).\n\n```yaml\nparameter_name: 1.2 # nominal only (reference dimension marked as such in datasheet)\nparameter_name: 1.1 .. 1.2 .. 1.3 # min .. nominal .. max\nparameter_name: 1.1 .. 1.3 # min .. max\nparameter_name: 1.2 +/-0.1 # nominal plus symmetrical tolerance\nparameter_name: 1.2 +0.1 -0.05 # nominal plus asymmetrical tolerance\n```\n\n### Dict-based\n\n```yaml\nparameter_name: # nominal only\n  nominal: 1.2\n  tolerance: 0 # optional to make it clear that this is the case\nparameter_name: # minimum maximum and nominal\n  minimum: 1.1\n  nominal: 1.2\n  maximum: 1.3\nparameter_name: # minimum maximum\n  minimum: 1.1\n  maximum: 1.3\nparameter_name: # nominal with symmetrical tolerance\n  nominal: 1.2\n  tolerance: 0.1\nparameter_name: # nominal with asymmetrical tolerance\n  nominal: 1.2\n  tolerance: [-0.05, 0.1] # order does not matter, the sign is important.\n```\n\n### Deprecated format\n\nSupport for this format will be dropped in the future. This format only supports min, nom, max dimensioning.\n\n```yaml\nparameter_name_min: 1.1\nparameter_name: 1.2\nparameter_name_max: 1.3\n```\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/ipc_noLead_generator.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nimport argparse\nimport yaml\nimport math\nfrom math import sqrt\nimport warnings\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\n\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\nfrom ipc_pad_size_calculators import *\nfrom quad_dual_pad_border import add_dual_or_quad_pad_border\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"utils\"))\nfrom ep_handling_utils import getEpRoundRadiusParams\n\nipc_density = 'nominal'\nipc_doc_file = '../ipc_definitions.yaml'\ncategory = 'NoLead'\ndefault_library = 'Package_DFN_QFN'\n\nDEFAULT_PASTE_COVERAGE = 0.65\nDEFAULT_VIA_PASTE_CLEARANCE = 0.15\nDEFAULT_MIN_ANNULAR_RING = 0.15\n\nSILK_MIN_LEN = 0.1\n\nDEBUG_LEVEL = 0\n\ndef roundToBase(value, base):\n    return round(value/base) * base\n\nclass NoLead():\n    def __init__(self, configuration):\n        self.configuration = configuration\n        with open(ipc_doc_file, 'r') as ipc_stream:\n            try:\n                self.ipc_defintions = yaml.safe_load(ipc_stream)\n\n                self.configuration['min_ep_to_pad_clearance'] = 0.2\n\n                #ToDo: find a settings file that can contain these.\n                self.configuration['paste_radius_ratio'] = 0.25\n                self.configuration['paste_maximum_radius'] = 0.25\n\n                if 'ipc_generic_rules' in self.ipc_defintions:\n                    self.configuration['min_ep_to_pad_clearance'] = self.ipc_defintions['ipc_generic_rules'].get('min_ep_to_pad_clearance', 0.2)\n\n            except yaml.YAMLError as exc:\n                print(exc)\n\n    def calcPadDetails(self, device_dimensions, EP_size, ipc_data, ipc_round_base):\n        # Zmax = Lmin + 2JT + √(CL^2 + F^2 + P^2)\n        # Gmin = Smax − 2JH − √(CS^2 + F^2 + P^2)\n        # Xmax = Wmin + 2JS + √(CW^2 + F^2 + P^2)\n\n        # Some manufacturers do not list the terminal spacing (S) in their datasheet but list the terminal lenght (T)\n        # Then one can calculate\n        # Stol(RMS) = √(Ltol^2 + 2*^2)\n        # Smin = Lmin - 2*Tmax\n        # Smax(RMS) = Smin + Stol(RMS)\n\n        manf_tol = {\n            'F': self.configuration.get('manufacturing_tolerance', 0.1),\n            'P': self.configuration.get('placement_tolerance', 0.05)\n        }\n\n        pull_back_0 = TolerancedSize(nominal=0)\n        pull_back = device_dimensions.get('lead_to_edge', pull_back_0)\n\n        if 'lead_center_pos_x' in device_dimensions or 'lead_center_pos_y' in device_dimensions:\n            Gmin_x, Zmax_x, Xmax = ipc_pad_center_plus_size(ipc_data, ipc_round_base, manf_tol,\n                    center_position=device_dimensions.get('lead_center_pos_x', TolerancedSize(nominal=0)),\n                    lead_length=device_dimensions.get('lead_len_H'),\n                    lead_width=device_dimensions['lead_width'])\n\n            Gmin_y, Zmax_y, Xmax_y_ignored = ipc_pad_center_plus_size(ipc_data, ipc_round_base, manf_tol,\n                    center_position=device_dimensions.get('lead_center_pos_y', TolerancedSize(nominal=0)),\n                    lead_length=device_dimensions.get('lead_len_H'),\n                    lead_width=device_dimensions['lead_width'])\n        else:\n            Gmin_x, Zmax_x, Xmax = ipc_body_edge_inside_pull_back(\n                    ipc_data, ipc_round_base, manf_tol,\n                    body_size=device_dimensions['body_size_x'],\n                    lead_width=device_dimensions['lead_width'],\n                    lead_len=device_dimensions.get('lead_len_H'),\n                    body_to_inside_lead_edge=device_dimensions.get('body_to_inside_lead_edge'),\n                    heel_reduction=device_dimensions.get('heel_reduction', 0),\n                    pull_back=pull_back\n                    )\n\n            Gmin_y, Zmax_y, Xmax_y_ignored = ipc_body_edge_inside_pull_back(\n                    ipc_data, ipc_round_base, manf_tol,\n                    body_size=device_dimensions['body_size_y'],\n                    lead_width=device_dimensions['lead_width'],\n                    lead_len=device_dimensions.get('lead_len_V'),\n                    body_to_inside_lead_edge=device_dimensions.get('body_to_inside_lead_edge'),\n                    heel_reduction=device_dimensions.get('heel_reduction', 0),\n                    pull_back=pull_back\n                    )\n\n        min_ep_to_pad_clearance = self.configuration['min_ep_to_pad_clearance']\n\n        heel_reduction_max = 0\n\n        if Gmin_x - 2*min_ep_to_pad_clearance < EP_size['x']:\n            heel_reduction_max = ((EP_size['x'] + 2*min_ep_to_pad_clearance - Gmin_x)/2)\n            #print('{}, {}, {}'.format(Gmin_x, EP_size['x'], min_ep_to_pad_clearance))\n            Gmin_x = EP_size['x'] + 2*min_ep_to_pad_clearance\n        if Gmin_y - 2*min_ep_to_pad_clearance < EP_size['y']:\n            heel_reduction = ((EP_size['y'] + 2*min_ep_to_pad_clearance - Gmin_y)/2)\n            if heel_reduction>heel_reduction_max:\n                heel_reduction_max = heel_reduction\n            Gmin_y = EP_size['y'] + 2*min_ep_to_pad_clearance\n\n        heel_reduction_max += device_dimensions.get('heel_reduction', 0) #include legacy stuff\n        if heel_reduction_max > 0 and DEBUG_LEVEL >= 1:\n            print('Heel reduced by {:.4f} to reach minimum EP to pad clearances'.format(heel_reduction_max))\n\n        Pad = {}\n        Pad['left'] = {'center':[-(Zmax_x+Gmin_x)/4, 0], 'size':[(Zmax_x-Gmin_x)/2,Xmax]}\n        Pad['right'] = {'center':[(Zmax_x+Gmin_x)/4, 0], 'size':[(Zmax_x-Gmin_x)/2,Xmax]}\n        Pad['top'] = {'center':[0,-(Zmax_y+Gmin_y)/4], 'size':[Xmax,(Zmax_y-Gmin_y)/2]}\n        Pad['bottom'] = {'center':[0,(Zmax_y+Gmin_y)/4], 'size':[Xmax,(Zmax_y-Gmin_y)/2]}\n\n        return Pad\n\n    @staticmethod\n    def deviceDimensions(device_size_data, fp_id):\n        unit = device_size_data.get('unit')\n        dimensions = {\n            'body_size_x': TolerancedSize.fromYaml(device_size_data, base_name='body_size_x', unit=unit),\n            'body_size_y': TolerancedSize.fromYaml(device_size_data, base_name='body_size_y', unit=unit),\n            'lead_width': TolerancedSize.fromYaml(device_size_data, base_name='lead_width', unit=unit),\n            'pitch': TolerancedSize.fromYaml(device_size_data, base_name='pitch', unit=unit).nominal\n        }\n        dimensions['has_EP'] = False\n        if 'EP_size_x_min' in device_size_data and 'EP_size_x_max' in device_size_data or 'EP_size_x' in device_size_data:\n            dimensions['EP_size_x'] = TolerancedSize.fromYaml(device_size_data, base_name='EP_size_x', unit=unit)\n            dimensions['EP_size_y'] = TolerancedSize.fromYaml(device_size_data, base_name='EP_size_y', unit=unit)\n            dimensions['has_EP'] = True\n            dimensions['EP_center_x'] = TolerancedSize(nominal=0)\n            dimensions['EP_center_y'] = TolerancedSize(nominal=0)\n            if 'EP_center_x' in device_size_data and 'EP_center_y' in device_size_data:\n                dimensions['EP_center_x'] = TolerancedSize.fromYaml(device_size_data, base_name='EP_center_x', unit=unit)\n                dimensions['EP_center_y'] = TolerancedSize.fromYaml(device_size_data, base_name='EP_center_y', unit=unit)\n\n        if 'heel_reduction' in device_size_data:\n            print(\n                \"\\033[1;35mThe use of manual heel reduction is deprecated. It is automatically calculated from the minimum EP to pad clearance (ipc config file)\\033[0m\"\n            )\n            dimensions['heel_reduction'] = device_size_data.get('heel_reduction', 0)\n\n        if 'lead_to_edge' in device_size_data:\n            dimensions['lead_to_edge'] = TolerancedSize.fromYaml(device_size_data, base_name='lead_to_edge', unit=unit)\n\n        if 'lead_center_pos_x' in device_size_data:\n            dimensions['lead_center_pos_x'] = TolerancedSize.fromYaml(device_size_data, base_name='lead_center_pos_x', unit=unit)\n        if 'lead_center_to_center_x' in device_size_data:\n            dimensions['lead_center_pos_x'] = TolerancedSize.fromYaml(device_size_data, base_name='lead_center_to_center_x', unit=unit)/2\n\n        if 'lead_center_pos_y' in device_size_data:\n            dimensions['lead_center_pos_y'] = TolerancedSize.fromYaml(device_size_data, base_name='lead_center_pos_y', unit=unit)\n        if 'lead_center_to_center_y' in device_size_data:\n            dimensions['lead_center_pos_y'] = TolerancedSize.fromYaml(device_size_data, base_name='lead_center_to_center_y', unit=unit)/2\n\n        dimensions['lead_len_H'] = None\n        dimensions['lead_len_V'] = None\n        if 'lead_len_H' in device_size_data and 'lead_len_V' in device_size_data:\n            dimensions['lead_len_H'] = TolerancedSize.fromYaml(device_size_data, base_name='lead_len_H', unit=unit)\n            dimensions['lead_len_V'] = TolerancedSize.fromYaml(device_size_data, base_name='lead_len_V', unit=unit)\n        elif 'lead_len' in device_size_data or (\n                'lead_len_min' in device_size_data and 'lead_len_max' in device_size_data):\n            dimensions['lead_len_H'] = TolerancedSize.fromYaml(device_size_data, base_name='lead_len', unit=unit)\n            dimensions['lead_len_V'] = dimensions['lead_len_H']\n\n        if 'body_to_inside_lead_edge' in device_size_data:\n            dimensions['body_to_inside_lead_edge'] = TolerancedSize.fromYaml(device_size_data, base_name='body_to_inside_lead_edge', unit=unit)\n        elif dimensions['lead_len_H'] is None:\n            raise KeyError('{}: Either lead lenght or inside lead to edge dimension must be given.'.format(fp_id))\n\n        return dimensions\n\n    def generateFootprint(self, device_params, fp_id):\n        print('Building footprint for parameter set: {}'.format(fp_id))\n        device_dimensions = NoLead.deviceDimensions(device_params, fp_id)\n\n        if device_dimensions['has_EP'] and 'thermal_vias' in device_params:\n            self.__createFootprintVariant(device_params, device_dimensions, True)\n\n        self.__createFootprintVariant(device_params, device_dimensions, False)\n\n    def __createFootprintVariant(self, device_params, device_dimensions, with_thermal_vias):\n        fab_line_width = self.configuration.get('fab_line_width', 0.1)\n        silk_line_width = self.configuration.get('silk_line_width', 0.12)\n\n        lib_name = device_params.get('library', default_library)\n\n        pincount = device_params['num_pins_x']*2 + device_params['num_pins_y']*2\n\n        default_ipc_config = 'qfn_pull_back' if 'lead_to_edge' in device_params else 'qfn'\n        if device_params.get('ipc_class', default_ipc_config) == 'qfn_pull_back':\n            ipc_reference = 'ipc_spec_flat_no_lead_pull_back'\n        else:\n            ipc_reference = 'ipc_spec_flat_no_lead'\n\n        used_density = device_params.get('ipc_density', ipc_density)\n        ipc_data_set = self.ipc_defintions[ipc_reference][used_density]\n        ipc_round_base = self.ipc_defintions[ipc_reference]['round_base']\n\n        layout = ''\n        if device_dimensions['has_EP']:\n            name_format = self.configuration['fp_name_EP_format_string_no_trailing_zero']\n            if 'EP_size_x_overwrite' in device_params:\n                EP_size = {\n                    'x':device_params['EP_size_x_overwrite'],\n                    'y':device_params['EP_size_y_overwrite']\n                    }\n            else:\n                EP_size = {\n                    'x':device_dimensions['EP_size_x'].nominal,\n                    'y':device_dimensions['EP_size_y'].nominal\n                    }\n            EP_center = {\n                'x':device_dimensions['EP_center_x'].nominal,\n                'y':device_dimensions['EP_center_y'].nominal\n                }\n        else:\n            name_format = self.configuration['fp_name_format_string_no_trailing_zero']\n            if device_params.get('use_name_format', 'QFN') == 'LGA':\n                name_format = self.configuration['fp_name_lga_format_string_no_trailing_zero']\n                if device_params['num_pins_x'] > 0 and device_params['num_pins_y'] > 0:\n                    layout = self.configuration['lga_layout_border'].format(\n                        nx=device_params['num_pins_x'], ny=device_params['num_pins_y'])\n\n            EP_size = {'x':0, 'y':0}\n\n        if 'custom_name_format' in device_params:\n            name_format = device_params['custom_name_format']\n\n        pad_details = self.calcPadDetails(device_dimensions, EP_size, ipc_data_set, ipc_round_base)\n\n\n        pad_suffix = '_Pad{pad_x:.2f}x{pad_y:.2f}mm'.format(pad_x=pad_details['left']['size'][0],\n            pad_y=pad_details['left']['size'][1])\n        pad_suffix = '' if device_params.get('include_pad_size', 'none') not in ('fp_name_only', 'both') else pad_suffix\n        pad_suffix_3d = '' if device_params.get('include_pad_size', 'none') not in ('both') else pad_suffix\n\n        suffix = device_params.get('suffix', '')\n        suffix_3d = suffix if device_params.get('include_suffix_in_3dpath', 'True') == 'True' else \"\"\n\n        model3d_path_prefix = self.configuration.get('3d_model_prefix','${KISYS3DMOD}')\n\n        size_x = device_dimensions['body_size_x'].nominal\n        size_y = device_dimensions['body_size_y'].nominal\n\n        fp_name = name_format.format(\n            man=device_params.get('manufacturer',''),\n            mpn=device_params.get('part_number',''),\n            pkg=device_params['device_type'],\n            pincount=pincount,\n            size_y=size_y,\n            size_x=size_x,\n            pitch=device_dimensions['pitch'],\n            layout=layout,\n            ep_size_x = EP_size['x'],\n            ep_size_y = EP_size['y'],\n            suffix=pad_suffix,\n            suffix2=suffix,\n            vias=self.configuration.get('thermal_via_suffix', '_ThermalVias') if with_thermal_vias else ''\n            ).replace('__','_').lstrip('_')\n\n        fp_name_2 = name_format.format(\n            man=device_params.get('manufacturer',''),\n            mpn=device_params.get('part_number',''),\n            pkg=device_params['device_type'],\n            pincount=pincount,\n            size_y=size_y,\n            size_x=size_x,\n            pitch=device_dimensions['pitch'],\n            layout=layout,\n            ep_size_x = EP_size['x'],\n            ep_size_y = EP_size['y'],\n            suffix=pad_suffix_3d,\n            suffix2=suffix_3d,\n            vias=''\n            ).replace('__','_').lstrip('_')\n\n        if 'fp_name_prefix' in device_params:\n            prefix = device_params['fp_name_prefix']\n            if not prefix.endswith('_'):\n                prefix += '_'\n            fp_name = prefix + fp_name\n            fp_name_2 = prefix + fp_name_2\n\n        model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'\\\n            .format(\n                model3d_path_prefix=model3d_path_prefix, lib_name=lib_name,\n                fp_name=fp_name_2)\n        #print(fp_name)\n        #print(pad_details)\n\n        kicad_mod = Footprint(fp_name)\n\n                # init kicad footprint\n        kicad_mod.setDescription(\n            \"{manufacturer} {mpn} {package}, {pincount} Pin ({datasheet}), generated with kicad-footprint-generator {scriptname}\"\\\n            .format(\n                manufacturer = device_params.get('manufacturer',''),\n                package = device_params['device_type'],\n                mpn = device_params.get('part_number',''),\n                pincount = pincount,\n                datasheet = device_params['size_source'],\n                scriptname = os.path.basename(__file__).replace(\"  \", \" \")\n                ).lstrip())\n\n        kicad_mod.setTags(self.configuration['keyword_fp_string']\\\n            .format(\n                man=device_params.get('manufacturer',''),\n                package=device_params['device_type'],\n                category=category\n            ).lstrip())\n        kicad_mod.setAttribute('smd')\n\n        pad_radius = add_dual_or_quad_pad_border(kicad_mod, self.configuration, pad_details, device_params)\n\n        if device_dimensions['has_EP']:\n            pad_shape_details = getEpRoundRadiusParams(device_params, self.configuration, pad_radius)\n            ep_pad_number = device_params.get('EP_pin_number', pincount+1)\n            if with_thermal_vias:\n                thermals = device_params['thermal_vias']\n                paste_coverage = thermals.get('EP_paste_coverage',\n                                               device_params.get('EP_paste_coverage', DEFAULT_PASTE_COVERAGE))\n\n                kicad_mod.append(ExposedPad(\n                    number=ep_pad_number, size=EP_size,\n                    at=EP_center,\n                    paste_layout=thermals.get('EP_num_paste_pads', device_params.get('EP_num_paste_pads', 1)),\n                    paste_coverage=paste_coverage,\n                    via_layout=thermals.get('count', 0),\n                    paste_between_vias=thermals.get('paste_between_vias'),\n                    paste_rings_outside=thermals.get('paste_rings_outside'),\n                    via_drill=thermals.get('drill', 0.3),\n                    via_grid=thermals.get('grid'),\n                    paste_avoid_via=thermals.get('paste_avoid_via', True),\n                    via_paste_clarance=thermals.get('paste_via_clearance', DEFAULT_VIA_PASTE_CLEARANCE),\n                    min_annular_ring=thermals.get('min_annular_ring', DEFAULT_MIN_ANNULAR_RING),\n                    bottom_pad_min_size=thermals.get('bottom_min_size', 0),\n                    kicad4_compatible=args.kicad4_compatible,\n                    **pad_shape_details\n                    ))\n            else:\n                kicad_mod.append(ExposedPad(\n                    number=ep_pad_number, size=EP_size,\n                    at=EP_center,\n                    paste_layout=device_params.get('EP_num_paste_pads', 1),\n                    paste_coverage=device_params.get('EP_paste_coverage', DEFAULT_PASTE_COVERAGE),\n                    kicad4_compatible=args.kicad4_compatible,\n                    **pad_shape_details\n                    ))\n\n        body_edge = {\n            'left': -size_x/2,\n            'right': size_x/2,\n            'top': -size_y/2,\n            'bottom': size_y/2\n            }\n\n        bounding_box = body_edge.copy()\n\n        if device_params['num_pins_x'] == 0 and EP_size['y'] > size_y:\n                bounding_box['top'] = -EP_size['y']/2\n                bounding_box['bottom'] = EP_size['y']/2\n\n        if device_params['num_pins_y'] == 0 and EP_size['x'] > size_x:\n                bounding_box['left'] = -EP_size['x']/2\n                bounding_box['right'] = EP_size['x']/2\n\n        if device_params['num_pins_y'] > 0:\n            bounding_box['left'] = pad_details['left']['center'][0] - pad_details['left']['size'][0]/2\n\n            bounding_box['right'] = pad_details['right']['center'][0] + pad_details['right']['size'][0]/2\n\n        if device_params['num_pins_x'] > 0:\n            bounding_box['top'] = pad_details['top']['center'][1] - pad_details['top']['size'][1]/2\n\n            bounding_box['bottom'] = pad_details['bottom']['center'][1] + pad_details['bottom']['size'][1]/2\n\n        pad_width = pad_details['top']['size'][0]\n\n        for key in body_edge:\n            if bounding_box[key] < 0:\n                bounding_box[key] = min(bounding_box[key], body_edge[key])\n            else:\n                bounding_box[key] = max(bounding_box[key], body_edge[key])\n\n        # ############################ SilkS ##################################\n\n        silk_pad_offset = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n        silk_offset = configuration['silk_fab_offset']\n        if device_params['num_pins_x'] == 0:\n            kicad_mod.append(Line(\n                start={'x':0,\n                    'y':body_edge['top']-silk_offset},\n                end={'x':body_edge['right'],\n                    'y':body_edge['top']-silk_offset},\n                width=configuration['silk_line_width'],\n                layer=\"F.SilkS\"))\n            kicad_mod.append(Line(\n                start={'x':body_edge['left'],\n                    'y':body_edge['bottom']+silk_offset},\n                end={'x':body_edge['right'],\n                    'y':body_edge['bottom']+silk_offset},\n                width=configuration['silk_line_width'],\n                layer=\"F.SilkS\", y_mirror=0))\n        elif device_params['num_pins_y'] == 0:\n            kicad_mod.append(Line(\n                start={'y':0,\n                    'x':body_edge['left']-silk_offset},\n                end={'y':body_edge['bottom'],\n                    'x':body_edge['left']-silk_offset},\n                width=configuration['silk_line_width'],\n                layer=\"F.SilkS\"))\n            kicad_mod.append(Line(\n                start={'y':body_edge['top'],\n                    'x':body_edge['right']+silk_offset},\n                end={'y':body_edge['bottom'],\n                    'x':body_edge['right']+silk_offset},\n                width=configuration['silk_line_width'],\n                layer=\"F.SilkS\", x_mirror=0))\n        else:\n            sx1 = -(device_dimensions['pitch']*(device_params['num_pins_x']-1)/2.0\n                + pad_width/2.0 + silk_pad_offset)\n\n            sy1 = -(device_dimensions['pitch']*(device_params['num_pins_y']-1)/2.0\n                + pad_width/2.0 + silk_pad_offset)\n\n            poly_silk = [\n                {'x': sx1, 'y': body_edge['top']-silk_offset},\n                {'x': body_edge['left']-silk_offset, 'y': body_edge['top']-silk_offset},\n                {'x': body_edge['left']-silk_offset, 'y': sy1}\n            ]\n            if sx1 - SILK_MIN_LEN < body_edge['left']-silk_offset:\n                poly_silk = poly_silk[1:]\n            if sy1 - SILK_MIN_LEN < body_edge['top']-silk_offset:\n                poly_silk = poly_silk[:-1]\n            if len(poly_silk) > 1:\n                kicad_mod.append(PolygoneLine(\n                    polygone=poly_silk,\n                    width=configuration['silk_line_width'],\n                    layer=\"F.SilkS\", x_mirror=0))\n                kicad_mod.append(PolygoneLine(\n                    polygone=poly_silk,\n                    width=configuration['silk_line_width'],\n                    layer=\"F.SilkS\", y_mirror=0))\n                kicad_mod.append(PolygoneLine(\n                    polygone=poly_silk,\n                    width=configuration['silk_line_width'],\n                    layer=\"F.SilkS\", x_mirror=0, y_mirror=0))\n                if len(poly_silk) > 2:\n                    kicad_mod.append(Line(\n                        start={'x': sx1, 'y': body_edge['top']-silk_offset},\n                        end={'x': body_edge['left']-silk_offset, 'y': body_edge['top']-silk_offset},\n                        width=configuration['silk_line_width'],\n                        layer=\"F.SilkS\"))\n\n        # # ######################## Fabrication Layer ###########################\n\n        fab_bevel_size = min(configuration['fab_bevel_size_absolute'], configuration['fab_bevel_size_relative']*min(size_x, size_y))\n\n        poly_fab = [\n            {'x': body_edge['left']+fab_bevel_size, 'y': body_edge['top']},\n            {'x': body_edge['right'], 'y': body_edge['top']},\n            {'x': body_edge['right'], 'y': body_edge['bottom']},\n            {'x': body_edge['left'], 'y': body_edge['bottom']},\n            {'x': body_edge['left'], 'y': body_edge['top']+fab_bevel_size},\n            {'x': body_edge['left']+fab_bevel_size, 'y': body_edge['top']},\n        ]\n\n        kicad_mod.append(PolygoneLine(\n            polygone=poly_fab,\n            width=configuration['fab_line_width'],\n            layer=\"F.Fab\"))\n\n        # # ############################ CrtYd ##################################\n\n        off = ipc_data_set['courtyard']\n        grid = configuration['courtyard_grid']\n\n        cy1=roundToBase(bounding_box['top']-off, grid)\n\n        kicad_mod.append(RectLine(\n            start={\n                'x':roundToBase(bounding_box['left']-off, grid),\n                'y':cy1\n                },\n            end={\n                'x':roundToBase(bounding_box['right']+off, grid),\n                'y':roundToBase(bounding_box['bottom']+off, grid)\n                },\n            width=configuration['courtyard_line_width'],\n            layer='F.CrtYd'))\n\n        # ######################### Text Fields ###############################\n\n        addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n            courtyard={'top': cy1, 'bottom': -cy1}, fp_name=fp_name, text_y_inside_position='center')\n\n        ##################### Output and 3d model ############################\n\n        kicad_mod.append(Model(filename=model_name))\n\n        output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n        if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n            os.makedirs(output_dir)\n        filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=fp_name)\n\n        file_handler = KicadFileHandler(kicad_mod)\n        file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('files', metavar='file', type=str, nargs='+',\n                        help='list of files holding information about what devices should be created.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../package_config_KLCv3.yaml')\n    parser.add_argument('--density', type=str, nargs='?', help='IPC density level (L,N,M)', default='N')\n    parser.add_argument('--ipc_doc', type=str, nargs='?', help='IPC definition document', default='../ipc_definitions.yaml')\n    parser.add_argument('--force_rectangle_pads', action='store_true', help='Force the generation of rectangle pads instead of rounded rectangle')\n    parser.add_argument('--kicad4_compatible', action='store_true', help='Create footprints kicad 4 compatible')\n    parser.add_argument('-v', '--verbose', action='count', help='set debug level')\n    args = parser.parse_args()\n\n    if args.density == 'L':\n        ipc_density = 'least'\n    elif args.density == 'M':\n        ipc_density = 'most'\n\n    if args.verbose:\n        DEBUG_LEVEL = args.verbose\n\n    ipc_doc_file = args.ipc_doc\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    if args.force_rectangle_pads or args.kicad4_compatible:\n        configuration['round_rect_max_radius'] = None\n        configuration['round_rect_radius_ratio'] = 0\n\n    configuration['kicad4_compatible'] = args.kicad4_compatible\n\n    for filepath in args.files:\n        no_lead = NoLead(configuration)\n\n        with open(filepath, 'r') as command_stream:\n            try:\n                cmd_file = yaml.safe_load(command_stream)\n            except yaml.YAMLError as exc:\n                print(exc)\n        for pkg in cmd_file:\n            no_lead.generateFootprint(cmd_file[pkg], pkg)\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/qfn.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nimport re\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))\n\nlib_name = \"Package_DFN_QFN\"\n\nfrom KicadModTree import *\n\ndef qfn(args):\n    footprint_name = args[\"name\"]\n    desc = args[\"description\"]\n\n    pkgWidth = args[\"pkg_width\"]\n    pkgHeight = args[\"pkg_height\"]\n\n    pitch = args[\"pitch\"]\n    nVertPads = args[\"n_vert_pads\"]\n    nHorzPads = args[\"n_horz_pads\"]\n    padWidth = args[\"pad_width\"]\n    padHeight = args[\"pad_height\"]\n    padHDistance = args[\"pad_h_distance\"]\n    padVDistance = args[\"pad_v_distance\"]\n\n    cornerPads = args[\"corner_pads\"]\n    cornerPadSize = args[\"corner_pad_size\"]\n    cornerPadHDistance = args[\"corner_pad_h_distance\"]\n    cornerPadVDistance = args[\"corner_pad_v_distance\"]\n\n    centerPad = args[\"center_pad\"]\n    centerPadWidth = args[\"center_pad_width\"]\n    centerPadHeight = args[\"center_pad_height\"]\n    centerPadHDiv = args[\"center_pad_h_div\"]\n    centerPadVDiv = args[\"center_pad_v_div\"]\n    pasteMarginRatio = args[\"paste_margin_ratio\"]\n\n    thermalVias = args[\"thermal_vias\"]\n    viaSize = args[\"via_size\"]\n\n    pat = re.compile('_ThermalVias')\n    model = pat.sub(\"\", footprint_name)\n\n    f = Footprint(footprint_name)\n    f.setDescription(desc)\n    f.setTags(\"QFN \" + str(pitch))\n    f.setAttribute(\"smd\")\n    f.append(Model(filename=\"${KISYS3DMOD}/Package_DFN_QFN.3dshapes/\" + model + \".wrl\",\n                   at=[0.0, 0.0, 0.0],\n                   scale=[1.0, 1.0, 1.0],\n                   rotate=[0.0, 0.0, 0.0]))\n\n    d = [viaSize, viaSize]\n\n    p1 = [viaSize + 0.3, viaSize + 0.3]\n    p2 = [padWidth, padHeight]\n    p3 = [cornerPadSize, cornerPadSize]\n\n    s1 = [0.65, 0.65]\n    s2 = [1.0, 1.0]\n\n    t1 = 0.125\n    t2 = 0.15\n\n    wCrtYd = 0.05\n    wFab = 0.10\n    wSilkS = 0.12\n\n    padShape = Pad.SHAPE_RECT\n\n    chamfer = min(1.0, 0.25*min(pkgWidth, pkgHeight))\n    silkOffset = 0.125\n    crtYd = 0.25\n    silkClearance = 0.2 + wSilkS / 2\n    bottomPadMargin = 0.5\n\n    xCenter = 0.0\n    xLeftFab = xCenter - pkgWidth / 2\n    xRightFab = xCenter + pkgWidth / 2\n    xChamferFab = xLeftFab + chamfer\n    xPadLeft = xCenter - (padHDistance / 2)\n    xPadRight = xCenter + (padHDistance / 2)\n    xLeftCrtYd = xPadLeft - (padWidth / 2 + crtYd)\n    xRightCrtYd = xPadRight + (padWidth / 2 + crtYd)\n\n    yCenter = 0.0\n    yTopFab = yCenter - pkgHeight / 2\n    yBottomFab = yCenter + pkgHeight / 2\n    yChamferFab = yTopFab + chamfer\n    yPadTop = yCenter - (padVDistance / 2)\n    yPadBottom = yCenter + (padVDistance / 2)\n    yTopCrtYd = yPadTop - (padWidth / 2 + crtYd)\n    yBottomCrtYd = yPadBottom + (padWidth / 2 + crtYd)\n    yRef = yTopCrtYd - 0.75\n    yValue = yBottomCrtYd + 0.75\n\n    if cornerPads:\n        hDist = (cornerPadHDistance + cornerPadSize) / 2 + silkClearance\n        vDist = (cornerPadVDistance + cornerPadSize) / 2 + silkClearance\n        xLeftSilk = xCenter - hDist\n        xRightSilk = xCenter + hDist\n        yTopSilk = yCenter - vDist\n        yBottomSilk = yCenter + vDist\n    else:\n        xLeftSilk = xLeftFab - silkOffset\n        xRightSilk = xRightFab + silkOffset\n        yTopSilk = yTopFab - silkOffset\n        yBottomSilk = yBottomFab + silkOffset\n\n    h2 = (pitch * (nHorzPads - 1) + padHeight) / 2 + silkClearance\n    v2 = (pitch * (nVertPads - 1) + padHeight) / 2 + silkClearance\n    xLeft2Silk = xCenter - h2\n    xRight2Silk = xCenter + h2\n    yTop2Silk = yCenter - v2\n    yBottom2Silk = yCenter + v2\n\n    # Text\n    f.append(Text(type=\"reference\", text=\"REF**\", at=[xCenter, yRef],\n                  layer=\"F.SilkS\", size=s2, thickness=t2))\n    f.append(Text(type=\"value\", text=footprint_name, at=[xCenter, yValue],\n                  layer=\"F.Fab\", size=s2, thickness=t2))\n    f.append(Text(type=\"user\", text=\"%R\", at=[xCenter, yCenter],\n                  layer=\"F.Fab\", size=s1, thickness=t1))\n\n    # Fab\n    f.append(PolygoneLine(polygone=[[xRightFab, yBottomFab],\n                                    [xLeftFab, yBottomFab],\n                                    [xLeftFab, yChamferFab],\n                                    [xChamferFab, yTopFab],\n                                    [xRightFab, yTopFab],\n                                    [xRightFab, yBottomFab]],\n                          layer=\"F.Fab\", width=wFab))\n\n    # Courtyard\n    f.append(RectLine(start=[xLeftCrtYd, yTopCrtYd],\n                      end=[xRightCrtYd, yBottomCrtYd],\n                      layer=\"F.CrtYd\", width=wCrtYd))\n\n    # Silk\n    f.append(PolygoneLine(polygone=[[xRight2Silk, yTopSilk],\n                                    [xRightSilk, yTopSilk],\n                                    [xRightSilk, yTop2Silk]],\n                          layer=\"F.SilkS\", width=wSilkS))\n    f.append(PolygoneLine(polygone=[[xLeft2Silk, yBottomSilk],\n                                    [xLeftSilk, yBottomSilk],\n                                    [xLeftSilk, yBottom2Silk]],\n                          layer=\"F.SilkS\", width=wSilkS))\n    f.append(PolygoneLine(polygone=[[xRight2Silk, yBottomSilk],\n                                    [xRightSilk, yBottomSilk],\n                                    [xRightSilk, yBottom2Silk]],\n                          layer=\"F.SilkS\", width=wSilkS))\n    f.append(Line(start=[xLeftSilk, yTopSilk],\n                  end=[xLeft2Silk, yTopSilk],\n                  layer=\"F.SilkS\", width=wSilkS))\n\n    # Pads\n    def padStart(n):\n        return (n-1) * pitch / 2\n\n    padNo = 1\n\n    if cornerPads:\n        f.append(Pad(number=str(padNo), type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                     at=[xCenter - cornerPadHDistance / 2,\n                         yCenter - cornerPadVDistance / 2],\n                     size=p3, layers=Pad.LAYERS_SMT))\n        padNo = padNo + 1\n\n    for i in range(0, nVertPads):\n        y = yCenter - padStart(nVertPads) + i * pitch\n        f.append(Pad(number=str(padNo), type=Pad.TYPE_SMT, shape=padShape,\n                     at=[xPadLeft, y], size=p2, layers=Pad.LAYERS_SMT))\n        padNo = padNo + 1\n\n    if cornerPads:\n        f.append(Pad(number=str(padNo), type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                     at=[xCenter - cornerPadHDistance / 2,\n                         yCenter + cornerPadVDistance / 2],\n                     size=p3, layers=Pad.LAYERS_SMT))\n        padNo = padNo + 1\n\n    for i in range(0, nHorzPads):\n        x = xCenter - padStart(nHorzPads) + i * pitch\n        f.append(Pad(number=str(padNo), type=Pad.TYPE_SMT, shape=padShape,\n                     rotation=90.0,\n                     at=[x, yPadBottom], size=p2, layers=Pad.LAYERS_SMT))\n        padNo = padNo + 1\n\n    if cornerPads:\n        f.append(Pad(number=str(padNo), type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                     at=[xCenter + cornerPadHDistance / 2,\n                         yCenter + cornerPadVDistance / 2],\n                     size=p3, layers=Pad.LAYERS_SMT))\n        padNo = padNo + 1\n\n    for i in range(0, nVertPads):\n        y = yCenter + padStart(nVertPads) - i * pitch\n        f.append(Pad(number=str(padNo), type=Pad.TYPE_SMT, shape=padShape,\n                     at=[xPadRight, y], size=p2, layers=Pad.LAYERS_SMT))\n        padNo = padNo + 1\n\n    if cornerPads:\n        f.append(Pad(number=str(padNo), type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                     at=[xCenter + cornerPadHDistance / 2,\n                         yCenter - cornerPadVDistance / 2],\n                     size=p3, layers=Pad.LAYERS_SMT))\n        padNo = padNo + 1\n\n    for i in range(0, nHorzPads):\n        x = xCenter + padStart(nHorzPads) - i * pitch\n        f.append(Pad(number=str(padNo), type=Pad.TYPE_SMT, shape=padShape,\n                     rotation=90.0,\n                     at=[x, yPadTop], size=p2, layers=Pad.LAYERS_SMT))\n        padNo = padNo + 1\n\n    if centerPad:\n        if thermalVias:\n            f.append(Pad(number=str(padNo),\n                         type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                         at=[xCenter, yCenter],\n                         size=[centerPadWidth + 2 * bottomPadMargin,\n                               centerPadHeight + 2 * bottomPadMargin],\n                         layers=[\"B.Cu\"]))\n\n        f.append(Pad(number=str(padNo),\n                     type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                     at=[xCenter, yCenter],\n                     size=[centerPadWidth, centerPadHeight],\n                     layers=[\"F.Cu\", \"F.Mask\"]))\n\n        subPadWidth = centerPadWidth / centerPadHDiv\n        subPadHeight = centerPadHeight / centerPadVDiv\n        subPadStartX = xCenter - (centerPadHDiv - 1) * subPadWidth / 2\n        subPadStartY = yCenter - (centerPadVDiv - 1) * subPadHeight / 2\n\n        pasteRatio = 1 + 2 * pasteMarginRatio\n\n        for i in range(0, centerPadHDiv):\n            x = subPadStartX + i * subPadWidth\n            for j in range(0, centerPadVDiv):\n                y = subPadStartY + j * subPadHeight\n                f.append(Pad(number=\"\", type=Pad.TYPE_SMT,\n                             shape=Pad.SHAPE_RECT,\n                             at=[x, y],\n                             size=[subPadWidth * pasteRatio, subPadHeight * pasteRatio],\n                             layers=[\"F.Paste\"]))\n\n        if thermalVias:\n            nHVias = 2 * centerPadHDiv - 1\n            nVVias = 2 * centerPadVDiv - 1\n            viaHSpace = centerPadWidth / (nHVias + 1)\n            viaVSpace = centerPadHeight / (nVVias + 1)\n            viaStartX = xCenter - (nHVias - 1) * viaHSpace / 2\n            viaStartY = yCenter - (nVVias - 1) * viaVSpace / 2\n\n            for i in range(0, nHVias):\n                x = viaStartX + i * viaHSpace\n                for j in range(0, nVVias):\n                    y = viaStartY + j * viaVSpace\n                    if i % 2 == 1 or j % 2 == 1:\n                        f.append(Pad(number=str(padNo), type=Pad.TYPE_THT,\n                                     shape=Pad.SHAPE_CIRCLE, at=[x, y], size=p1,\n                                     layers=[\"*.Cu\"], drill=d))\n\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name)\n\n    file_handler = KicadFileHandler(f)\n    file_handler.writeFile(filename)\n\n\nif __name__ == '__main__':\n    parser = ModArgparser(qfn)\n    # the root node of .yml files is parsed as name\n    parser.add_parameter(\"name\", type=str, required=True)\n    parser.add_parameter(\"description\", type=str, required=True)\n    parser.add_parameter(\"pkg_width\", type=float, required=True)\n    parser.add_parameter(\"pkg_height\", type=float, required=True)\n    parser.add_parameter(\"pitch\", type=float, required=False, default=0.5)\n    parser.add_parameter(\"n_vert_pads\", type=int, required=True)\n    parser.add_parameter(\"n_horz_pads\", type=int, required=True)\n    parser.add_parameter(\"pad_width\", type=float, required=False, default=0.9)\n    parser.add_parameter(\"pad_height\", type=float, required=False, default=0.3)\n    parser.add_parameter(\"pad_h_distance\", type=float, required=True)\n    parser.add_parameter(\"pad_v_distance\", type=float, required=True)\n    parser.add_parameter(\"corner_pads\", type=bool, required=False, default=False)\n    parser.add_parameter(\"corner_pad_size\", type=float, required=False, default=0.3)\n    parser.add_parameter(\"corner_pad_h_distance\", type=float, required=False, default=2.5)\n    parser.add_parameter(\"corner_pad_v_distance\", type=float, required=False, default=2.5)\n    parser.add_parameter(\"center_pad\", type=bool, required=False, default=False)\n    parser.add_parameter(\"center_pad_width\", type=float, required=False, default=1.8)\n    parser.add_parameter(\"center_pad_height\", type=float, required=False, default=1.8)\n    parser.add_parameter(\"center_pad_h_div\", type=int, required=False, default=2)\n    parser.add_parameter(\"center_pad_v_div\", type=int, required=False, default=2)\n    parser.add_parameter(\"paste_margin_ratio\", type=float, required=False, default=-0.2)\n    parser.add_parameter(\"thermal_vias\", type=bool, required=False, default=False)\n    parser.add_parameter(\"via_size\", type=float, required=False, default=0.3)\n\n    # now run our script which handles the whole part of parsing the files\n    parser.run()\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/qfn.yml",
    "content": "SiliconLabs_QFN-20-1EP_3x3mm_Pitch0.5mm_ThermalVias:\n  description: \"20-Lead Plastic Quad Flat, No Lead Package - 3x3 mm Body [QFN] with corner pads and thermal vias; see figure 8.2 of https://www.silabs.com/documents/public/data-sheets/efm8bb1-datasheet.pdf\"\n  pkg_width: 3.0\n  pkg_height: 3.0\n  pitch: 0.5\n  n_horz_pads: 4\n  n_vert_pads: 4\n  pad_width: 0.9\n  pad_height: 0.3\n  pad_h_distance: 3.1\n  pad_v_distance: 3.1\n  corner_pads: true\n  corner_pad_size: 0.3\n  corner_pad_h_distance: 2.5\n  corner_pad_v_distance: 2.5\n  center_pad: true\n  center_pad_width: 1.8\n  center_pad_height: 1.8\n  center_pad_h_div: 2\n  center_pad_v_div: 2\n  paste_margin_ratio: -0.2\n  thermal_vias: true\n  via_size: 0.3\nQFN-48-1EP_6x6mm_Pitch0.4mm_ThermalVias:\n  description: \"48-Lead Plastic Quad Flat, No Lead Package - 6x6 mm Body [QFN] with thermal vias; see figure 7.2 of https://static.dev.sifive.com/SiFive-FE310-G000-datasheet-v1.0.4.pdf\"\n  pkg_width: 6.0\n  pkg_height: 6.0\n  pitch: 0.4\n  n_horz_pads: 12\n  n_vert_pads: 12\n  pad_width: 0.65\n  pad_height: 0.2\n  pad_h_distance: 5.85\n  pad_v_distance: 5.85\n  corner_pads: false\n  center_pad: true\n  center_pad_width: 4.4\n  center_pad_height: 4.4\n  center_pad_h_div: 3\n  center_pad_v_div: 3\n  paste_margin_ratio: -0.2\n  thermal_vias: true\n  via_size: 0.3\nSiliconLabs_QFN-20-1EP_3x3mm_Pitch0.5mm:\n  description: \"20-Lead Plastic Quad Flat, No Lead Package - 3x3 mm Body [QFN] with corner pads; see figure 8.2 of https://www.silabs.com/documents/public/data-sheets/efm8bb1-datasheet.pdf\"\n  pkg_width: 3.0\n  pkg_height: 3.0\n  pitch: 0.5\n  n_horz_pads: 4\n  n_vert_pads: 4\n  pad_width: 0.9\n  pad_height: 0.3\n  pad_h_distance: 3.1\n  pad_v_distance: 3.1\n  corner_pads: true\n  corner_pad_size: 0.3\n  corner_pad_h_distance: 2.5\n  corner_pad_v_distance: 2.5\n  center_pad: true\n  center_pad_width: 1.8\n  center_pad_height: 1.8\n  center_pad_h_div: 2\n  center_pad_v_div: 2\n  paste_margin_ratio: -0.2\n  thermal_vias: false\nQFN-48-1EP_6x6mm_Pitch0.4mm:\n  description: \"48-Lead Plastic Quad Flat, No Lead Package - 6x6 mm Body [QFN]; see figure 7.2 of https://static.dev.sifive.com/SiFive-FE310-G000-datasheet-v1.0.4.pdf\"\n  pkg_width: 6.0\n  pkg_height: 6.0\n  pitch: 0.4\n  n_horz_pads: 12\n  n_vert_pads: 12\n  pad_width: 0.65\n  pad_height: 0.2\n  pad_h_distance: 5.85\n  pad_v_distance: 5.85\n  corner_pads: false\n  center_pad: true\n  center_pad_width: 4.4\n  center_pad_height: 4.4\n  center_pad_h_div: 3\n  center_pad_v_div: 3\n  paste_margin_ratio: -0.2\n  thermal_vias: false\nQFN-48-1EP_7x7mm_P0.5mm_EP5.6x5.6mm:\n  description: \"48-Lead Plastic Quad Flat, No Lead Package - 7x7 mm Body [QFN]; see figure 37 of http://www.st.com/resource/en/datasheet/stm32f042k6.pdf\"\n  pkg_width: 7.0\n  pkg_height: 7.0\n  pitch: 0.5\n  n_horz_pads: 12\n  n_vert_pads: 12\n  pad_width: 0.55\n  pad_height: 0.3\n  pad_h_distance: 6.75\n  pad_v_distance: 6.75\n  corner_pads: false\n  center_pad: true\n  center_pad_width: 5.6\n  center_pad_height: 5.6\n  center_pad_h_div: 4\n  center_pad_v_div: 4\n  paste_margin_ratio: -0.1\n  thermal_vias: false\nQFN-44-1EP_9x9mm_Pitch0.65mm:\n  description: \"44-Lead Plastic Quad Flat, No Lead Package - 9x9 mm Body [QFN]; see section 10.3 of https://www.parallax.com/sites/default/files/downloads/P8X32A-Propeller-Datasheet-v1.4.0_0.pdf\"\n  pkg_width: 9.0\n  pkg_height: 9.0\n  pitch: 0.65\n  n_horz_pads: 11\n  n_vert_pads: 11\n  pad_width: 0.60\n  pad_height: 0.33\n  pad_h_distance: 8.6\n  pad_v_distance: 8.6\n  corner_pads: false\n  center_pad: true\n  center_pad_width: 7.5\n  center_pad_height: 7.5\n  center_pad_h_div: 2\n  center_pad_v_div: 2\n  paste_margin_ratio: -0.14666666666666667\n  thermal_vias: false\nQFN-44-1EP_9x9mm_Pitch0.65mm_ThermalVias:\n  description: \"44-Lead Plastic Quad Flat, No Lead Package - 9x9 mm Body [QFN] with thermal vias; see section 10.3 of https://www.parallax.com/sites/default/files/downloads/P8X32A-Propeller-Datasheet-v1.4.0_0.pdf\"\n  pkg_width: 9.0\n  pkg_height: 9.0\n  pitch: 0.65\n  n_horz_pads: 11\n  n_vert_pads: 11\n  pad_width: 0.60\n  pad_height: 0.33\n  pad_h_distance: 8.6\n  pad_v_distance: 8.6\n  corner_pads: false\n  center_pad: true\n  center_pad_width: 7.5\n  center_pad_height: 7.5\n  center_pad_h_div: 2\n  center_pad_v_div: 2\n  paste_margin_ratio: -0.14666666666666667\n  thermal_vias: true\n  via_size: 0.3\nQFN-36-1EP_6x6mm_P0.5mm_EP4.1x4.1mm:\n  description: \"36-Lead Plastic Quad Flat, No Lead Package - 6x6 mm Body [QFN]; see figure 36 of http://www.st.com/resource/en/datasheet/stm32f101t6.pdf\"\n  pkg_width: 6.0\n  pkg_height: 6.0\n  pitch: 0.5\n  n_horz_pads: 9\n  n_vert_pads: 9\n  pad_width: 0.75\n  pad_height: 0.3\n  pad_h_distance: 5.55\n  pad_v_distance: 5.55\n  corner_pads: false\n  center_pad: true\n  center_pad_width: 4.1\n  center_pad_height: 4.1\n  center_pad_h_div: 4\n  center_pad_v_div: 4\n  paste_margin_ratio: -0.1\n  thermal_vias: false\nQFN-76-1EP_9x9mm_P0.4mm_EP3.8x3.8mm:\n  description: \"76-Lead Plastic Quad Flat, No Lead Package - 9x9 mm Body [QFN]; see section 3.2 of https://www.marvell.com/documents/bqcwxsoiqfjkcjdjhkvc/\"\n  pkg_width: 9.0\n  pkg_height: 9.0\n  pitch: 0.4\n  n_horz_pads: 19\n  n_vert_pads: 19\n  pad_width: 1\n  pad_height: 0.2\n  pad_h_distance: 8.6\n  pad_v_distance: 8.6\n  corner_pads: false\n  center_pad: true\n  center_pad_width: 3.8\n  center_pad_height: 3.8\n  center_pad_h_div: 1\n  center_pad_v_div: 1\n  paste_margin_ratio: 0\n  thermal_vias: false\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/MicroSiP.yaml",
    "content": "Texas_MicroSiP-10-1EP_3.8x3.0mm_P0.6mm_EP0.7x2.9mm_ThermalVia:\n  device_type: 'MicroSiP'\n  library: Package_LGA\n  manufacturer: 'Texas'\n  part_number: 'SIL0010A'\n  size_source: 'http://www.ti.com/lit/ml/mpds579b/mpds579b.pdf'\n  ipc_class: 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n\n  body_size_x:\n    nominal: 3.8\n    tolerance: 0.1\n  body_size_y:\n    nominal: 3\n    tolerance: 0.1\n\n  lead_width:\n    nominal: 0.3\n    tolerance: 0.1\n  lead_len:\n    nominal: 0.65\n    tolerance: 0.1\n  # this will result in a pad 0.8x0.45 (max tolerance + placement_tolerance)\n  lead_center_pos_x:\n    nominal: 1.525\n    tolerance: 0\n\n  EP_size_x_min: 0.6\n  EP_size_x_max: 0.8\n  EP_size_y_min: 2.8\n  EP_size_y_max: 3.0\n  EP_center_x:\n    nominal: -0.175\n  EP_center_y:\n    nominal: 0\n  #EP_paste_coverage: 0.86\n  EP_num_paste_pads: [1, 3]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [1, 3]\n    grid: 1.03\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [1, 3]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.86\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.6\n  num_pins_x: 0\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: ''\n  include_suffix_in_3dpath: 'False'\n\nTexas_MicroSiP-8-1EP_2.8x3.0mm_P0.65mm_EP1.9x1.1mm_ThermalVia:\n  device_type: 'MicroSiP'\n  library: Package_LGA\n  manufacturer: 'Texas'\n  part_number: 'SIL0008D'\n  size_source: 'http://www.ti.com/lit/ds/symlink/tps82130.pdf#page=19'\n  ipc_class: 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n\n  body_size_x:\n    minimum: 2.7\n    maximum: 2.9\n  body_size_y:\n    minimum: 2.9\n    maximum: 3.1\n\n  lead_width:\n    minimum: 0.38\n    maximum: 0.42\n  lead_len:\n    minimum: 0.48\n    maximum: 0.52\n  lead_to_edge:\n    nominal: 0.1\n    tolerance: 0\n\n  EP_size_x:\n    minimum: 1.0\n    maximum: 1.2\n  EP_size_y:\n    minimum: 1.8\n    maximum: 2.0\n  EP_num_paste_pads: [1, 3]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [1, 3]\n    grid: 0.75\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [1, 3]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: ''\n  include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/csp.yaml",
    "content": "LFCSP-32-1EP_5x5mm_P0.5mm_EP3.1x3.1mm:\n  device_type: 'LFCSP'\n  library: Package_CSP\n  #manufacturer: 'Analog'\n  #part_number: 'CP-32-2'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/414143737956480539664569cp_32_2.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n  body_size_y:\n    nominal: 5\n  body_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 1\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.23\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.95\n    nominal: 3.1\n    maximum: 3.25\n  EP_size_y:\n    minimum: 2.95\n    nominal: 3.1\n    maximum: 3.25\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    #EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\n\nLFCSP-48-1EP_7x7mm_P0.5mm_EP4.1x4.1mm:\n  device_type: 'LFCSP'\n  library: Package_CSP\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/lfcspcp/cp_48_5.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'LFCSP-{pincount}-1EP_{size_x:g}x{size_x:g}mm_P{pitch:g}mm_EP{ep_size_x:g}x{ep_size_x:g}mm{vias:s}'\n  body_size_x:\n    nominal: 7\n    tolerance: 0\n  body_size_y:\n    nominal: 7\n    tolerance: 0\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.23\n    maximum: 0.3\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 3.95\n    nominal: 4.1\n    maximum: 4.25\n  EP_size_y:\n    minimum: 3.95\n    nominal: 4.1\n    maximum: 4.25\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLFCSP-72-1EP_10x10mm_Pitch0.5mm_EP5.3x5.3mm_ThermalVias:\n  device_type: 'LFCSP'\n  library: Package_CSP\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/ADAU1452_1451_1450.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 9.9\n    nominal: 10.0\n    maximum: 10.1\n  body_size_y:\n    minimum: 9.9\n    nominal: 10.0\n    maximum: 10.1\n  lead_width:\n    minimum: 0.18\n    nominal: 0.23\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 5.15\n    nominal: 5.3\n    maximum: 5.45\n  EP_size_y:\n    minimum: 5.15\n    nominal: 5.3\n    maximum: 5.45\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 18\n  num_pins_y: 18\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/dfn.yaml",
    "content": "DFN-6-1EP_1.2x1.2mm_P0.4mm_EP0.3x0.94mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.onsemi.com/pub/Collateral/NCP133-D.PDF'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  #body_size_x_min: 2.85\n  body_size_x:\n    nominal: 1.2\n    tolerance: 0\n  #body_size_x_max: 3.15\n  #body_size_y_min: 2.85\n  body_size_y:\n    nominal: 1.2\n    tolerance: 0\n  #body_size_y_max: 3.15\n  lead_to_edge:\n    nominal: 0.05\n    tolerance: 0\n  lead_width_min: 0.13\n  lead_width_max: 0.23\n  lead_len_min: 0.15\n  lead_len_max: 0.25\n\n  EP_size_x_min: 0.2\n  EP_size_x_max: 0.4\n  EP_size_y_min: 0.84\n  EP_size_y_max: 1.04\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 3\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nDFN-6-1EP_2x1.8mm_P0.5mm_EP1.2x1.6mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.diodes.com/assets/Package-Files/U-DFN2018-6.pdf'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 2\n    minimum: 1.95\n    maximum: 2.075\n  body_size_y:\n    nominal: 1.8\n    minimum: 1.750\n    maximum: 1.875\n  lead_width_min: 0.15\n  lead_width_max: 0.25\n  lead_len_min: 0.2\n  lead_len_max: 0.3\n\n  EP_size_x: 1.2\n  EP_size_y: 1.6\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 3\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nDFN-6-1EP_2x2mm_P0.5mm_EP0.6x1.37mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-dfn/05081703_C_DC6.pdf'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 2\n    minimum: 1.9\n    maximum: 2.1\n  body_size_y:\n    nominal: 2\n    minimum: 1.9\n    maximum: 2.1\n  lead_width_min: 0.2\n  lead_width_max: 0.3\n  lead_len_min: 0.3\n  lead_len_max: 0.5\n\n  EP_size_x: 0.6\n  EP_size_y: 1.37\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n  # heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 3\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nDFN-6-1EP_3x2mm_P0.5mm_EP1.65x1.35mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-dfn/(DCB6)%20DFN%2005-08-1715%20Rev%20A.pdf'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x: 3\n  body_size_y: 2\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x: 1.65\n  EP_size_y: 1.35\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  heel_reduction: 0.0 #for relatively large EP pads (increase clearance)\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 3\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nDFN-6-1EP_3x3mm_P1mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.silabs.com/documents/public/data-sheets/Si7020-A20.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  #body_size_x_min: 2.85\n  body_size_x: 3.0\n  #body_size_x_max: 3.15\n  #body_size_y_min: 2.85\n  body_size_y: 3.0\n  #body_size_y_max: 3.15\n  lead_width_min: 0.35\n  lead_width_max: 0.45\n  lead_len_min: 0.35\n  lead_len_max: 0.45\n  EP_size_x_min: 1.4\n  EP_size_x: 1.5\n  EP_size_x_max: 1.6\n  EP_size_y_min: 2.3\n  EP_size_y: 2.4\n  EP_size_y_max: 2.5\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  pitch: 1.0\n  num_pins_x: 0\n  num_pins_y: 3\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nMLF-6-1EP_1.6x1.6mm_P0.5mm_EP0.5x1.26mm:\n  device_type: 'MLF'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/mic5353.pdf'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 1.6\n    tolerance: 0.05\n  body_size_y:\n    nominal: 1.6\n    tolerance: 0.05\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.35\n    tolerance: 0.05\n\n  EP_size_x:\n    nominal: 0.5\n    tolerance: 0.05\n  EP_size_y:\n    nominal: 1.26\n    tolerance: 0.05\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 3\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nDFN-8-1EP_2x2mm_P0.5mm_EP0.6x1.2mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.qorvo.com/products/d/da001879'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 2\n    tolerance: 0.05\n  body_size_y:\n    nominal: 2\n    tolerance: 0.05\n  overall_height:\n    minimum: 0.8\n    maximum: 1\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.35\n    tolerance: 0.05\n\n  EP_size_x:\n    nominal: 0.60\n    tolerance: 0.05\n#  EP_size_x_overwrite: 0.7\n  EP_size_y:\n    nominal: 1.20\n    tolerance: 0.05\n#  EP_size_y_overwrite: 1.3\n# EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nDFN-8-1EP_2x2mm_P0.5mm_EP0.7x1.3mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.onsemi.com/pub/Collateral/NUF4401MN-D.PDF#page=6'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 2\n    tolerance: 0\n  body_size_y:\n    nominal: 2\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    maximum: 1\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.25\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 0.5\n    maximum: 0.7\n  EP_size_x_overwrite: 0.7\n  EP_size_y:\n    minimum: 1.1\n    maximum: 1.3\n  EP_size_y_overwrite: 1.3\n# EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nDFN-8-1EP_3x2mm_P0.5mm_EP0.56x2.15mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/2451fg.pdf#page=17'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 2\n    tolerance: 0.1\n  body_size_y:\n    nominal: 3\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 0.56\n    tolerance: 0.05\n# EP_size_x_overwrite: 0.56\n  EP_size_y:\n    nominal: 2.15\n    tolerance: 0.05\n# EP_size_y_overwrite: 2.15\n# EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n  #\nDFN-8-1EP_2x2mm_P0.5mm_EP0.8x1.2mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.onsemi.com/pub/Collateral/NB3N551-D.PDF#page=7'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 2\n    tolerance: 0\n  body_size_y:\n    nominal: 2\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    maximum: 1\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.25\n    maximum: 0.35\n\n  EP_size_x:\n    minimum: 0.7\n    maximum: 0.9\n  EP_size_x_overwrite: 0.9\n  EP_size_y:\n    minimum: 1.1\n    maximum: 1.3\n  EP_size_y_overwrite: 1.3\n# EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nDFN-8-1EP_2x2mm_P0.5mm_EP0.9x1.5mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8127-AVR-8-bit-Microcontroller-ATtiny4-ATtiny5-ATtiny9-ATtiny10_Datasheet.pdf'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 2\n    tolerance: 0.05\n  body_size_y:\n    nominal: 2\n    tolerance: 0.05\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    nominal: 0.3\n    tolerance: 0.1\n\n  EP_size_x: 0.9\n  EP_size_y: 1.5\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  heel_reduction: 0.025 #for relatively large EP pads (increase clearance)\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nDFN-8-1EP_2x3mm_P0.5mm_EP1.7x1.4mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/8L_DFN_2x3x0_9_MC_C04-123C.pdf'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 3\n    tolerance: 0\n  body_size_y:\n    nominal: 2\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    maximum: 1\n    nominal: 0.9\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n    nominal: 0.25\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n    nominal: 0.4\n  EP_size_x:\n    minimum: 1.5\n    maximum: 1.75\n  EP_size_x_overwrite: 1.7\n  EP_size_y:\n    minimum: 1.3\n    maximum: 1.55\n  EP_size_y_overwrite: 1.4\n# EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nDFN-8-1EP_2x2mm_P0.5mm_EP0.9x1.6mm:\n  device_type: 'DFN'\n  size_source: 'https://www.st.com/resource/en/datasheet/lm2903.pdf#page=16'\n  body_size_x: 1.85 .. 2.00 .. 2.15\n  body_size_y: 1.85 .. 2.00 .. 2.15\n  lead_width: 0.18 .. 0.25 .. 0.30\n  lead_len: 0.20 .. 0.30 .. 0.50 # only max given in DS.\n                                 # Min and nominal from JEDEC MO-229 V2020D-3\n\n  EP_size_x: 0.75 .. 0.9 .. 1.00\n  EP_size_y: 1.45 .. 1.6 .. 1.70\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n\nDFN-8-1EP_3x3mm_P0.5mm_EP1.65x2.38mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/4320fb.pdf#page=10'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  body_size_x:\n    nominal: 3\n    tolerance: 0.1\n  body_size_y:\n    nominal: 3\n    tolerance: 0.1\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n  \n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n\n  EP_size_x: 1.65\n  EP_size_y: 2.38\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    paste_avoid_via: False\n\nDFN-8-1EP_3x3mm_P0.65mm_EP1.7x2.05mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ixysic.com/home/pdfs.nsf/www/IX4426-27-28.pdf/$file/IX4426-27-28.pdf'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 3\n    tolerance: 0\n  body_size_y:\n    nominal: 3\n    tolerance: 0\n  lead_width:\n    nominal: 0.3\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.05\n\n  EP_size_x: 1.7\n  EP_size_y: 2.05\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  # heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nDFN-8-1EP_4x4mm_P0.8mm_EP2.3x3.24mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.st.com/resource/en/datasheet/ld1086.pdf#page=35'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    minimum: 3.90\n    nominal: 4\n    maximum: 4.10\n  body_size_y:\n    minimum: 3.90\n    nominal: 4\n    maximum: 4.10\n  lead_width:\n    minimum: 0.23\n    nominal: 0.30\n    maximum: 0.38\n  lead_len:\n    minumum: 0.4\n    nominal: 0.5\n    maximum: 0.6\n\n  EP_size_x:\n    minimum: 2.05\n    nominal: 2.20\n    maximum: 2.30\n\n  EP_size_y:\n    minimum: 2.82\n    nominal: 3\n    maximum: 3.23\n\n  EP_size_x_overwrite: 2.30\n  EP_size_y_overwrite: 3.24\n\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  # heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  pitch: 0.80\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nDFN-10-1EP_3x3mm_P0.5mm_EP1.7x2.5mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.monolithicpower.com/pub/media/document/MPQ2483_r1.05.pdf'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    minimum: 2.9\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    maximum: 3.1\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 1.45\n    maximum: 17.5\n  EP_size_x_overwrite: 1.7\n\n  EP_size_y:\n    minimum: 2.25\n    maximum: 2.55\n  EP_size_y_overwrite: 2.5\n\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 5\n\nDFN-10-1EP_3x3mm_P0.5mm_EP1.65x2.38mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/3471fb.pdf#page=15'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 3.0\n    tolerance: 0.1\n  body_size_y:\n    nominal: 3.0\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.38\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 1.65\n    tolerance: 0.05\n  EP_size_y:\n    nominal: 2.38\n    tolerance: 0.05\n\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    #EP_paste_coverage: 0.7\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 5\n\nBalun_Johanson_0900PC15J0013:\n  device_type: 'DFN'\n  manufacturer: 'Johanson'\n  part_number: '0900PC15J0013'\n  library: 'RF_Converter'\n  size_source: 'https://www.johansontechnology.com/datasheets/0900PC15J0013/0900PC15J0013.pdf'\n  custom_name_format: 'Balun_Johanson_0900PC15J0013'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 1.25\n    tolerance: 0.2\n  body_size_y:\n    nominal: 2\n    tolerance: 0.2\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.1\n  lead_len:\n    minimum: 0.05\n    nominal: 0.15 # should be 0.2mm by specs, but 0.8mm between pads is required.\n    maximum: 0.15 # should be 0.3mm by specs, but 0.8mm between pads is required.\n#  lead_to_edge: 0.1\n  pitch: 0.50\n  num_pins_x: 1\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  pad_length_addition: -0.1\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nTexas_S-PDSO-N10_EP1.2x2.0mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/tps7a91.pdf#page=30'\n  custom_name_format: 'Texas_S-PDSO-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    minimum: 2.4\n    maximum: 2.6\n  body_size_y:\n    minimum: 2.4\n    maximum: 2.6\n  overall_height:\n    minimum: 0.7\n    maximum: 0.8\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.35\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 1.1\n    maximum: 1.3\n  EP_size_y:\n    minimum: 1.9\n    maximum: 2.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  # heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nWDFN-8-1EP_2x2mm_P0.5mm_EP0.8x1.2mm:\n  device_type: 'WDFN'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/20005474E.pdf#page=25'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  body_size_x: 2.0\n  body_size_y: 2.0\n  lead_width: 0.25 +/- 0.05\n  lead_len: 0.3 +/- 0.05\n\n  EP_size_x:\n    minimum: 0.7\n    nominal: 0.8\n    maximum: 0.9\n  EP_size_y:\n    minimum: 1.1\n    nominal: 1.2\n    maximum: 1.3\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n\nWDFN-8-1EP_3x2mm_P0.5mm_EP1.3x1.4mm:\n  device_type: 'WDFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/8L_TDFN_2x3_MNY_C04-0129E-MNY.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 3.0\n    tolerance: 0\n  body_size_y:\n    nominal: 2.0\n    tolerance: 0\n  lead_width_min: 0.2\n  lead_width_max: 0.3\n  lead_len_min: 0.25\n  lead_len_max: 0.45\n\n\n  EP_size_x: 1.3\n  EP_size_y: 1.4\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nWDFN-8-1EP_4x3mm_P0.65mm_EP2.4x1.8mm:\n  device_type: 'WDFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.onsemi.com/pub/Collateral/509AF.PDF'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 4.0\n    tolerance: 0\n  body_size_y:\n    nominal: 3.0\n    tolerance: 0\n  lead_width_min: 0.2\n  lead_width_max: 0.3\n  lead_len_min: 0.45\n  lead_len_max: 0.55\n\n  EP_size_x:\n    minimum: 2.3\n    maximum: 2.5\n  EP_size_y:\n    minimum: 1.7\n    maximum: 1.9\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    #EP_paste_coverage: 0.7\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nWDFN-12-1EP_3x3mm_P0.45mm_EP1.7x2.5mm:\n  device_type: 'WDFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.diodes.com/assets/Datasheets/PAM2306.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    minimum: 2.95\n    maximum: 3.05\n  body_size_y:\n    minimum: 2.95\n    maximum: 3.05\n  lead_width_min: 0.15\n  lead_width_max: 0.25\n  lead_len_min: 0.35\n  lead_len_max: 0.45\n\n\n  EP_size_x: 1.7\n  EP_size_y: 2.5\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.45\n  num_pins_x: 0\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nBroadcom_DFN-6_2.0x2.0mm:\n  device_type: 'DFN'\n  size_source: 'https://docs.broadcom.com/docs/AV02-4755EN'\n  library: 'OptoDevice'\n  manufacturer: 'Broadcom'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  body_size_x:\n    nominal: 2\n    tolerance: 0.1\n  body_size_y:\n    nominal: 2\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.65\n    tolerance: 0.1\n  lead_width:\n    nominal: 0.3\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.75\n    tolerance: 0.15\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 3\n\nTexas_VSON-HR_1.5x2mm_P0.5mm:\n  device_type: 'VSON-HR'\n  size_source: 'http://www.ti.com/lit/ds/symlink/tps62823.pdf#page=29'\n  manufacturer: 'Texas'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  body_size_x:\n    minimum: 1.4\n    maximum: 1.6\n  body_size_y:\n    minimum: 1.9\n    maximum: 2.1\n  overall_height:\n    maximum: 1\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.4\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n\nTDFN-6-1EP_2.5x2.5mm_P0.65mm_EP1.3x2mm:\n  device_type: 'TDFN'\n  size_source: 'http://www.nve.com/Downloads/ab3.pdf'\n  body_size_x: 2.5 +/-0.1\n  body_size_y: 2.5 +/-0.1\n  overall_height: 0.8\n  lead_width: 0.3 +/-0.05\n  lead_len: 0.3 +/-0.05\n\n  EP_size_x: 1.3 +/-0.05\n  EP_size_y: 2.0 +/-0.05\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 3\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  suffix: ''\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nTDFN-14-1EP_3x3mm_P0.4mm_EP1.78x2.35mm:\n  device_type: 'TDFN'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0137.PDF (T1433-2C)'\n  body_size_x: 2.9 .. 3.0 .. 3.1\n  body_size_y: 2.9 .. 3.0 .. 3.1\n  overall_height: 0.7 .. 0.75 .. 0.8\n  lead_width: 0.2 +/-0.05\n  lead_len: 0.2 .. 0.3 .. 0.4\n\n  EP_size_x: 1.7 +/- 0.1\n  EP_size_y: 2.3 +/-0.1\n  EP_size_x_overwrite: 1.78\n  EP_size_y_overwrite: 2.35\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 0\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  suffix: ''\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nTDFN-10-1EP_2x3mm_P0.5mm_EP2.0x0.8mm:\n  device_type: 'TDFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0429.PDF'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 2.0\n    tolerance: 0.1\n  body_size_y:\n    nominal: 3.0\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.30\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 0.9\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.0\n    tolerance: 0.1\n\n  EP_num_paste_pads: [1, 2]\n\n  thermal_vias:\n    count: [1, 2]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [1, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    #EP_paste_coverage: 0.7\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 5\n\nTDFN-8-1EP_2x2mm_P0.5mm_EP0.8x1.30mm:\n  device_type: 'TDFN'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0168.PDF'\n  body_size_x: 2.0 +/-0.1\n  body_size_y: 2.0 +/-0.1\n  overall_height: 0.75\n  lead_width: 0.25 +/-0.05\n  lead_len: 0.3 +/-0.1\n\n  EP_size_x: 0.8 +/-0.1\n  EP_size_y: 1.20 +/-0.1\n  EP_size_y_overwrite: 1.30 +/-0.1\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.50\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  suffix: ''\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nTDFN-8-1EP_3x2mm_P0.5mm_EP1.3x1.4mm:\n  device_type: 'TDFN'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/MCP6V66-Family-Data-Sheet-DS20006266A.pdf#page=35'\n  body_size_x: 3.0\n  body_size_y: 2.0\n  overall_height: 0.75\n  lead_width: 0.25 +/-0.05\n  lead_len: 0.3 +0.15 -0.05\n\n  EP_size_x: 1.3 +/-0.05\n  EP_size_y: 1.4 +/-0.05\n  #EP_size_y_overwrite: 1.30 +/-0.1\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.50\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  suffix: ''\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nTDFN-8-1EP_3x2mm_P0.5mm_EP1.4x1.4mm:\n  device_type: 'TDFN'\n  size_source: 'http://ww1.microchip.com/downloads/en/devicedoc/20005514a.pdf#page=35'\n  body_size_x: 3.00\n  body_size_y: 2.00\n  overall_height: \n    minimum: 0.70\n    nominal: 0.75\n    maximum: 0.80\n  lead_width: \n    minimum: 0.20\n    nominal: 0.25\n    maximum: 0.30\n  lead_len: \n    minimum: 0.25\n    nominal: 0.30\n    maximum: 0.45\n\n  EP_size_x: 1.20 .. 1.60\n  EP_size_y: 1.20 .. 1.60\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.50\n  num_pins_x: 0\n  num_pins_y: 4\n\nDFN-14_1.35x3.5mm_P0.5mm:\n  device_type: 'DFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://m.littelfuse.com/~/media/electronics/datasheets/tvs_diode_arrays/littelfuse_tvs_diode_array_sp3012_datasheet.pdf.pdf#page=7'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    minimum: 1.25\n    nominal: 1.35\n    maximum: 1.45\n  body_size_y:\n    minimum: 3.4\n    nominal: 3.5\n    maximum: 3.6\n  overall_height:\n    minimum: 0.45\n    nominal: 0.5\n    maximum: 0.55\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.25\n    nominal: 0.3\n    maximum: 0.35\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 7\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/hvson8.yaml",
    "content": "HVSON-8-1EP_4x4mm_P0.8mm_EP2.2x3.1mm:\n  device_type: 'HVSON'\n  library: Package_SON\n  size_source: 'https://www.nxp.com/docs/en/data-sheet/PCF8523.pdf (page 57)'\n  ipc_class: 'qfn' #'qfn' | 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    maximum: 4.1\n  overall_height:\n    minimum: 1.00\n  lead_width:\n    minimum: 0.30\n    maximum: 0.40\n  lead_len:\n    minimum: 0.4\n    maximum: 0.65\n\n  EP_size_x:\n    minimum: 2.05\n    maximum: 2.35\n  EP_size_y:\n    minimum: 2.95\n    maximum: 3.25\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.8\n  num_pins_x: 0\n  num_pins_y: 4\n\nHVSON-8-1EP_3x3mm_P0.65mm_EP1.6x2.4mm:\n  device_type: 'HVSON'\n  library: Package_SON\n  size_source: 'https://www.nxp.com/docs/en/data-sheet/TJA1051.pdf#page=16'\n  ipc_class: 'qfn' #'qfn' | 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    minimum: 2.9\n    nominal: 3.0\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3.0\n    maximum: 3.1\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 1.0\n  lead_width:\n    minimum: 0.25\n    nominal: 0.3\n    maximum: 0.35\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 1.55\n    nominal: 1.6\n    maximum: 1.65\n  EP_size_y:\n    minimum: 2.35\n    nominal: 2.4\n    maximum: 2.45\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/lfcsp.yaml",
    "content": "LFCSP-8-1EP_3x3mm_P0.5mm_EP1.74x1.45mm:\n  device_type: 'LFCSP'\n  library: Package_CSP\n  # manufacturer: 'Analog'\n  # part_number: 'CP-8-13'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/lfcspcp/cp-8/CP_8_13.pdf'\n  # ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  #body_size_x_min: 2.85\n  body_size_x:\n    nominal: 3.0\n    tolerance: 0.1\n  #body_size_x_max: 3.15\n  #body_size_y_min: 2.85\n  body_size_y:\n    nominal: 3.0\n    tolerance: 0.1\n  #body_size_y_max: 3.15\n  lead_to_edge:\n    nominal: 0.0\n    tolerance: 0.0\n  lead_width_min: 0.2\n  lead_width_max: 0.3\n  lead_len_min: 0.3\n  lead_len_max: 0.5\n\n  EP_size_x_min: 1.35\n  EP_size_x_max: 1.55\n  EP_size_y_min: 1.64\n  EP_size_y_max: 1.84\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n\nLFCSP-WD-8-1EP_3x3mm_P0.65mm_EP1.6x2.44mm:\n  device_type: 'LFCSP-WD'\n  library: Package_CSP\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/lfcspcp/CP_8_19.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    maximum: 0.35\n    nominal: 0.30\n    minimum: 0.20\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    maximum: 1.70\n    nominal: 1.60\n    minimum: 1.50\n  EP_size_y:\n    maximum: 2.54\n    nominal: 2.44\n    minimum: 2.34\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 3]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    #paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 3]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    #EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLFCSP-WD-10-1EP_3x3mm_P0.5mm_EP1.64x2.38mm:\n  device_type: 'LFCSP-WD'\n  library: Package_CSP\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/lfcspcp/cp-10/CP_10_9.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    maximum: 0.30\n    nominal: 0.25\n    minimum: 0.20\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    maximum: 1.74\n    nominal: 1.64\n    minimum: 1.49\n  EP_size_y:\n    maximum: 2.48\n    nominal: 2.38\n    minimum: 2.23\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 3]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 3]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLFCSP-16-1EP_3x3mm_P0.5mm_EP1.3x1.3mm:\n  device_type: 'LFCSP'\n  library: Package_CSP\n  # manufacturer: 'Analog'\n  # part_number: 'CP-16-21'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/lfcspcp/cp-16/CP_16_21.pdf'\n\n  body_size_x:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    maximum: 0.30\n    nominal: 0.23\n    minimum: 0.18\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    maximum: 1.45\n    nominal: 1.30\n    minimum: 1.15\n  EP_size_y:\n    maximum: 1.45\n    nominal: 1.30\n    minimum: 1.15\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.3\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n\nLFCSP-16-1EP_3x3mm_P0.5mm_EP1.6x1.6mm:\n  device_type: 'LFCSP'\n  library: Package_CSP\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/lfcspcp/cp-16/CP_16_22.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    maximum: 0.30\n    nominal: 0.23\n    minimum: 0.18\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    maximum: 1.75\n    nominal: 1.60\n    minimum: 1.45\n  EP_size_y:\n    maximum: 1.75\n    nominal: 1.60\n    minimum: 1.45\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLFCSP-16-1EP_3x3mm_P0.5mm_EP1.7x1.7mm:\n  device_type: 'LFCSP'\n  library: Package_CSP\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/HMC7992.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_height:\n    minimum: 0.75\n    nominal: 0.85\n    maximum: 0.95\n\n  lead_width:\n    maximum: 0.30\n    nominal: 0.25\n    minimum: 0.20\n  lead_len:\n    maximum: 0.35\n    nominal: 0.30\n    minimum: 0.25\n\n  EP_size_x:\n    maximum: 1.92\n    nominal: 1.70\n    minimum: 1.48\n  EP_size_y:\n    maximum: 1.92\n    nominal: 1.70\n    minimum: 1.48\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLFCSP-16-1EP_4x4mm_P0.65mm_EP2.4x2.4mm:\n  device_type: 'LFCSP'\n  library: Package_CSP\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/lfcspcp/cp-16/cp-16-40.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  body_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.27\n    nominal: 0.33\n    maximum: 0.39\n  lead_len:\n    minimum: 0.5\n    nominal: 0.6\n    maximum: 0.7\n\n  EP_size_x:\n    maximum: 2.55\n    nominal: 2.40\n    minimum: 2.25\n  EP_size_y:\n    maximum: 2.55\n    nominal: 2.40\n    minimum: 2.25\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLFCSP-20-1EP_4x4mm_P0.5mm_EP2.6x2.6mm:\n  device_type: 'LFCSP'\n  library: Package_CSP\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/lfcspcp/cp-20/CP_20_8.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  body_height:\n    minimum: 0.70\n    nominal: 0.75\n    maximum: 0.80\n\n  lead_width:\n    maximum: 0.30\n    nominal: 0.25\n    minimum: 0.18\n  lead_len:\n    maximum: 0.50\n    nominal: 0.40\n    minimum: 0.30\n\n  EP_size_x:\n    maximum: 2.75\n    nominal: 2.60\n    minimum: 2.35\n  EP_size_y:\n    maximum: 2.75\n    nominal: 2.60\n    minimum: 2.35\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.70\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLFCSP-24-1EP_4x4mm_P0.5mm_EP2.3x2.3mm:\n  device_type: 'LFCSP'\n  library: Package_CSP\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/lfcspcp/cp_24_14.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  body_height:\n    minimum: 0.70\n    nominal: 0.75\n    maximum: 0.80\n\n  lead_width:\n    maximum: 0.30\n    nominal: 0.25\n    minimum: 0.2\n  lead_len:\n    maximum: 0.50\n    nominal: 0.40\n    minimum: 0.30\n\n  EP_size_x:\n    maximum: 2.44\n    nominal: 2.30\n    minimum: 2.16\n  EP_size_y:\n    maximum: 2.44\n    nominal: 2.30\n    minimum: 2.16\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.70\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLFCSP-28-1EP_5x5mm_P0.5mm_EP3.14x3.14mm:\n  device_type: 'LFCSP'\n  library: Package_CSP\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/lfcspcp/cp-28/CP_28_10.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 4.9\n    nominal: 5\n    minimum: 5.1\n  body_size_y:\n    minimum: 4.9\n    nominal: 5\n    minimum: 5.1\n  body_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    maximum: 0.30\n    nominal: 0.25\n    minimum: 0.20\n  lead_len:\n    minimum: 0.48\n    nominal: 0.53\n    maximum: 0.58\n\n  EP_size_x:\n    maximum: 3.24\n    nominal: 3.14\n    minimum: 3.04\n  EP_size_y:\n    maximum: 3.24\n    nominal: 3.14\n    minimum: 3.04\n  #EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.70\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 7\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLFCSP-64-1EP_9x9mm_P0.5mm_EP5.21x5.21mm:\n  device_type: 'LFCSP'\n  library: Package_CSP\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/lfcspcp/cp_64_7.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 8.9\n    nominal: 9\n    minimum: 9.1\n  body_size_y:\n    minimum: 8.9\n    nominal: 9\n    minimum: 9.1\n  body_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 1.0\n\n  lead_width:\n    maximum: 0.30\n    nominal: 0.25\n    minimum: 0.18\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    maximum: 5.36\n    nominal: 5.21\n    minimum: 5.06\n  EP_size_y:\n    maximum: 5.36\n    nominal: 5.21\n    minimum: 5.06\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/lga.yaml",
    "content": "LGA-16_3x3mm_P0.5mm_LayoutBorder3x5y:\n  device_type: 'LGA'\n  library: Package_LGA\n  use_name_format: 'LGA'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.st.com/resource/en/datasheet/lis331hh.pdf'\n  ipc_class: 'qfn_pull_back'\n  body_size_x_min: 2.85\n  body_size_x: 3.0\n  body_size_x_max: 3.15\n  body_size_y_min: 2.85\n  body_size_y: 3.0\n  body_size_y_max: 3.15\n  lead_width_min: 0.19\n  lead_width_max: 0.31\n  lead_to_edge:\n    minimum: 0.04\n    maximum: 0.16\n  lead_len_min: 0.29\n  lead_len_max: 0.41\n  pitch: 0.5\n  num_pins_x: 3\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLGA-14_2x2mm_P0.35mm_LayoutBorder3x4y:\n  device_type: 'LGA'\n  library: Package_LGA\n  use_name_format: 'LGA'\n  ipc_density: 'least'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.st.com/resource/en/datasheet/lis2dh.pdf'\n  ipc_class: 'qfn_pull_back'\n  body_size_x_min: 1.85\n  body_size_x: 2.0\n  body_size_x_max: 2.15\n  body_size_y_min: 1.85\n  body_size_y: 2.0\n  body_size_y_max: 2.15\n  lead_width_min: 0.2\n  lead_width_max: 0.2\n  lead_to_edge:\n    nominal: 0.1\n  lead_len_min: 0.275\n  lead_len_max: 0.275\n  pitch: 0.35\n  num_pins_x: 3\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLGA-14_3x2.5mm_P0.5mm_LayoutBorder3x4y:\n  device_type: 'LGA'\n  library: Package_LGA\n  use_name_format: 'LGA'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.st.com/resource/en/datasheet/lsm6ds3.pdf'\n  ipc_class: 'qfn_pull_back'\n  body_size_x_min: 2.9\n  body_size_x: 3.0\n  body_size_x_max: 3.1\n  body_size_y_min: 2.4\n  body_size_y: 2.5\n  body_size_y_max: 2.6\n  lead_width_min: 0.15\n  lead_width_max: 0.35\n  lead_to_edge:\n    nominal: 0.1\n  lead_len_min: 0.35\n  lead_len_max: 0.55\n  pitch: 0.5\n  num_pins_x: 3\n  num_pins_y: 4\n  chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLGA-14_3x5mm_P0.8mm_LayoutBorder1x6y:\n  device_type: 'LGA'\n  library: Package_LGA\n  use_name_format: 'LGA'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.st.com/resource/en/datasheet/lsm303dlhc.pdf'\n  ipc_class: 'qfn_pull_back'\n  body_size_x_min: 2.85\n  body_size_x: 3.0\n  body_size_x_max: 3.15\n  body_size_y_min: 4.85\n  body_size_y: 5.0\n  body_size_y_max: 5.15\n  lead_width_min: 0.5\n  lead_width_max: 0.5\n  lead_to_edge:\n    nominal: 0.1\n  lead_len_min: 0.8\n  lead_len_max: 0.8\n  pitch: 0.8\n  num_pins_x: 1\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nLGA-16_4x4mm_P0.65mm_LayoutBorder4x4y:\n  device_type: 'LGA'\n  library: Package_LGA\n  use_name_format: 'LGA'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.st.com/resource/en/datasheet/l3gd20.pdf'\n  ipc_class: 'qfn_pull_back'\n  body_size_x_min: 3.85\n  body_size_x: 4.0\n  body_size_x_max: 4.15\n  body_size_y_min: 3.85\n  body_size_y: 4.0\n  body_size_y_max: 4.15\n  lead_width_min: 0.3\n  lead_width_max: 0.3\n  lead_to_edge:\n    nominal: 0.1\n  lead_len_min: 0.4\n  lead_len_max: 0.4\n  pitch: 0.65\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nNXP-8_3x5mm_P1.25mm_LayoutBorder2x4y_H1.2mm:\n  device_type: 'LGA'\n  library: Package_LGA\n  use_name_format: 'LGA'\n  manufacturer: 'NXP'\n  #part_number: 'MPL115A1'\n  size_source: 'https://www.nxp.com/docs/en/data-sheet/MPL115A1.pdf#page=15'\n  body_size_x:\n    nominal: 3\n    tolerance: 0\n  body_size_y:\n    nominal: 5\n    tolerance: 0\n  body_height:\n    maximum: 1.2\n  lead_width:\n    nominal: 0.5\n    tolerance: 0.05\n  lead_center_pos_x:\n    nominal: 1\n    tolerance: 0\n  lead_len:\n    nominal: 0.8\n    tolerance: 0.05\n  pitch: 1.25\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  suffix: '_H1.2mm'\n  #include_suffix_in_3dpath: 'False'\n\nNXP-8_3x5mm_P1.25mm_LayoutBorder2x4y_H1.1mm:\n  device_type: 'LGA'\n  library: Package_LGA\n  use_name_format: 'LGA'\n  manufacturer: 'NXP'\n  #part_number: 'MPL3115A2'\n  size_source: 'https://www.nxp.com/docs/en/data-sheet/MPL3115A2.pdf#page=42'\n  body_size_x:\n    nominal: 3\n    tolerance: 0\n  body_size_y:\n    nominal: 5\n    tolerance: 0\n  body_height:\n    maximum: 1.1\n    tolerance: 0.1\n  lead_width:\n    nominal: 0.5\n    tolerance: 0.05\n  lead_center_pos_x:\n    nominal: 1\n    tolerance: 0\n  lead_len:\n    nominal: 0.8\n    tolerance: 0.05\n  pitch: 1.25\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  suffix: '_H1.1mm'\n  #include_suffix_in_3dpath: 'False'\n\nBosch_LGA-8_3x3mm_P0.8mm:\n  device_type: 'LGA'\n  library: Package_LGA\n  use_name_format: 'LGA'\n  manufacturer: 'Bosch'\n  #part_number: 'mpn'\n  size_source: 'https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME680-DS001-00.pdf#page=44'\n  ipc_class: 'qfn_pull_back'\n  body_size_x_min: 2.95\n  body_size_x: 3.0\n  body_size_x_max: 3.05\n  body_size_y_min: 2.95\n  body_size_y: 3.0\n  body_size_y_max: 3.05\n  lead_width_min: 0.37\n  lead_width_max: 0.43\n  lead_to_edge:\n    minimum: 0.05\n    maximum: 0.15\n  lead_len_min: 0.37\n  lead_len_max: 0.43\n  pitch: 0.8\n  num_pins_x: 4\n  num_pins_y: 0\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  suffix: '_ClockwisePinNumbering'\n  #include_suffix_in_3dpath: 'False'\n\nST_HLGA-10_2.5x2.5mm_P0.6mm:\n  device_type: 'HLGA'\n  library: Package_LGA\n  use_name_format: 'LGA'\n  manufacturer: 'ST'\n  #part_number: 'mpn'\n  size_source: 'https://www.st.com/resource/en/datasheet/lps25hb.pdf#page=46'\n  ipc_class: 'qfn_pull_back'\n  body_size_x:\n    nominal: 2.5\n    tolerance: 0.1\n  body_size_y:\n    nominal: 2.5\n    tolerance: 0.1\n  lead_width:\n    nominal: 0.3\n    tolerance: 0.05\n  lead_center_pos_x:\n    nominal: 0.92\n    tolerance: 0\n  lead_center_pos_y:\n    nominal: 0.92\n    tolerance: 0\n  lead_len:\n    nominal: 0.45\n    tolerance: 0.05\n  pitch: 0.6\n  num_pins_x: 3\n  num_pins_y: 2\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_ClockwisePinNumbering'\n  #include_suffix_in_3dpath: 'False'\n\nBroadcom_LGA-8_2.0x2.0mm:\n  device_type: 'LGA'\n  size_source: 'https://docs.broadcom.com/docs/AV02-4755EN'\n  library: 'OptoDevice'\n  manufacturer: 'Broadcom'\n  ipc_class: 'qfn_pull_back'\n  body_size_x:\n    nominal: 2\n    tolerance: 0.1\n  body_size_y:\n    nominal: 2\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.34\n    tolerance: 0.1\n  lead_width:\n    nominal: 0.31\n    tolerance: 0.1\n  lead_len:\n    nominal: 0.35\n    tolerance: 0.1\n  lead_to_edge:\n    nominal: 0.05\n  pitch: 0.53\n  num_pins_x: 0\n  num_pins_y: 4\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/oscillator.yaml",
    "content": "Oscillator_SMD_Silicon_Labs_LGA-6_2.5x3.2mm_P1.25mm:\n  device_type: 'LGA'\n  library: Oscillator\n  fp_name_prefix: Oscillator_SMD\n  manufacturer: 'Silicon_Labs'\n  #part_number: ''\n  size_source: 'https://www.silabs.com/documents/public/data-sheets/si512-13.pdf'\n  ipc_class: 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n\n  body_size_x:\n    nominal: 2.5\n    tolerance: 0\n  body_size_y:\n    nominal: 3.2\n    tolerance: 0\n\n  lead_width:\n    minimum: 0.45\n    nominal: 0.5\n    maximum: 0.55\n  lead_len:\n    minimum: 0.65\n    nominal: 0.7\n    maximum: 0.75\n  lead_center_to_center_x:\n    nominal: 1.65\n    tolerance: 0\n\n  pitch: 1.25\n  num_pins_x: 0\n  num_pins_y: 3\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: ''\n  # include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/hvqfn.yaml",
    "content": "HVQFN-16-1EP_3x3mm_P0.5mm_EP1.5x1.5mm:\n  device_type: 'HVQFN'\n  #manufacturer: 'NXP'\n  #part_number: 'SOT758-1'\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT758-1.pdf'\n  ipc_class: 'qfn'\n  body_size_x:\n    minimum: 2.9\n    nominal: 3.0\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3.0\n    maximum: 3.1\n  overall_height:\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 1.45\n    maximum: 1.75\n  EP_size_y:\n    minimum: 1.45\n    maximum: 1.75\n  EP_size_x_overwrite: 1.5\n  EP_size_y_overwrite: 1.5\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n\nHVQFN-24-1EP_4x4mm_P0.5mm_EP2.5x2.5mm:\n  device_type: 'HVQFN'\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT616-3.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  body_size_x:\n    minimum: 3.9\n    nominal: 4.0\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    nominal: 4.0\n    maximum: 4.1\n  overall_height:\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.45\n    maximum: 2.75\n  EP_size_y:\n    minimum: 2.45\n    maximum: 2.75\n  EP_size_x_overwrite: 2.5\n  EP_size_y_overwrite: 2.5\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    EP_paste_coverage: 0.55\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n\nHVQFN-24-1EP_4x4mm_P0.5mm_EP2.6x2.6mm:\n  device_type: 'HVQFN'\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT616-3.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  body_size_x:\n    minimum: 3.9\n    nominal: 4.0\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    nominal: 4.0\n    maximum: 4.1\n  overall_height:\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.45\n    maximum: 2.75\n  EP_size_y:\n    minimum: 2.45\n    maximum: 2.75\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    EP_paste_coverage: 0.55\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n\nHVQFN-32-1EP_5x5mm_P0.5mm_EP3.1x3.1mm:\n  device_type: 'HVQFN'\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT617-1.pdf'\n  ipc_class: 'qfn'\n  body_size_x:\n    minimum: 4.9\n    nominal: 5.0\n    maximum: 5.1\n  body_size_y:\n    minimum: 4.9\n    nominal: 5.0\n    maximum: 5.1\n  overall_height:\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.95\n    maximum: 3.25\n  EP_size_y:\n    minimum: 2.95\n    maximum: 3.25\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    EP_paste_coverage: 0.55\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n\nHVQFN-40-1EP_6x6mm_P0.5mm_EP4.1x4.1mm:\n  device_type: 'HVQFN'\n  size_source: 'https://www.nxp.com/docs/en/package-information/SOT618-1.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  body_size_x:\n    minimum: 5.9\n    nominal: 6.0\n    maximum: 6.1\n  body_size_y:\n    minimum: 5.9\n    nominal: 6.0\n    maximum: 6.1\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    nominal: 0.21\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 3.95\n    maximum: 4.25\n  EP_size_y:\n    minimum: 3.95\n    maximum: 4.25\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    EP_paste_coverage: 0.6\n  pitch: 0.5\n  num_pins_x: 10\n  num_pins_y: 10"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-1x.yaml",
    "content": "QFN-12-1EP_3x3mm_P0.5mm_EP1.6x1.6mm:\n  device_type: 'QFN'\n  size_source: 'https://www.nxp.com/docs/en/data-sheet/MMZ09332B.pdf'\n  ipc_class: 'qfn'\n  body_size_x:\n    nominal: 3\n  body_size_y:\n    nominal: 3\n  overall_height:\n    minimum: 0.8\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 1.40\n    maximum: 1.60\n  EP_size_y:\n    minimum: 1.40\n    maximum: 1.60\n  EP_size_x_overwrite: 1.6\n  EP_size_y_overwrite: 1.6\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3,3]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [3, 3]\n    EP_paste_coverage: 0.75\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 3\n  num_pins_y: 3\n  \nQFN-12-1EP_3x3mm_P0.5mm_EP1.65x1.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/QFN_12_%2005-08-1855.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 1.55\n    nominal: 1.65\n    maximum: 1.75\n  EP_size_y:\n    minimum: 1.55\n    nominal: 1.65\n    maximum: 1.75\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 3\n  num_pins_y: 3\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-16-1EP_3x3mm_P0.5mm_EP1.45x1.45mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://cds.linear.com/docs/en/datasheet/37551fd.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 3\n    tolerance: 0.1\n  body_size_y:\n    nominal: 3\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x: 1.45\n  EP_size_y: 1.45\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-16-1EP_3x3mm_P0.5mm_EP1.7x1.7mm:\n  device_type: 'QFN'\n  ipc_class: 'qfn'\n  size_source: 'https://www.st.com/resource/en/datasheet/tsv521.pdf'\n  body_size_x:\n    minimum: 2.9\n    nominal: 3.0\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3.0\n    maximum: 3.1\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x: 1.7\n  EP_size_y: 1.7\n  heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n\nQFN-16-1EP_3x3mm_P0.5mm_EP1.75x1.75mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.onsemi.com/pub/Collateral/NCN4555-D.PDF'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 3\n    tolerance: 0\n  body_size_y:\n    nominal: 3\n    tolerance: 0\n  overall_height:\n    minimum: 0.7\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 1.65\n    maximum: 1.85\n  #EP_size_x_overwrite: 1.75\n  EP_size_y:\n    minimum: 1.65\n    maximum: 1.85\n  #EP_size_y_overwrite: 1.75\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-16-1EP_3x3mm_P0.5mm_EP1.9x1.9mm:\n  device_type: 'QFN'\n  ipc_class: 'qfn'\n  size_source: 'https://www.nxp.com/docs/en/package-information/98ASA00525D.pdf'\n  body_size_x:\n    nominal: 3.0\n  body_size_y:\n    nominal: 3.0\n  overall_height:\n    minimum: 0.5\n    maximum: 0.65\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.25\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 1.8\n    maximum: 2.0\n  EP_size_y:\n    minimum: 1.8\n    maximum: 2.0\n\n  EP_num_paste_pads: [2, 2]\n  heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n\nQFN-16-1EP_4x4mm_P0.65mm_EP2.1x2.1mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.thatcorp.com/datashts/THAT_1580_Datasheet.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  overall_height:\n    nominal: 0.9\n    tolerance: 0.05\n\n  lead_width:\n    minimum: 0.25\n    maximum: 0.35\n  lead_len:\n    minimum: 0.35\n    maximum: 0.45\n\n  EP_size_x: 2.1\n  EP_size_y: 2.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-16-1EP_4x4mm_P0.65mm_EP2.15x2.15mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/4001f.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0.1\n  body_size_y:\n    nominal: 4\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.3\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.55\n    tolerance: 0.2\n\n  EP_size_x:\n    nominal: 2.15\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.15\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-16-1EP_4x4mm_P0.5mm_EP2.45x2.45mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.renesas.com/eu/en/www/doc/datasheet/isl8117.pdf#page=22'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0\n  body_size_y:\n    nominal: 4\n    tolerance: 0\n  overall_height:\n    nominal: 0.9\n    tolerance: 0.1\n\n  lead_width:\n    nominal: 0.25\n    tolerance: [-0.07, 0.05]\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.01\n\n  EP_size_x:\n    nominal: 2.45\n    tolerance: [-0.15, 0.1]\n  EP_size_y:\n    nominal: 2.45\n    tolerance: [-0.15, 0.1]\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-16-1EP_4x4mm_P0.65mm_EP2.5x2.5mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=266'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n  body_size_y:\n    nominal: 4\n  overall_height:\n    nominal: 0.9\n    tolerance: 0.1\n\n  lead_width:\n    minimum: 0.25\n    nominal: 0.30\n    maximum: 0.35\n  lead_len:\n    minimum: 0.30\n    nominal: 0.40\n    maximum: 0.50\n\n  EP_size_x:\n      minimum: 2.50\n      nominal: 2.65\n      maximum: 2.80\n\n  EP_size_y:\n      minimum: 2.50\n      nominal: 2.65\n      maximum: 2.80\n\n  EP_size_x_overwrite: 2.5\n  EP_size_y_overwrite: 2.5\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-20-1EP_4x4mm_P0.5mm_EP2.6x2.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/doc2535.pdf#page=164'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0\n  body_size_y:\n    nominal: 4\n    tolerance: 0\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.23\n    maximum: 0.30\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.55\n\n  EP_size_x:\n    minimum: 2.45\n    nominal: 2.6\n    maximum: 2.75\n  EP_size_y:\n    minimum: 2.45\n    nominal: 2.6\n    maximum: 2.75\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.15\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-16-1EP_4x4mm_P0.65mm_EP2.7x2.7mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.allegromicro.com/~/media/Files/Datasheets/A4403-Datasheet.ashx'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.85\n    nominal: 4\n    maximum: 4.15\n  body_size_y:\n    minimum: 3.85\n    nominal: 4\n    maximum: 4.15\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    minimum: 0.25\n    maximum: 0.35\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x: 2.7\n  EP_size_y: 2.7\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-16-1EP_4x4mm_P0.65mm_EP2.7x2.7mm_PullBack:\n  device_type: 'QFN'\n  #manufacturer: 'AMS'\n  #part_number: 'mpn'\n  size_source: 'https://ams.com/documents/20143/36005/AS5055A_DS000304_2-00.pdf#page=24'\n  ipc_class: 'qfn_pull_back' #'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0\n  body_size_y:\n    nominal: 4\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n\n  lead_width:\n    minimum: 0.25\n    nominal: 0.3\n    maximum: 0.35\n  body_to_inside_lead_edge:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n  lead_to_edge:\n    minimum: 0\n    maximum: 0.15\n\n  EP_size_x:\n    minimum: 2.6\n    nominal: 2.7\n    maximum: 2.8\n  EP_size_y:\n    minimum: 2.6\n    nominal: 2.7\n    maximum: 2.8\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-16-1EP_5x5mm_P0.8mm_EP2.7x2.7mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.intersil.com/content/dam/Intersil/documents/l16_/l16.5x5.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n  body_size_y:\n    nominal: 5\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n\n  lead_width:\n    minimum: 0.28\n    maximum: 0.40\n  lead_len:\n    minimum: 0.35\n    maximum: 0.75\n\n  EP_size_x:\n    minimum: 2.55\n    nominal: 2.7\n    maximum: 2.85\n  EP_size_y:\n    minimum: 2.55\n    nominal: 2.7\n    maximum: 2.85\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.8\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-20.yaml",
    "content": "QFN-20-1EP_3x3mm_P0.45mm_EP1.6x1.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/atmel-8235-8-bit-avr-microcontroller-attiny20_datasheet.pdf#page=212'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  overall_height:\n    minimum: 0.75\n    nominal: 0.8\n    maximum: 0.85\n\n  lead_width:\n    minimum: 0.17\n    nominal: 0.22\n    maximum: 0.27\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  # For backwards compatibility use 1.6mm even though nominal would be 1.55\n  EP_size_x:\n    minimum: 1.4\n    nominal: 1.55\n    maximum: 1.7\n  EP_size_x_overwrite: 1.6\n  EP_size_y:\n    minimum: 1.4\n    nominal: 1.55\n    maximum: 1.7\n  EP_size_y_overwrite: 1.6\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.45\n  num_pins_x: 5\n  num_pins_y: 5\n  chamfer_edge_pins: 0.15\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-20-1EP_3x3mm_P0.4mm_EP1.65x1.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/3553fc.pdf#page=34'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 3\n    tolerance: 0.1\n  body_size_y:\n    nominal: 3\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.2\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n\n  EP_size_x:\n    nominal: 1.65\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 1.65\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.15\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-20-1EP_3x4mm_P0.5mm_EP1.65x2.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/QFN_20_05-08-1742.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 3\n    tolerance: 0.1\n  body_size_y:\n    nominal: 4\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 1.65\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.65\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-20-1EP_4x4mm_P0.5mm_EP2.5x2.5mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=274'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0\n  body_size_y:\n    nominal: 4\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.6\n    nominal: 2.7\n    maximum: 2.8\n  EP_size_x_overwrite: 2.5\n  EP_size_y:\n    minimum: 2.6\n    nominal: 2.7\n    maximum: 2.8\n  EP_size_y_overwrite: 2.5\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.15\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-20-1EP_4x4mm_P0.5mm_EP2.6x2.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/doc2535.pdf#page=164'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0\n  body_size_y:\n    nominal: 4\n    tolerance: 0\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.23\n    maximum: 0.30\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.55\n\n  EP_size_x:\n    minimum: 2.45\n    nominal: 2.6\n    maximum: 2.75\n  EP_size_y:\n    minimum: 2.45\n    nominal: 2.6\n    maximum: 2.75\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.15\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-20-1EP_4x4mm_P0.5mm_EP2.7x2.7mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.silabs.com/documents/public/data-sheets/Si5351-B.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0\n  body_size_y:\n    nominal: 4\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.2\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 2.65\n    nominal: 2.7\n    maximum: 2.75\n  EP_size_y:\n    minimum: 2.65\n    nominal: 2.7\n    maximum: 2.75\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.15\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-20-1EP_3.5x3.5mm_P0.5mm_EP2x2mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ml/mpqf239/mpqf239.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.35\n    maximum: 3.65\n  body_size_y:\n    minimum: 3.35\n    maximum: 3.65\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2\n  EP_size_y:\n    nominal: 2\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.15\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nMLF-20-1EP_4x4mm_P0.5mm_EP2.6x2.6mm:\n  device_type: 'MLF'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/doc8246.pdf#page=263'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0\n  body_size_y:\n    nominal: 4\n    tolerance: 0\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.23\n    maximum: 0.30\n  lead_len:\n    minimum: 0.35\n    nominal: 0.45\n    maximum: 0.55\n\n  EP_size_x:\n    minimum: 2.45\n    nominal: 2.6\n    maximum: 2.75\n  EP_size_y:\n    minimum: 2.45\n    nominal: 2.6\n    maximum: 2.75\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.15\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-20-1EP_4x5mm_P0.5mm_EP2.65x3.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/QFN_20_05-08-1711.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0.1\n  body_size_y:\n    nominal: 5\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    minimum: 2.55\n    nominal: 2.65\n    maximum: 2.75\n  EP_size_y:\n    minimum: 3.55\n    nominal: 3.65\n    maximum: 3.75\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 3]\n\n  thermal_vias:\n    count: [3, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.55\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-20-1EP_5x5mm_P0.65mm_EP3.35x3.35mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=276'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0\n  body_size_y:\n    nominal: 5\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n\n  lead_width:\n    minimum: 0.25\n    nominal: 0.3\n    maximum: 0.35\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 3.15\n    nominal: 3.25\n    maximum: 3.35\n  # For backwards compatibility use maximum size for EP\n  EP_size_x_overwrite: 3.35\n  EP_size_y:\n    minimum: 3.15\n    nominal: 3.25\n    maximum: 3.35\n  EP_size_y_overwrite: 3.35\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-24.yaml",
    "content": "LFCSP-24-1EP_4x4mm_P0.5mm_EP2.5x2.5mm:\n  device_type: 'LFCSP'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/lfcspcp/cp_24_7.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  library: 'Package_CSP'\n  body_size_x:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.45\n    nominal: 2.5\n    maximum: 2.65\n  EP_size_y:\n    minimum: 2.45\n    nominal: 2.5\n    maximum: 2.65\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n\nQFN-24-1EP_3x3mm_P0.4mm_EP1.75x1.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.invensense.com/wp-content/uploads/2015/02/PS-MPU-9250A-01-v1.1.pdf#page=39'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  overall_height:\n    minimum: 0.95\n    nominal: 1\n    maximum: 1.05\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.25\n    nominal: 0.3\n    maximum: 0.35\n\n  # Choosen for backwards compatibility\n  EP_size_x:\n    minimum: 1.65\n    nominal: 1.7\n    maximum: 1.75\n  EP_size_x_overwrite: 1.75\n  EP_size_y:\n    minimum: 1.49\n    nominal: 1.54\n    maximum: 1.59\n  EP_size_y_overwrite: 1.6\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 6\n  num_pins_y: 6\n  chamfer_edge_pins: 0.12\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-24-1EP_3x4mm_P0.4mm_EP1.65x2.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/QFN_20_05-08-1742.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 3\n    tolerance: 0.1\n  body_size_y:\n    nominal: 4\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.2\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  # Chosen for backwards compatibility\n  EP_size_x:\n    nominal: 1.65\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.65\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 3]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 5\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.12\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-24-1EP_4x4mm_P0.5mm_EP2.15x2.15mm:\n  device_type: 'QFN'\n  size_source: 'https://www.st.com/resource/en/datasheet/led1642gw.pdf#page=34'\n  ipc_class: 'qfn'\n  body_size_x:\n    minimum: 3.85\n    nominal: 4.00\n    maximum: 4.15\n  body_size_y:\n    minimum: 3.85\n    nominal: 4.00\n    maximum: 4.15\n  overall_height:\n    minimum: 0.80\n    nominal: 0.90\n    maximum: 1.00\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.30\n    nominal: 0.40\n    maximum: 0.50\n\n  EP_size_x:\n    minimum: 2.00\n    nominal: 2.15\n    maximum: 2.25\n  EP_size_y:\n    minimum: 2.00\n    nominal: 2.15\n    maximum: 2.25\n  EP_num_paste_pads: [2, 2]\n  \n  thermal_vias:\n    count: [3, 3]\n    drill: 0.3\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n\n\nQFN-24-1EP_4x4mm_P0.5mm_EP2.6x2.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=278'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0\n  body_size_y:\n    nominal: 4\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.2\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  # size choosen for backwards compatibility\n  EP_size_x:\n    minimum: 2.4\n    nominal: 2.5\n    maximum: 2.6\n  EP_size_x_overwrite: 2.6\n  EP_size_y:\n    minimum: 2.4\n    nominal: 2.5\n    maximum: 2.6\n  EP_size_y_overwrite: 2.6\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-24-1EP_4x4mm_P0.5mm_EP2.65x2.65mm:\n  device_type: 'QFN'\n  size_source: 'http://www.cypress.com/file/46236/download'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  body_size_x:\n    nominal: 4\n    tolerance: 0.1\n  body_size_y:\n    nominal: 4\n    tolerance: 0.1\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.07\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x: 2.65\n  EP_size_y: 2.65\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n\nQFN-24-1EP_4x4mm_P0.5mm_EP2.7x2.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://store.invensense.com/datasheets/invensense/MPU-6050_DataSheet_V3%204.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  overall_height:\n    minimum: 0.85\n    nominal: 0.9\n    maximum: 0.95\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    nominal: 0.35\n    maximum: 0.4\n\n  EP_size_x:\n    minimum: 2.65\n    nominal: 2.7\n    maximum: 2.75\n  EP_size_y:\n    minimum: 2.55\n    nominal: 2.6\n    maximum: 2.65\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-24-1EP_4x4mm_P0.5mm_EP2.7x2.7mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.alfarzpp.lv/eng/sc/AS3330.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0.1\n  body_size_y:\n    nominal: 4\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.9\n    tolerance: 0.1\n\n  lead_width:\n    nominal: 0.23\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 2.7\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.7\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-24-1EP_4x4mm_P0.5mm_EP2.8x2.8mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/hmc431.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    maximum: 4.1\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    nominal: 0.4\n\n  EP_size_x:\n    minimum: 2.65\n    maximum: 2.95\n  EP_size_y:\n    minimum: 2.65\n    maximum: 2.95\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  # The datasheet does not give the pitch as a reference dimension. Instead, it only specifies\n  # the range.\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-24-1EP_4x5mm_P0.5mm_EP2.65x3.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/QFN_24_05-08-1696.pdf'\n  #custom_name_format: ''\n  ipc_class: qfn #'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 4.0\n    tolerance: 0.1\n  body_size_y:\n    nominal: 5.0\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 2.65\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 3.65\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 3]\n\n\n  thermal_vias:\n    count: [3, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 5\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #include_suffix_in_3dpath: 'False'\n\nQFN-24-1EP_5x5mm_P0.65mm_EP3.2x3.2mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/(UH24)%20QFN%2005-08-1747%20Rev%20A.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0.1\n  body_size_y:\n    nominal: 5\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.3\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.55\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 3.2\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 3.2\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    #EP_paste_coverage: 0.75\n    grid: [1.1, 1.1]\n    # bottom_pad_size:\n    paste_avoid_via: True\n\n  pitch: 0.65\n  num_pins_x: 6\n  num_pins_y: 6\n  chamfer_edge_pins: 0.15\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-24-1EP_5x5mm_P0.65mm_EP3.4x3.4mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.thatcorp.com/datashts/THAT_5173_Datasheet.pdf#page=17'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0.1\n  body_size_y:\n    nominal: 5\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.9\n    tolerance: 0.05\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.05\n\n  EP_size_x:\n    nominal: 3.4\n    tolerance: 0.05\n  EP_size_y:\n    nominal: 3.4\n    tolerance: 0.05\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-24-1EP_5x5mm_P0.65mm_EP3.6x3.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.nxp.com/docs/en/package-information/98ASA00734D.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0\n  body_size_y:\n    nominal: 5\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    maximum: 1\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 3.45\n    maximum: 3.75\n  EP_size_y:\n    minimum: 3.45\n    maximum: 3.75\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    #EP_paste_coverage: 0.75\n    grid: [0.85, 0.85]\n    # bottom_pad_size:\n    paste_avoid_via: True\n\n  pitch: 0.65\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-28.yaml",
    "content": "QFN-28-1EP_3x6mm_P0.5mm_EP1.7x4.75mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/05081926_0_UDE28.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 3\n    tolerance: 0.1\n  body_size_y:\n    nominal: 6\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 1.7\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 4.75\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 4]\n\n  thermal_vias:\n    count: [2, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 10\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-28-1EP_4x4mm_P0.4mm_EP2.3x2.3mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.issi.com/WW/pdf/31FL3731.pdf#page=21'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.95\n    nominal: 4\n    maximum: 4.05\n  body_size_y:\n    minimum: 3.95\n    nominal: 4\n    maximum: 4.05\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.15\n    nominal: 2.3\n    maximum: 2.4\n  EP_size_y:\n    minimum: 2.15\n    nominal: 2.3\n    maximum: 2.4\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    # grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 7\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-28-1EP_4x4mm_P0.4mm_EP2.4x2.4mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=280'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0\n  body_size_y:\n    nominal: 4\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.17\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.5\n    nominal: 2.6\n    maximum: 2.7\n  EP_size_x_overwrite: 2.4\n  EP_size_y:\n    minimum: 2.5\n    nominal: 2.6\n    maximum: 2.7\n  EP_size_y_overwrite: 2.4\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    # grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 7\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-28-1EP_4x4mm_P0.4mm_EP2.6x2.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'package code T2844-1; https://pdfserv.maximintegrated.com/package_dwgs/21-0139.PDF'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    nominal: 4\n    maximum: 4.1\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.5\n    nominal: 2.6\n    maximum: 2.7\n  EP_size_y:\n    minimum: 2.5\n    nominal: 2.6\n    maximum: 2.7\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    # grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 7\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-28-1EP_4x4mm_P0.45mm_EP2.4x2.4mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/8008S.pdf#page=16'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.95\n    nominal: 4\n    maximum: 4.05\n  body_size_y:\n    minimum: 3.95\n    nominal: 4\n    maximum: 4.05\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n\n  lead_width:\n    minimum: 0.17\n    nominal: 0.22\n    maximum: 0.27\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 2.35\n    nominal: 2.4\n    maximum: 2.45\n  EP_size_y:\n    minimum: 2.35\n    nominal: 2.4\n    maximum: 2.45\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    # grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.45\n  num_pins_x: 7\n  num_pins_y: 7\n  chamfer_edge_pins: 0.1\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-28_4x4mm_P0.5mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.st.com/resource/en/datasheet/stm32f031k6.pdf#page=90'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.9\n    nominal: 4.0\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    nominal: 4.0\n    maximum: 4.1\n  overall_height:\n    minimum: 0.5\n    nominal: 0.55\n    maximum: 0.6\n  lead_width:\n    minimum: 0.17\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  pitch: 0.5\n  num_pins_x: 7\n  num_pins_y: 7\n  edge_heel_reduction: 0.12\n  chamfer_edge_pins: 0.16\n\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-28-1EP_4x5mm_P0.5mm_EP2.65x3.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/technical-documentation/data-sheets/3555fe.pdf#page=32'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0.1\n  body_size_y:\n    nominal: 5\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 2.65\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 3.65\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 3]\n\n  thermal_vias:\n    count: [3, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    # grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-28-1EP_5x5mm_P0.5mm_EP3.35x3.35mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=283'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0\n  body_size_y:\n    nominal: 5\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.35\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 3.15\n    nominal: 3.25\n    maximum: 3.35\n  EP_size_x_overwrite: 3.35\n  EP_size_y:\n    minimum: 3.15\n    nominal: 3.25\n    maximum: 3.35\n  EP_size_y_overwrite: 3.35\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 7\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-28-1EP_5x6mm_P0.5mm_EP3.65x4.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/05081932_0_UHE28.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0.1\n  body_size_y:\n    nominal: 6\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 3.65\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 4.65\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 4]\n\n  thermal_vias:\n    count: [3, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-28-1EP_6x6mm_P0.65mm_EP4.25x4.25mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=289'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 6\n    tolerance: 0\n  body_size_y:\n    nominal: 6\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n\n  lead_width:\n    minimum: 0.23\n    maximum: 0.35\n  lead_len:\n    minimum: 0.5\n    maximum: 0.7\n\n  EP_size_x:\n    minimum: 3.65\n    nominal: 3.7\n    maximum: 4.2\n  EP_size_x_overwrite: 4.25\n  EP_size_y:\n    minimum: 3.65\n    nominal: 3.7\n    maximum: 4.2\n  EP_size_y_overwrite: 4.25\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [0.95, 0.95]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 7\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-28-1EP_6x6mm_P0.65mm_EP4.8x4.8mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.semtech.com/uploads/documents/sx1272.pdf#page=125'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 5.9\n    nominal: 6\n    maximum: 6.1\n  body_size_y:\n    minimum: 5.9\n    nominal: 6\n    maximum: 6.1\n  overall_height:\n    minimum: 0.8\n    maximum: 1\n  lead_width:\n    minimum: 0.25\n    nominal: 0.3\n    maximum: 0.35\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 4.65\n    nominal: 4.8\n    maximum: 4.9\n  EP_size_y:\n    minimum: 4.65\n    nominal: 4.8\n    maximum: 4.9\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [0.95, 0.95]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 7\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-3x.yaml",
    "content": "QFN-32-1EP_4x4mm_P0.4mm_EP2.65x2.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.renesas.com/eu/en/package-image/pdf/outdrawing/l32.4x4a.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0.05\n  body_size_y:\n    nominal: 4\n    tolerance: 0.05\n  overall_height:\n    nominal: 0.9\n    tolerance: 0.1\n\n  lead_width:\n    nominal: 0.2\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.05\n\n  EP_size_x:\n    nominal: 2.65\n    tolerance: 0.05\n  EP_size_y:\n    nominal: 2.65\n    tolerance: 0.05\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    #EP_paste_coverage: 0.75\n    grid: [0.85, 0.85]\n    # bottom_pad_size:\n    paste_avoid_via: True\n\n  pitch: 0.4\n  num_pins_x: 8\n  num_pins_y: 8\n  chamfer_edge_pins: 0.1\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-32-1EP_4x4mm_P0.4mm_EP2.9x2.9mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/atmel-8153-8-and-16-bit-avr-microcontroller-xmega-e-atxmega8e5-atxmega16e5-atxmega32e5_datasheet.pdf#page=70'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0\n  body_size_y:\n    nominal: 4\n    tolerance: 0\n  overall_height:\n    minimum: 0.5\n    nominal: 0.55\n    maximum: 0.6\n\n  lead_width:\n    minimum: 0.15\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    maximum: 0.4\n\n  EP_size_x:\n    minimum: 2.7\n    nominal: 2.8\n    maximum: 2.9\n  EP_size_x_overwrite: 2.9\n  EP_size_y:\n    minimum: 2.7\n    nominal: 2.8\n    maximum: 2.9\n  EP_size_y_overwrite: 2.9\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-32-1EP_5x5mm_P0.5mm_EP3.1x3.1mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/8008S.pdf#page=20'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0.1\n  body_size_y:\n    nominal: 5\n    tolerance: 0.1\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.95\n    nominal: 3.1\n    maximum: 3.25\n  EP_size_y:\n    minimum: 2.95\n    nominal: 3.1\n    maximum: 3.25\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-32-1EP_5x5mm_P0.5mm_EP3.3x3.3mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/00002164B.pdf#page=68'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 4.9\n    nominal: 5\n    maximum: 5.1\n  body_size_y:\n    minimum: 4.9\n    nominal: 5\n    maximum: 5.1\n  overall_height:\n    minimum: 0.7\n    nominal: 0.85\n    maximum: 1\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 3.2\n    nominal: 3.3\n    maximum: 3.4\n  EP_size_y:\n    minimum: 3.2\n    nominal: 3.3\n    maximum: 3.4\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-32-1EP_5x5mm_P0.5mm_EP3.45x3.45mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/QFN_32_05-08-1693.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0.1\n  body_size_y:\n    nominal: 5\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 3.45\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 3.45\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-32-1EP_5x5mm_P0.5mm_EP3.6x3.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://infocenter.nordicsemi.com/pdf/nRF52810_PS_v1.1.pdf#page=468'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0\n  body_size_y:\n    nominal: 5\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.2\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 3.4\n    nominal: 3.5\n    maximum: 3.6\n  EP_size_x_overwrite: 3.6\n  EP_size_y:\n    minimum: 3.4\n    nominal: 3.5\n    maximum: 3.6\n  EP_size_y_overwrite: 3.6\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-32-1EP_5x5mm_P0.5mm_EP3.65x3.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.exar.com/ds/mxl7704.pdf#page=35'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0\n  body_size_y:\n    nominal: 5\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.23\n    maximum: 0.28\n  lead_len:\n    minimum: 0.30\n    nominal: 0.35\n    maximum: 0.40\n\n  EP_size_x:\n    minimum: 3.55\n    nominal: 3.65\n    maximum: 3.75\n  EP_size_y:\n    minimum: 3.55\n    nominal: 3.65\n    maximum: 3.75\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-32-1EP_5x5mm_P0.5mm_EP3.7x3.7mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.espressif.com/sites/default/files/documentation/0a-esp8285_datasheet_en.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 4.95\n    nominal: 5.00\n    maximum: 5.05\n  body_size_y:\n    minimum: 4.95\n    nominal: 5.00\n    maximum: 5.05\n  overall_height:\n    minimum: 0.80\n    nominal: 0.85\n    maximum: 0.90\n  lead_width:\n    minimum: 0.20\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.35\n    nominal: 0.40\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 3.65\n    nominal: 3.70\n    maximum: 3.75\n  EP_size_y:\n    minimum: 3.65\n    nominal: 3.70\n    maximum: 3.75\n    \n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-32-1EP_7x7mm_P0.65mm_EP4.65x4.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8209-8-bit%20AVR%20ATmega16M1-32M1-64M1_Datasheet.pdf#page=426'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 7\n    tolerance: 0\n  body_size_y:\n    nominal: 7\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.25\n    nominal: 0.3\n    maximum: 0.37\n  lead_len:\n    minimum: 0.5\n    nominal: 0.6\n    maximum: 0.7\n\n  EP_size_x:\n    minimum: 4.4\n    nominal: 4.5\n    maximum: 4.6\n  EP_size_x_overwrite: 4.65\n  EP_size_y:\n    minimum: 4.4\n    nominal: 4.5\n    maximum: 4.6\n  EP_size_y_overwrite: 4.65\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1.05, 1.05]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-32-1EP_7x7mm_P0.65mm_EP4.7x4.7mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.nxp.com/docs/en/data-sheet/LPC111X.pdf#page=108'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 6.9\n    nominal: 7\n    maximum: 7.1\n  body_size_y:\n    minimum: 6.9\n    nominal: 7\n    maximum: 7.1\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 1\n\n  lead_width:\n    minimum: 0.23\n    nominal: 0.28\n    maximum: 0.35\n  lead_len:\n    minimum: 0.45\n    nominal: 0.6\n    maximum: 0.75\n\n  EP_size_x:\n    minimum: 4.55\n    nominal: 4.7\n    maximum: 4.85\n  EP_size_y:\n    minimum: 4.55\n    nominal: 4.7\n    maximum: 4.85\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1.05, 1.05]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-32-1EP_7x7mm_P0.65mm_EP5.4x5.4mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.thatcorp.com/datashts/THAT_5171_Datasheet.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 6.9\n    maximum: 7.1\n  body_size_y:\n    minimum: 6.9\n    maximum: 7.1\n  overall_height:\n    minimum: 0.85\n    maximum: 0.95\n\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.35\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 5.35\n    maximum: 5.45\n  EP_size_y:\n    minimum: 5.35\n    maximum: 5.45\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    #EP_paste_coverage: 0.7\n    grid: [1.4, 1.4]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-36-1EP_5x6mm_P0.5mm_EP3.6x4.1mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.trinamic.com/fileadmin/assets/Products/ICs_Documents/TMC2100_datasheet_Rev1.08.pdf#page=43'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 4.9\n    nominal: 5\n    maximum: 5.1\n  body_size_y:\n    minimum: 5.9\n    nominal: 6\n    maximum: 6.1\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.2\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 3.5\n    nominal: 3.6\n    maximum: 3.7\n  EP_size_y:\n    minimum: 4.0\n    nominal: 4.1\n    maximum: 4.2\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [3, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 10\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-36-1EP_5x6mm_P0.5mm_EP3.6x4.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/(UHE36)%20QFN%2005-08-1876%20Rev%20%C3%98.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0.1\n  body_size_y:\n    nominal: 6\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 3.6\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 4.6\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 4]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [3, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 10\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-36-1EP_6x6mm_P0.5mm_EP3.7x3.7mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/36L_QFN_6x6_with_3_7x3_7_EP_Punch_Dimpled_4E_C04-0241A.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 6\n    tolerance: 0\n  body_size_y:\n    nominal: 6\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.2\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 3.6\n    nominal: 3.7\n    maximum: 3.8\n  EP_size_y:\n    minimum: 3.6\n    nominal: 3.7\n    maximum: 3.8\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 9\n  num_pins_y: 9\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-36-1EP_6x6mm_P0.5mm_EP4.1x4.1mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'www.st.com/resource/en/datasheet/stm32f101t6.pdf#page=72'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 5.875\n    nominal: 6\n    maximum: 6.125\n  body_size_y:\n    minimum: 5.875\n    nominal: 6\n    maximum: 6.125\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.23\n    maximum: 0.3\n  lead_len:\n    minimum: 0.35\n    nominal: 0.55\n    maximum: 0.75\n\n  EP_size_x:\n    minimum: 1.75\n    nominal: 3.7\n    maximum: 4.25\n  EP_size_x_overwrite: 4.1\n  EP_size_y:\n    minimum: 1.75\n    nominal: 3.7\n    maximum: 4.25\n  EP_size_y_overwrite: 4.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 9\n  num_pins_y: 9\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-38-1EP_4x6mm_P0.4mm_EP2.65x4.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/QFN_38_05-08-1750.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n    tolerance: 0.1\n  body_size_y:\n    nominal: 6\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.2\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 2.65\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 4.65\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 4]\n\n  thermal_vias:\n    count: [2, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 7\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-38-1EP_5x7mm_P0.5mm_EP3.15x5.15mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/QFN_38_05-08-1701.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0.1\n  body_size_y:\n    nominal: 7\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 3.15\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 5.15\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 5]\n  # heel_reduction: 0.05\n\n  thermal_vias:\n    count: [3, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 4]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 7\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-4x.yaml",
    "content": "QFN-40-1EP_5x5mm_P0.4mm_EP3.6x3.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=297'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0\n  body_size_y:\n    nominal: 5\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.17\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 3.6\n    tolerance: 0\n  EP_size_y:\n    nominal: 3.6\n    tolerance: 0\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.1 #deprecated\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 10\n  num_pins_y: 10\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-40-1EP_5x5mm_P0.4mm_EP3.8x3.8mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.issi.com/WW/pdf/31FL3736.pdf#page=28'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 4.9\n    nominal: 5\n    maximum: 5.1\n  body_size_y:\n    minimum: 4.9\n    nominal: 5\n    maximum: 5.1\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 3.15\n    maximum: 3.8\n  EP_size_x_overwrite: 3.8\n  EP_size_y:\n    minimum: 3.15\n    maximum: 3.8\n  EP_size_y_overwrite: 3.8\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.1 #deprecated\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 10\n  num_pins_y: 10\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-40-1EP_6x6mm_P0.5mm_EP4.6x4.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=295'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 6\n    tolerance: 0\n  body_size_y:\n    nominal: 6\n    tolerance: 0\n  lead_width:\n    minimum: 0.18\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 4.5\n    nominal: 4.65\n    maximum: 4.8\n  EP_size_x_overwrite: 4.6\n  EP_size_y:\n    minimum: 4.5\n    nominal: 4.65\n    maximum: 4.8\n  EP_size_y_overwrite: 4.6\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  # heel_reduction: 0.1 #deprecated\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 10\n  num_pins_y: 10\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-42-1EP_5x6mm_P0.4mm_EP3.7x4.7mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/05081875_0_UHE42.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0.1\n  body_size_y:\n    nominal: 6\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 3.7\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 4.7\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 4]\n  # heel_reduction: 0.05 #deprecated\n\n  thermal_vias:\n    count: [4, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 9\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-44-1EP_7x7mm_P0.5mm_EP5.2x5.2mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/2512S.pdf#page=17'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 6.9\n    nominal: 7\n    maximum: 7.1\n  body_size_y:\n    minimum: 6.9\n    nominal: 7\n    maximum: 7.1\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.23\n    maximum: 0.3\n  lead_len:\n    minimum: 0.59\n    nominal: 0.64\n    maximum: 0.69\n\n  EP_size_x:\n    minimum: 5.0\n    nominal: 5.2\n    maximum: 5.4\n  EP_size_y:\n    minimum: 5.0\n    nominal: 5.2\n    maximum: 5.4\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  # heel_reduction: 0.05 #deprecated\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 11\n  num_pins_y: 11\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-44-1EP_7x7mm_P0.5mm_EP5.15x5.15mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/QFN_44_05-08-1763.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 7\n    tolerance: 0.1\n  body_size_y:\n    nominal: 7\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 5.15\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 5.15\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  # heel_reduction: 0.05 #deprecated\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 11\n  num_pins_y: 11\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-44-1EP_8x8mm_P0.65mm_EP6.45x6.45mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/39935c.pdf#page=152'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 8\n    tolerance: 0\n  body_size_y:\n    nominal: 8\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n\n  lead_width:\n    minimum: 0.25\n    nominal: 0.3\n    maximum: 0.38\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 6.3\n    nominal: 6.45\n    maximum: 6.8\n  EP_size_y:\n    minimum: 6.3\n    nominal: 6.45\n    maximum: 6.8\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [5, 5]\n  # heel_reduction: 0.05 #deprecated\n\n  thermal_vias:\n    count: [6, 6]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 11\n  num_pins_y: 11\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-48-1EP_5x5mm_P0.35mm_EP3.7x3.7mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf#page=47'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 4.95\n    nominal: 5\n    maximum: 5.05\n  body_size_y:\n    minimum: 4.95\n    nominal: 5\n    maximum: 5.05\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.13\n    nominal: 0.18\n    maximum: 0.23\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 3.65\n    nominal: 3.7\n    maximum: 3.75\n  EP_size_y:\n    minimum: 3.65\n    nominal: 3.7\n    maximum: 3.75\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.1 #deprecated\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.35\n  num_pins_x: 10\n  num_pins_y: 14\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-48-1EP_6x6mm_P0.4mm_EP4.2x4.2mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://static.dev.sifive.com/SiFive-FE310-G000-datasheet-v1p5.pdf#page=20'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 6\n    tolerance: 0.1\n  body_size_y:\n    nominal: 6\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.85\n    tolerance: 0.08\n\n  lead_width:\n    nominal: 0.2\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.05\n\n  EP_size_x:\n    nominal: 4.2\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 4.2\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.1 #deprecated\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.6\n    grid: [1.05, 1.05]\n    # bottom_pad_size:\n    paste_avoid_via: True\n\n  pitch: 0.4\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-48-1EP_6x6mm_P0.5mm_EP4.3x4.3mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf#page=38'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 5.95\n    nominal: 6\n    maximum: 6.05\n  body_size_y:\n    minimum: 5.95\n    nominal: 6\n    maximum: 6.05\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 4.25\n    nominal: 4.3\n    maximum: 4.35\n  EP_size_y:\n    minimum: 4.25\n    nominal: 4.3\n    maximum: 4.35\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.1 #deprecated\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    # EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-48-1EP_6x6mm_P0.4mm_EP4.6x4.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.3.pdf#page=67'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 6\n    tolerance: 0\n  body_size_y:\n    nominal: 6\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 4.5\n    nominal: 4.6\n    maximum: 4.7\n  EP_size_y:\n    minimum: 4.5\n    nominal: 4.6\n    maximum: 4.7\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.05 #deprecated\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.6\n    grid: [1.2, 1.2]\n    # bottom_pad_size:\n    paste_avoid_via: True\n\n  pitch: 0.4\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-48-1EP_6x6mm_P0.4mm_EP4.66x4.66mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.onsemi.com/pub/Collateral/485BA.PDF'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 6\n    tolerance: 0\n  body_size_y:\n    nominal: 6\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    maximum: 1\n\n  lead_width:\n    minimum: 0.15\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 4.4\n    maximum: 4.6\n  EP_size_x_overwrite: 4.66\n  EP_size_y:\n    minimum: 4.4\n    maximum: 4.6\n  EP_size_y_overwrite: 4.66\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.05 #deprecated\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_paste_coverage: 0.6\n    grid: [1.2, 1.2]\n    # bottom_pad_size:\n    paste_avoid_via: True\n\n  pitch: 0.4\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-48-1EP_7x7mm_P0.5mm_EP5.30x5.30mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.trinamic.com/fileadmin/assets/Products/ICs_Documents/TMC2041_datasheet.pdf#page=62'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 7\n    tolerance: 0\n  body_size_y:\n    nominal: 7\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.2\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 5.2\n    nominal: 5.3\n    maximum: 5.4\n  EP_size_y:\n    minimum: 5.2\n    nominal: 5.3\n    maximum: 5.4\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  # heel_reduction: 0.05 #deprecated\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-48-1EP_7x7mm_P0.5mm_EP5.45x5.45mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.thatcorp.com/datashts/THAT_626x_Datasheet.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 6.9\n    maximum: 7.1\n  body_size_y:\n    minimum: 6.9\n    maximum: 7.1\n  overall_height:\n    minimum: 0.8\n    maximum: 1\n\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.35\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 5.31\n    maximum: 5.6\n  EP_size_x_overwrite: 5.45\n  EP_size_y:\n    minimum: 5.31\n    maximum: 5.6\n  EP_size_y_overwrite: 5.45\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  # heel_reduction: 0.05 #deprecated\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-48-1EP_7x7mm_P0.5mm_EP5.6x5.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.st.com/resource/en/datasheet/stm32f042k6.pdf#page=94'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 6.9\n    nominal: 7\n    maximum: 7.1\n  body_size_y:\n    minimum: 6.9\n    nominal: 7\n    maximum: 7.1\n  overall_height:\n    minimum: 0.5\n    nominal: 0.55\n    maximum: 0.6\n\n  lead_width:\n    minimum: 0.2\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 5.5\n    nominal: 5.6\n    maximum: 5.7\n  EP_size_y:\n    minimum: 5.5\n    nominal: 5.6\n    maximum: 5.7\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  # heel_reduction: 0.05 #deprecated\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-48-1EP_7x7mm_P0.5mm_EP5.15x5.15mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/QFN_48_05-08-1704.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 7\n    tolerance: 0.1\n  body_size_y:\n    nominal: 7\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 5.15\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 5.15\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  # heel_reduction: 0.05 #deprecated\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-48-1EP_8x8mm_P0.5mm_EP6.2x6.2mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232H.pdf#page=49'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 8\n    tolerance: 0\n  body_size_y:\n    nominal: 8\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.2\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.5\n    nominal: 0.55\n    maximum: 0.6\n\n  EP_size_x:\n    minimum: 6.15\n    nominal: 6.2\n    maximum: 6.25\n  EP_size_y:\n    minimum: 6.15\n    nominal: 6.2\n    maximum: 6.25\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [5, 5]\n  # heel_reduction: 0.05 #deprecated\n\n  thermal_vias:\n    count: [6, 6]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-5x.yaml",
    "content": "QFN-52-1EP_7x8mm_P0.5mm_EP5.41x6.45mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/QFN_52_05-08-1729.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 7\n    tolerance: 0.1\n  body_size_y:\n    nominal: 8\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 5.41\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 6.45\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 5]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 6]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 14\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-56-1EP_7x7mm_P0.4mm_EP5.6x5.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.cypress.com/file/416486/download#page=40'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 7\n    tolerance: 0.1\n  body_size_y:\n    nominal: 7\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.55\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.2\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 5.6\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 5.6\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 14\n  num_pins_y: 14\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-56-1EP_8x8mm_P0.5mm_EP4.3x4.3mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/00002142A.pdf#page=40'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 7.85\n    nominal: 8.00\n    maximum: 8.15\n  body_size_y:\n    minimum: 7.85\n    nominal: 8.00\n    maximum: 8.15\n  overall_height:\n    minimum: 0.70\n    nominal: 0.85\n    maximum: 1.00\n\n  lead_width:\n    minimum: 0.15 #according to Note 2 on page 40 (table min. value is 0.18 mm)\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.30\n    nominal: 0.40\n    maximum: 0.50\n\n  EP_size_x:\n    minimum: 4.20\n    nominal: 4.30\n    maximum: 4.40\n  EP_size_y:\n    minimum: 4.20\n    nominal: 4.30\n    maximum: 4.40\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 14\n  num_pins_y: 14\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-56-1EP_8x8mm_P0.5mm_EP4.5x5.2mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/an/scea032/scea032.pdf#page=4'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 7.85\n    maximum: 8.15\n  body_size_y:\n    minimum: 7.85\n    maximum: 8.15\n  overall_height:\n    minimum: 0.8\n    maximum: 0.9\n\n  lead_width:\n    nominal: 0.23\n    tolerance: [-0.05, 0.07]\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 4.35\n    maximum: 4.65\n  EP_size_y:\n    minimum: 5.05\n    maximum: 5.35\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 14\n  num_pins_y: 14\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-56-1EP_8x8mm_P0.5mm_EP5.6x5.6mm:\n  # also known as Texas RTQ (S-PVQFN-N56)\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/tlc5957.pdf#page=23'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 7.85\n    maximum: 8.15\n  body_size_y:\n    minimum: 7.85\n    maximum: 8.15\n  overall_height:\n    minimum: 0.8\n    maximum: 1\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.30\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 5.6\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 5.6\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 14\n  num_pins_y: 14\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-56-1EP_8x8mm_P0.5mm_EP5.9x5.9mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/00001734B.pdf#page=50'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 7.85\n    nominal: 8.00\n    maximum: 8.15\n  body_size_y:\n    minimum: 7.85\n    nominal: 8.00\n    maximum: 8.15\n  overall_height:\n    minimum: 0.70\n    nominal: 0.85\n    maximum: 1.00\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 5.9\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 5.9\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 14\n  num_pins_y: 14\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-64_9x9.yaml",
    "content": "QFN-64-1EP_9x9mm_P0.5mm_EP3.8x3.8xmm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://datasheet.lcsc.com/szlcsc/Realtek-Semicon-RTL8211EG-VB-CG_C69264.pdf#page=77'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x: 9.0\n  body_size_y: 9.0\n  lead_width: 0.18 .. 0.25 .. 0.30\n  lead_len: 0.30 .. 0.40 .. 0.50\n\n  EP_size_x: 3.55 .. 3.80 .. 4.05\n  EP_size_y: 3.55 .. 3.80 .. 4.05\n\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    # EP_paste_coverage: 0.65\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-64-1EP_9x9mm_P0.5mm_EP4.7x4.7mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/60001477A.pdf (page 1083)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  #body_size_x_min: 8.9\n  body_size_x: 9.0\n  #body_size_x_max: 9.1\n  #body_size_y_min: 8.9\n  body_size_y: 9.0\n  #body_size_y_max: 9.1\n  lead_width_min: 0.15\n  lead_width_max: 0.25\n  lead_len_min: 0.3\n  lead_len_max: 0.55\n\n  EP_size_x_min: 4.6\n  EP_size_x: 4.7\n  EP_size_x_max: 4.8\n  EP_size_y_min: 4.6\n  EP_size_y: 4.7\n  EP_size_y_max: 4.8\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    # EP_paste_coverage: 0.65\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-64-1EP_9x9mm_P0.5mm_EP5.4x5.4mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/70593d.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  #body_size_x_min: 8.9\n  body_size_x: 9.0\n  #body_size_x_max: 9.1\n  #body_size_y_min: 8.9\n  body_size_y: 9.0\n  #body_size_y_max: 9.1\n  lead_width_min: 0.2\n  lead_width_max: 0.3\n  lead_len_min: 0.3\n  lead_len_max: 0.5\n\n  EP_size_x_min: 5.3\n  EP_size_x: 5.4\n  EP_size_x_max: 5.5\n  EP_size_y_min: 5.3\n  EP_size_y: 5.4\n  EP_size_y_max: 5.5\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    # EP_paste_coverage: 0.65\n    #grid: [0.98, 0.98]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-64-1EP_9x9mm_P0.5mm_EP6x6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/tusb8041.pdf#page=42'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x_min: 8.9\n  body_size_x: 9.0\n  body_size_x_max: 9.1\n  body_size_y_min: 8.9\n  body_size_y: 9.0\n  body_size_y_max: 9.1\n  lead_width_min: 0.18\n  lead_width_max: 0.3\n  lead_len_min: 0.3\n  lead_len_max: 0.5\n\n  EP_size_x_min: 5.95\n  EP_size_x: 6\n  EP_size_x_max: 6.05\n  EP_size_y_min: 5.95\n  EP_size_y: 6\n  EP_size_y_max: 6.05\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    # EP_paste_coverage: 0.65\n    # grid: [0.8, 0.8]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-64-1EP_9x9mm_P0.5mm_EP7.15x7.15mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.analog.com/media/en/technical-documentation/data-sheets/229321fa.pdf#page=27'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 9.0\n    tolerance: 0.1\n  body_size_y:\n    nominal: 9.0\n    tolerance: 0.1\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 7.15\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 7.15\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [5, 5]\n  # heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [6, 6]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    # EP_paste_coverage: 0.65\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-64-1EP_9x9mm_P0.5mm_EP7.3x7.3mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/00002304A.pdf (page 43)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x_min: 8.9\n  body_size_x: 9.0\n  body_size_x_max: 9.1\n  body_size_y_min: 8.9\n  body_size_y: 9.0\n  body_size_y_max: 9.1\n  lead_width_min: 0.18\n  lead_width_max: 0.3\n  lead_len_min: 0.3\n  lead_len_max: 0.5\n\n  EP_size_x_min: 7.2\n  EP_size_x: 7.3\n  EP_size_x_max: 7.4\n  EP_size_y_min: 7.2\n  EP_size_y: 7.3\n  EP_size_y_max: 7.4\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [5, 5]\n  # heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [6, 6]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    # EP_paste_coverage: 0.65\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-64-1EP_9x9mm_P0.5mm_EP7.5x7.5mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/doc7593.pdf (page 432)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  #body_size_x_min: 8.9\n  body_size_x: 9.0\n  #body_size_x_max: 9.1\n  #body_size_y_min: 8.9\n  body_size_y: 9.0\n  #body_size_y_max: 9.1\n  lead_width_min: 0.18\n  lead_width_max: 0.3\n  lead_len_min: 0.3\n  lead_len_max: 0.55\n\n  EP_size_x_min: 7.4\n  EP_size_x: 7.5\n  EP_size_x_max: 7.6\n  EP_size_y_min: 7.4\n  EP_size_y: 7.5\n  EP_size_y_max: 7.6\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [6, 6]\n  # heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [7, 7]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    # EP_paste_coverage: 0.65\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  chamfer_edge_pins: 0.1\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-64-1EP_9x9mm_P0.5mm_EP7.65x7.65mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf (page 415)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x_min: 8.9\n  body_size_x: 9.0\n  body_size_x_max: 9.1\n  body_size_y_min: 8.9\n  body_size_y: 9.0\n  body_size_y_max: 9.1\n  lead_width_min: 0.18\n  lead_width_max: 0.3\n  lead_len_min: 0.35\n  lead_len_max: 0.45\n\n  EP_size_x_min: 7.5\n  EP_size_x: 7.65\n  EP_size_x_max: 7.8\n  EP_size_y_min: 7.5\n  EP_size_y: 7.65\n  EP_size_y_max: 7.8\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [6, 6]\n  # heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [7, 7]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    # EP_paste_coverage: 0.65\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-6x.yaml",
    "content": "QFN-64-1EP_8x8mm_P0.4mm_EP6.5x6.5mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/64L_VQFN_8x8_with%206_5x6_5%20EP_JXX_C04-0437A.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 8\n    tolerance: 0\n  body_size_y:\n    nominal: 8\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 6.4\n    nominal: 6.5\n    maximum: 6.6\n  EP_size_y:\n    minimum: 6.4\n    nominal: 6.5\n    maximum: 6.6\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [5, 5]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [6, 6]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-64-1EP_9x9mm_P0.5mm_EP4.35x4.35mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT2232H.pdf#page=57'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  body_size_x:\n    nominal: 9\n  body_size_y:\n    nominal: 9\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 4.3\n    nominal: 4.35\n    maximum: 4.4\n  EP_size_y:\n    minimum: 4.3\n    nominal: 4.35\n    maximum: 4.4\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nQFN-64-1EP_9x9mm_P0.5mm_EP5.2x5.2mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.silabs.com/documents/public/data-sheets/Si5345-44-42-D-DataSheet.pdf#page=51'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  body_size_x:\n    nominal: 9\n    tolerance: 0\n  body_size_y:\n    nominal: 9\n    tolerance: 0\n  overall_height:\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 5.10\n    nominal: 5.20\n    maximum: 5.30\n  EP_size_y:\n    minimum: 5.10\n    nominal: 5.20\n    maximum: 5.30\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n  \nQFN-64-1EP_9x9mm_P0.5mm_EP5.45x5.45mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.infineon.com/dgdl/Infineon-MA12040-DS-v01_00-EN.pdf?fileId=5546d46264a8de7e0164b7467a3d617c#page=81'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  body_size_x:\n    nominal: 9\n    tolerance: 0.1\n  body_size_y:\n    nominal: 9\n    tolerance: 0.1\n  overall_height:\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.25\n    maximum: 0.35\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 5.35\n    nominal: 5.45\n    maximum: 5.55\n  EP_size_y:\n    minimum: 5.35\n    nominal: 5.45\n    maximum: 5.55\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n  \nQFN-68-1EP_8x8mm_P0.4mm_EP5.2x5.2mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://cdn.microsemi.com/documents/1bf6886f-5919-4508-a50b-b1dbf3fdf0f4/download/#page=98'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 8\n    tolerance: 0\n  body_size_y:\n    nominal: 8\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 0.9\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 5.1\n    nominal: 5.2\n    maximum: 5.3\n  EP_size_y:\n    minimum: 5.1\n    nominal: 5.2\n    maximum: 5.3\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 17\n  num_pins_y: 17\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-7x.yaml",
    "content": "QFN-72-1EP_10x10mm_P0.5mm_EP6x6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/00001682C.pdf#page=70'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 9.9\n    nominal: 10.0\n    maximum: 10.1\n  body_size_y:\n    minimum: 9.9\n    nominal: 10.0\n    maximum: 10.1\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 5.9\n    nominal: 6.0\n    maximum: 6.1\n  EP_size_y:\n    minimum: 5.9\n    nominal: 6.0\n    maximum: 6.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.1 #deprecated\n\n  thermal_vias:\n    count: [6, 6]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [5, 5]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 18\n  num_pins_y: 18\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-mini-circuits.yaml",
    "content": "QFN-12-1EP_3x3mm_P0.51mm_EP1.45x1.45mm:\n  device_type: 'QFN'\n  size_source: 'https://ww2.minicircuits.com/case_style/DQ1225.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 3\n    tolerance: 0.1016\n  body_size_y:\n    nominal: 3\n    tolerance: 0.1016\n  overall_height:\n    nominal: 0.89\n    tolerance: 0.1016\n\n  lead_width:\n    nominal: 0.23\n    tolerance: 0.1016\n  lead_len:\n    nominal: 0.41\n    tolerance: 0.1016\n\n  EP_size_x:\n    nominal: 1.45\n    tolerance: 0.1016\n  EP_size_y:\n    nominal: 1.45\n    tolerance: 0.1016\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.51\n  num_pins_x: 3\n  num_pins_y: 3\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-onsemi-vct.yml",
    "content": "OnSemi_VCT-28_3.5x3.5mm_P0.4mm:\n  device_type: 'VCT'\n  manufacturer: 'OnSemi'\n  #part_number: 'mpn'\n  size_source: 'http://www.onsemi.com/pub/Collateral/601AE.PDF'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 3.5\n    tolerance: 0.08\n  body_size_y:\n    nominal: 3.5\n    tolerance: 0.08\n  lead_width:\n    minimum: .14\n    maximum: .24\n  lead_len:\n    minimum: .35\n    maximum: .45\n\n  pitch: 0.4\n  num_pins_x: 7\n  num_pins_y: 7\n  chamfer_edge_pins: 0.09\n  edge_heel_reduction: 0.1\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn-other-pincounts.yaml",
    "content": "QFN-76-1EP_9x9mm_P0.4mm_EP3.8x3.8mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.marvell.com/documents/bqcwxsoiqfjkcjdjhkvc/#page=19'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 9\n    tolerance: 0\n  body_size_y:\n    nominal: 9\n    tolerance: 0\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 1\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 3.8\n    tolerance: 0.2\n  EP_size_y:\n    nominal: 3.8\n    tolerance: 0.2\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  #heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    #EP_paste_coverage: 0.6\n    grid: [1.2, 1.2]\n    # bottom_pad_size:\n    paste_avoid_via: True\n\n  pitch: 0.4\n  num_pins_x: 19\n  num_pins_y: 19\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/qfn_texas.yaml",
    "content": "Texas_RUM0016A:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/lmh0074.pdf#page=13'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_RUM00{pincount}A_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    nominal: 4\n    tolerance: 0.1\n  body_size_y:\n    nominal: 4\n    tolerance: 0.1\n  overall_height:\n    maximum: 0.8\n\n  lead_width:\n    nominal: 0.3\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.1\n\n  EP_size_x:\n    nominal: 2.6\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.6\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    EP_paste_coverage: 0.7\n    # grid:\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PVQFN-N16_EP:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/msp430g2001.pdf#page=43'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    maximum: 4.1\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.23\n    maximum: 0.38\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.7\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.7\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    EP_paste_coverage: 0.5\n    # grid:\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\n  pitch: 0.65\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PWQFN-N16_EP:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/drv8801.pdf#page=31 MO-220 variation VGGC'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PWQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 3.85\n    maximum: 4.15\n  body_size_y:\n    minimum: 3.85\n    maximum: 4.15\n  overall_height:\n    minimum: 0.7\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.23\n    maximum: 0.38\n  lead_len:\n    minimum: 0.45\n    maximum: 0.65\n\n  EP_size_x:\n    nominal: 2.1\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.1\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    EP_paste_coverage: 0.7\n    # grid:\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PVQFN-N20_EP2.4x2.4:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/cc1101.pdf#page=101'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 3.85\n    maximum: 4.15\n  body_size_y:\n    minimum: 3.85\n    maximum: 4.15\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.30\n  lead_len:\n    minimum: 0.45\n    maximum: 0.65\n\n  EP_size_x:\n    nominal: 2.4\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.4\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    EP_paste_coverage: 0.5\n    # grid:\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\n  pitch: 0.5\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PVQFN-N20_EP2.7x2.7:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/drv8662.pdf#page=23'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 3.85\n    maximum: 4.15\n  body_size_y:\n    minimum: 3.85\n    maximum: 4.15\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.30\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.7\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.7\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    EP_paste_coverage: 0.7\n    # grid:\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PVQFN-N20_EP3.15x3.15:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'www.ti.com/lit/ds/symlink/tps7a7200.pdf#page=36'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 4.85\n    maximum: 5.15\n  body_size_y:\n    minimum: 4.85\n    maximum: 5.15\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.23\n    maximum: 0.38\n  lead_len:\n    minimum: 0.45\n    maximum: 0.65\n\n  EP_size_x:\n    nominal: 3.15\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 3.15\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    # EP_num_paste_pads: [2, 2]\n    # EP_paste_coverage: 0.7\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PWQFN-N24_EP:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/bq25601.pdf#page=54'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PWQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 3.85\n    maximum: 4.15\n  body_size_y:\n    minimum: 3.85\n    maximum: 4.15\n  overall_height:\n    minimum: 0.7\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.7\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.7\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    EP_paste_coverage: 0.7\n    # grid:\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PVQFN-N24_EP:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/msp430fr5720.pdf#page=108'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    maximum: 4.1\n  overall_height:\n    maximum: 1\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.1\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.1\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.05\n    EP_paste_coverage: 0.7\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    # EP_num_paste_pads: [2, 2]\n    # EP_paste_coverage: 0.5\n    # grid:\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nTexas_R-PWQFN-N28_EP:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/tps51363.pdf#page=29'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_R-PWQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 3.4\n    maximum: 3.6\n  body_size_y:\n    minimum: 4.4\n    maximum: 4.6\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.15\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.1\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 3.1\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.4\n  num_pins_x: 5\n  num_pins_y: 9\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.05\n    EP_paste_coverage: 0.7\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    # EP_num_paste_pads: [2, 2]\n    # EP_paste_coverage: 0.5\n    # grid:\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nTexas_S-PWQFN-N32_EP:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.ti.com/lit/ds/symlink/bq25703a.pdf#page=90'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PWQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 3.85\n    maximum: 4.15\n  body_size_y:\n    minimum: 3.85\n    maximum: 4.15\n  overall_height:\n    minimum: 0.7\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.15\n    maximum: 0.25\n  lead_len:\n    minimum: 0.25\n    maximum: 0.45\n\n  EP_size_x:\n    nominal: 2.8\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.8\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.4\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.05\n    EP_paste_coverage: 0.7\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    # EP_num_paste_pads: [2, 2]\n    # EP_paste_coverage: 0.5\n    # grid:\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nTexas_S-PVQFN-N32_EP:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/msp430f1122.pdf#page=54'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 4.9\n    maximum: 5.1\n  body_size_y:\n    minimum: 4.9\n    maximum: 5.1\n  overall_height:\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 3.45\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 3.45\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [4, 4]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PVQFN-N36_EP:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/slvsba5d/slvsba5d.pdf#page=35'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 5.9\n    maximum: 6.1\n  body_size_y:\n    minimum: 5.9\n    maximum: 6.1\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.45\n    maximum: 0.65\n\n  EP_size_x:\n    nominal: 4.4\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 4.4\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [4, 4]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1.05, 1.05]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\n  pitch: 0.5\n  num_pins_x: 9\n  num_pins_y: 9\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PVQFN-N40_EP2.9x2.9mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/msp430fr5731.pdf#page=111 JEDEC MO-220 variation VJJD-2'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 5.85\n    maximum: 6.15\n  body_size_y:\n    minimum: 5.85\n    maximum: 6.15\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    nominal: 0.23\n    tolerance: [-0.05, 0.07]\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.9\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.9\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [4, 4]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    #grid: [1.05, 1.05]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 10\n  num_pins_y: 10\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PVQFN-N40_EP3.52x2.62mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/drv8308.pdf#page=56 JEDEC MO-220 variation VJJD-2'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 5.85\n    maximum: 6.15\n  body_size_y:\n    minimum: 5.85\n    maximum: 6.15\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    nominal: 0.23\n    tolerance: [-0.05, 0.07]\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 3.52\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.62\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 2]\n\n  thermal_vias:\n    count: [4, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [4, 4]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    #grid: [1.05, 1.05]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 10\n  num_pins_y: 10\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PVQFN-N40_EP4.15x4.15mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/msp430g2755.pdf#page=70 JEDEC MO-220 variation VJJD-2'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 5.85\n    maximum: 6.15\n  body_size_y:\n    minimum: 5.85\n    maximum: 6.15\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    nominal: 0.23\n    tolerance: [-0.05, 0.07]\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 4.15\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 4.15\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [4, 4]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    #EP_paste_coverage: 0.7\n    grid: [1.0, 1.0]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 10\n  num_pins_y: 10\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PVQFN-N40_EP4.6x4.6mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/dac7750.pdf#page=54'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 5.85\n    maximum: 6.15\n  body_size_y:\n    minimum: 5.85\n    maximum: 6.15\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    nominal: 0.23\n    tolerance: [-0.05, 0.07]\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 4.6\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 4.6\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [4, 4]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    #EP_paste_coverage: 0.7\n    grid: [1.15, 1.15]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 10\n  num_pins_y: 10\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PVQFN-N48_EP: #RGZ0048A\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/msp430f5232.pdf#page=111'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 6.9\n    maximum: 7.1\n  body_size_y:\n    minimum: 6.9\n    maximum: 7.1\n  overall_height:\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 5.15\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 5.15\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [4, 4]\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [4, 4]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [1, 1]\n    # bottom_pad_size:\n    # paste_avoid_via: True\n\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_S-PVQFN-N64_EP: #RGC0064B\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/msp430f5217.pdf#page=120'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 8.9\n    maximum: 9.1\n  body_size_y:\n    minimum: 8.9\n    maximum: 9.1\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 4.25\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 4.25\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    grid: [0.8, 0.8]\n    # bottom_pad_size:\n    # paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 16\n  num_pins_y: 16\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTexas_VQFN_RGE0024H:\n  device_type: 'QFN'\n  manufacturer: 'Texas'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/tlc5971.pdf#page=39'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_RGE00{pincount}H_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    maximum: 4.1\n  overall_height:\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.28\n    maximum: 0.48\n\n  EP_size_x:\n    nominal: 2.7\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.7\n    tolerance: 0.1\n  EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.05\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    EP_num_paste_pads: [2, 2]\n    # grid:\n    # bottom_pad_size:\n    paste_avoid_via: False\n\nTexas_VQFN_RGE0024C:\n  device_type: 'QFN'\n  manufacturer: 'Texas'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/pca9548a.pdf#page=37'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_RGE00{pincount}C_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    maximum: 4.1\n  overall_height:\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.1\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.1\n    tolerance: 0.1\n  EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.05\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    EP_num_paste_pads: [2, 2]\n    # grid:\n    # bottom_pad_size:\n    paste_avoid_via: False\nTexas_RGV_S-PVQFN-N16_EP2.1x2.1mm:\n  device_type: 'QFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/ina3221.pdf#page=44'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  custom_name_format: 'Texas_RGV_S-PVQFN-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  body_size_x:\n    minimum: 3.85\n    maximum: 4.15\n  body_size_y:\n    minimum: 3.85\n    maximum: 4.15\n  overall_height:\n    minimum: 0.8\n    maximum: 1.0\n\n  lead_width:\n    minimum: 0.23\n    maximum: 0.38\n  lead_len:\n    minimum: 0.45\n    maximum: 0.65\n\n  EP_size_x:\n    nominal: 2.1\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.1\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    EP_paste_coverage: 0.75\n    # grid:\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/special_qfn.yaml",
    "content": "Texas_X2QFN-12_1.6x1.6mm_P0.4mm:\n  device_type: 'X2QFN'\n  manufacturer: 'Texas'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ml/mpqf391c/mpqf391c.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 1.55\n    maximum: 1.65\n  body_size_y:\n    minimum: 1.55\n    maximum: 1.65\n  overall_height:\n    maximum: 0.4\n\n  lead_width:\n    minimum: 0.15\n    maximum: 0.25\n  lead_len_V:\n    minimum: 0.2\n    maximum: 0.4\n  lead_len_H:\n    minimum: 0.4\n    maximum: 0.6\n\n  heel_reduction: 0.075\n\n  pitch: 0.4\n  num_pins_x: 4\n  num_pins_y: 2\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/tqfn.yaml",
    "content": "TQFN-16-1EP_3x3mm_P0.5mm_EP1.23x1.23mm:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0136.PDF (T1633-5), https://pdfserv.maximintegrated.com/land_patterns/90-0032.PDF'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 3\n  body_size_y:\n    nominal: 3\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n  lead_width:\n    minimum: 0.2\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x: 1.23\n  EP_size_y: 1.23\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTQFN-16-1EP_3x3mm_P0.5mm_EP1.6x1.6mm:\n  device_type: 'TQFN'\n  ipc_class: 'qfn'\n  size_source: 'https://www.diodes.com/assets/Datasheets/PI6C5946002.pdf#page=12'\n  body_size_x:\n    minimum: 2.9\n    nominal: 3.0\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3.0\n    maximum: 3.1\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 1.6\n    nominal: 1.8\n    maximum: 1.9\n  EP_size_y:\n    minimum: 1.6\n    nominal: 1.8\n    maximum: 1.9\n  EP_size_x_overwrite: 1.6\n  EP_size_y_overwrite: 1.6\n\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n\nTQFN-16-1EP_5x5mm_P0.8mm_EP2.29x2.29mm:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0140.PDF (T1655-4)'\n  #custom_name_format: 'TQFN-24-1EP_4x4mm_P0.5mm_EP2.8x2.8mm_PullBack{vias:s}'\n  ipc_class: 'qfn' #'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 5.0\n  body_size_y:\n    nominal: 5.0\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.25\n    nominal: 0.3\n    maximum: 0.35\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.19\n    nominal: 2.29\n    maximum: 2.39\n  EP_size_y:\n    minimum: 2.19\n    nominal: 2.29\n    maximum: 2.39\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.8\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #include_suffix_in_3dpath: 'False'\n\nTQFN-16-1EP_5x5mm_P0.8mm_EP3.1x3.1mm:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0140.PDF (T1655-2)'\n  #custom_name_format: 'TQFN-24-1EP_4x4mm_P0.5mm_EP2.8x2.8mm_PullBack{vias:s}'\n  ipc_class: 'qfn' #'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 5.0\n  body_size_y:\n    nominal: 5.0\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.25\n    nominal: 0.3\n    maximum: 0.35\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 3.0\n    nominal: 3.1\n    maximum: 3.2\n  EP_size_y:\n    minimum: 3.0\n    nominal: 3.1\n    maximum: 3.2\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.8\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #include_suffix_in_3dpath: 'False'\n\nTQFN-20-1EP_5x5mm_P0.65mm_EP3.1x3.1mm:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0140.PDF (T2055-3)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n  body_size_y:\n    nominal: 5\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.25\n    nominal: 0.30\n    maximum: 0.35\n  lead_len:\n    minimum: 0.45\n    nominal: 0.55\n    maximum: 0.65\n\n  EP_size_x:\n    minimum: 3.0\n    nominal: 3.1\n    maximum: 3.2\n  EP_size_y:\n    minimum: 3.0\n    nominal: 3.1\n    maximum: 3.2\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTQFN-20-1EP_5x5mm_P0.65mm_EP3.25x3.25mm:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0140.PDF (T2055-5)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n  body_size_y:\n    nominal: 5\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.25\n    nominal: 0.30\n    maximum: 0.35\n\n  # The footprints with EP3.25mm have a specified lead length of 0.4mm\n  # (while the default for 20-pins is 0.55mm). This uses the default lead\n  # length (instead of the actual 0.4mm) for calculating the pad size,\n  # to match the landing pattern recommended by Maxim (90-0010).\n  lead_len:\n    minimum: 0.30\n    nominal: 0.40\n    maximum: 0.50\n\n  EP_size_x:\n    minimum: 3.15\n    nominal: 3.25\n    maximum: 3.35\n  EP_size_y:\n    minimum: 3.15\n    nominal: 3.25\n    maximum: 3.35\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTQFN-24-1EP_4x4mm_P0.5mm_EP2.8x2.8mm_PullBack:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://ams.com/documents/20143/36005/AS1115_DS000206_1-00.pdf'\n  custom_name_format: 'TQFN-24-1EP_4x4mm_P0.5mm_EP2.8x2.8mm_PullBack{vias:s}'\n  ipc_class: 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 4.0\n  body_size_y:\n    nominal: 4.0\n  overall_height:\n    minimum: 0.5\n    nominal: 0.55\n    maximum: 0.65\n\n  lead_to_edge:\n    minimum: 0\n    maximum: 0.15\n  lead_width:\n    minimum: 0.18\n    nominal: 0.25\n    maximum: 0.35\n  body_to_inside_lead_edge:\n    minimum: 0.3\n    nominal: 0.35\n    maximum: 0.4\n\n  EP_size_x:\n    minimum: 2.7\n    nominal: 2.8\n    maximum: 2.9\n  EP_size_y:\n    minimum: 2.7\n    nominal: 2.8\n    maximum: 2.9\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.65\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #include_suffix_in_3dpath: 'False'\n\nTQFN-28-1EP_5x5mm_P0.50mm_EP2.70x2.70mm:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0140.PDF (T2855-4)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n  body_size_y:\n    nominal: 5\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.20\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.45\n    nominal: 0.55\n    maximum: 0.65\n\n  EP_size_x:\n    minimum: 2.60\n    nominal: 2.70\n    maximum: 2.80\n  EP_size_y:\n    minimum: 2.60\n    nominal: 2.70\n    maximum: 2.80\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.50\n  num_pins_x: 7\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTQFN-28-1EP_5x5mm_P0.50mm_EP3.25x3.25mm:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0140.PDF (T2855-3)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n  body_size_y:\n    nominal: 5\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.20\n    nominal: 0.25\n    maximum: 0.30\n  # There are variations of this footprint with a specified lead length\n  # of 0.4mm (while the default for 28-pins is 0.55mm). This uses the\n  # default lead length (instead of 0.4mm) for calculating the pad size,\n  # to match the landing pattern recommended by Maxim for both the 0.4mm\n  # and 0.55mm lead length variations (90-0028).\n  lead_len:\n    minimum: 0.45\n    nominal: 0.55\n    maximum: 0.65\n\n  EP_size_x:\n    minimum: 3.15\n    nominal: 3.25\n    maximum: 3.35\n  EP_size_y:\n    minimum: 3.15\n    nominal: 3.25\n    maximum: 3.35\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.50\n  num_pins_x: 7\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTQFN-32-1EP_5x5mm_P0.50mm_EP2.10x2.10mm:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0140.PDF (T3255-6)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n  body_size_y:\n    nominal: 5\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.20\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.30\n    nominal: 0.40\n    maximum: 0.50\n\n  EP_size_x:\n    minimum: 2.00\n    nominal: 2.10\n    maximum: 2.20\n  EP_size_y:\n    minimum: 2.00\n    nominal: 2.10\n    maximum: 2.20\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.50\n  num_pins_x: 8\n  num_pins_y: 8\n  chamfer_edge_pins: 0.09\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTQFN-32-1EP_5x5mm_P0.50mm_EP3.10x3.10mm:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0140.PDF (T3255-3)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n  body_size_y:\n    nominal: 5\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.20\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.30\n    nominal: 0.40\n    maximum: 0.50\n\n  EP_size_x:\n    minimum: 3.00\n    nominal: 3.10\n    maximum: 3.20\n  EP_size_y:\n    minimum: 3.00\n    nominal: 3.10\n    maximum: 3.20\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.50\n  num_pins_x: 8\n  num_pins_y: 8\n  chamfer_edge_pins: 0.09\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTQFN-32-1EP_5x5mm_P0.50mm_EP3.40x3.40mm:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0140.PDF (T3255-9)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n  body_size_y:\n    nominal: 5\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.20\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.30\n    nominal: 0.40\n    maximum: 0.50\n\n  EP_size_x:\n    minimum: 3.30\n    nominal: 3.40\n    maximum: 3.50\n  EP_size_y:\n    minimum: 3.30\n    nominal: 3.40\n    maximum: 3.50\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.50\n  num_pins_x: 8\n  num_pins_y: 8\n  chamfer_edge_pins: 0.09\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTQFN-40-1EP_5x5mm_P0.40mm_EP3.50x3.50mm:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0140.PDF (T4055-1)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n  body_size_y:\n    nominal: 5\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.20\n    maximum: 0.25\n  lead_len:\n    minimum: 0.30\n    nominal: 0.40\n    maximum: 0.50\n\n  EP_size_x:\n    minimum: 3.40\n    nominal: 3.50\n    maximum: 3.60\n  EP_size_y:\n    minimum: 3.40\n    nominal: 3.50\n    maximum: 3.60\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.40\n  num_pins_x: 10\n  num_pins_y: 10\n  chamfer_edge_pins: 0.12\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nTQFN-48-1EP_7x7mm_P0.5mm_EP5.1x5.1mm:\n  device_type: 'TQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://pdfserv.maximintegrated.com/package_dwgs/21-0144.PDF' #T4877-3\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 6.9\n    nominal: 7\n    maximum: 7.1\n  body_size_y:\n    minimum: 6.9\n    nominal: 7\n    maximum: 7.1\n  overall_height:\n    minimum: 0.7\n    nominal: 0.75\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.20\n    nominal: 0.25\n    maximum: 0.30\n  lead_len:\n    minimum: 0.30\n    nominal: 0.40\n    maximum: 0.50\n\n  EP_size_x:\n    minimum: 4.95\n    nominal: 5.1\n    maximum: 5.25\n  EP_size_y:\n    minimum: 4.95\n    nominal: 5.1\n    maximum: 5.25\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/ufqfpn.yaml",
    "content": "UFQFPN-32-1EP_5x5mm_P0.5mm_EP3.5x3.5mm:\n  device_type: 'UFQFPN'\n  size_source: 'https://www.st.com/resource/en/datasheet/stm32g071k8.pdf'\n  body_size_x:\n    minimum: 4.9\n    nominal: 5\n    maximum: 5.1\n  body_size_y:\n    minimum: 4.9\n    nominal: 5\n    maximum: 5.1\n  overall_height:\n    minimum: 0.5\n    nominal: 0.55\n    maximum: 0.6\n\n  lead_width:\n    minimum: 0.18\n    nominal: 0.23\n    maximum: 0.28\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 3.4\n    nominal: 3.5\n    maximum: 3.6\n  EP_size_y:\n    minimum: 3.4\n    nominal: 3.5\n    maximum: 3.6\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    paste_avoid_via: False\n\n  pitch: 0.50\n  num_pins_x: 8\n  num_pins_y: 8\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/uqfn.yaml",
    "content": "UQFN-10_1.3x1.8mm_P0.4mm:\n  device_type: 'UQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/00001725D.pdf (Page 9)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 1.3\n    tolerance: 0\n  body_size_y:\n    nominal: 1.8\n    tolerance: 0\n  lead_width:\n    minimum: 0.15\n    maximum: 0.25\n  lead_len_V:\n    minimum: 0.35\n    maximum: 0.45\n  lead_len_H:\n    minimum: 0.45\n    maximum: 0.55\n\n  heel_reduction: 0.05 #fnecessary to reach 0.2mm clearance between vertical and horizontal pads\n\n  pitch: 0.4\n  num_pins_x: 3\n  num_pins_y: 2\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nUQFN-10_1.6x2.1mm_P0.5mm:\n  device_type: 'UQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/00001725D.pdf (Page 12)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 1.6\n    tolerance: 0\n  body_size_y:\n    nominal: 2.1\n    tolerance: 0\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len_V:\n    minimum: 0.35\n    maximum: 0.45\n  lead_len_H:\n    minimum: 0.6\n    maximum: 0.7\n\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  pitch: 0.5\n  num_pins_x: 3\n  num_pins_y: 2\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nUQFN-16-1EP_4x4mm_P0.65mm_EP2.6x2.6mm:\n  device_type: 'UQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/16L_UQFN_4x4x0_5mm_JQ_C04257A.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n  body_size_y:\n    nominal: 4\n  overall_height:\n    minimum: 0.45\n    nominal: 0.5\n    maximum: 0.55\n  lead_width:\n    minimum: 0.25\n    maximum: 0.35\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.5\n    maximum: 2.7\n  EP_size_y:\n    minimum: 2.5\n    maximum: 2.7\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nUQFN-20-1EP_3x3mm_P0.4mm_EP1.85x1.85mm:\n  device_type: 'UQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=332'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 3\n  body_size_y:\n    nominal: 3\n  overall_height:\n    minimum: 0.45\n    nominal: 0.5\n    maximum: 0.55\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.20\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 1.65\n    nominal: 1.75\n    maximum: 1.85\n  EP_size_x_overwrite: 1.85\n  EP_size_y:\n    minimum: 1.65\n    nominal: 1.75\n    maximum: 1.85\n  EP_size_y_overwrite: 1.85\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nUQFN-20-1EP_4x4mm_P0.5mm_EP2.8x2.8mm:\n  device_type: 'UQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/40001839B.pdf#page=464'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n  body_size_y:\n    nominal: 4\n  overall_height:\n    minimum: 0.45\n    nominal: 0.5\n    maximum: 0.55\n\n  lead_width:\n    minimum: 0.2\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.6\n    nominal: 2.7\n    maximum: 2.8\n  EP_size_x_overwrite: 2.8\n  EP_size_y:\n    minimum: 2.6\n    nominal: 2.7\n    maximum: 2.8\n  EP_size_y_overwrite: 2.8\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 5\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nUQFN-28-1EP_4x4mm_P0.4mm_EP2.35x2.35mm:\n  device_type: 'UQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=338'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 4\n  body_size_y:\n    nominal: 4\n  overall_height:\n    minimum: 0.45\n    nominal: 0.5\n    maximum: 0.55\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.55\n    nominal: 2.65\n    maximum: 2.75\n  EP_size_x_overwrite: 2.35\n  EP_size_y:\n    minimum: 2.55\n    nominal: 2.65\n    maximum: 2.75\n  EP_size_y_overwrite: 2.35\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 7\n  num_pins_y: 7\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nUQFN-40-1EP_5x5mm_P0.4mm_EP3.8x3.8mm:\n  device_type: 'UQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=345'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n  body_size_y:\n    nominal: 5\n  overall_height:\n    minimum: 0.45\n    nominal: 0.5\n    maximum: 0.55\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 3.6\n    nominal: 3.7\n    maximum: 3.8\n  EP_size_x_overwrite: 3.8\n  EP_size_y:\n    minimum: 3.6\n    nominal: 3.7\n    maximum: 3.8\n  EP_size_y_overwrite: 3.8\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    #EP_paste_coverage: 0.7\n    grid: [1.3, 1.3]\n    # bottom_pad_size:\n    #paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 10\n  num_pins_y: 10\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nUQFN-48-1EP_6x6mm_P0.4mm_EP4.45x4.45mm:\n  device_type: 'UQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BQ.pdf#page=347'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 6\n  body_size_y:\n    nominal: 6\n  overall_height:\n    minimum: 0.45\n    nominal: 0.5\n    maximum: 0.55\n\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 4.45\n    nominal: 4.6\n    maximum: 4.75\n  EP_size_x_overwrite: 4.45\n  EP_size_y:\n    minimum: 4.45\n    nominal: 4.6\n    maximum: 4.75\n  EP_size_y_overwrite: 4.45\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 1\n    paste_rings_outside: 1\n    #EP_paste_coverage: 0.7\n    grid: [1.4, 1.4]\n    # bottom_pad_size:\n    #paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nUQFN-48-1EP_6x6mm_P0.4mm_EP4.62x4.62mm:\n  device_type: 'UQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://github.com/KiCad/kicad-symbols/pull/1189#issuecomment-449506354'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 5.9\n    nominal: 6\n    maximum: 6.1\n  body_size_y:\n    minimum: 5.9\n    nominal: 6\n    maximum: 6.1\n  lead_width:\n    minimum: 0.15\n    nominal: 0.2\n    maximum: 0.25\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x_min: 4.52\n  EP_size_x_max: 4.72\n  EP_size_y_min: 4.52\n  EP_size_y_max: 4.72\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [3, 3]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.6\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: True\n\n  pitch: 0.4\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/vqfn.yaml",
    "content": "VQFN-16-1EP_3x3mm_P0.5mm_EP1.6x1.6mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/cdclvp1102.pdf#page=28'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.9\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    maximum: 3.1\n  overall_height:\n    maximum: 1\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 1.6\n    tolerance: 0.05\n  EP_size_y:\n    nominal: 1.6\n    tolerance: 0.05\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.08\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nVQFN-16-1EP_3x3mm_P0.5mm_EP1.45x1.45mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/sbos354a/sbos354a.pdf, JEDEC MO-220 variant VEED-6'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.9\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    maximum: 3.1\n  overall_height:\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 1.45\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 1.45\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.08\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nVQFN-16-1EP_3x3mm_P0.5mm_EP1.68x1.68mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/tlv62095.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.9\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    maximum: 3.1\n  overall_height:\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 1.68\n    tolerance: 0.07\n  EP_size_y:\n    nominal: 1.68\n    tolerance: 0.07\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.08\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nVQFN-16-1EP_3x3mm_P0.5mm_EP1.8x1.8mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.st.com/resource/en/datasheet/stspin220.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.85\n    nominal: 3\n    maximum: 3.15\n  body_size_y:\n    minimum: 2.85\n    nominal: 3\n    maximum: 3.15\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    nominal: 0.25\n    maximum: 0.3\n  lead_len:\n    minimum: 0.45\n    nominal: 0.5\n    maximum: 0.55\n\n  EP_size_x:\n    minimum: 1.7\n    nominal: 1.8\n    maximum: 1.9\n  EP_size_y:\n    minimum: 1.7\n    nominal: 1.8\n    maximum: 1.9\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  heel_reduction: 0.2 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.08\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nVQFN-20-1EP_3x3mm_P0.4mm_EP1.7x1.7mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/20%20Lead%20VQFN%203x3x0_9mm_1_7EP%20U2B%20C04-21496a.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 3\n  body_size_y:\n    nominal: 3\n  overall_height:\n    minimum: 0.8\n    maximum: 0.9\n  lead_width:\n    minimum: 0.15\n    maximum: 0.25\n  lead_len:\n    minimum: 0.35\n    maximum: 0.45\n\n  EP_size_x: 1.7\n  EP_size_y: 1.7\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 5\n  num_pins_y: 5\n  chamfer_edge_pins: 0.08\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nVQFN-20-1EP_3x3mm_P0.45mm_EP1.55x1.55mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/doc8246.pdf#page=264'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    nominal: 3\n    maximum: 3.1\n  overall_height:\n    minimum: 0.75\n    nominal: 0.8\n    maximum: 0.85\n  lead_width:\n    minimum: 0.17\n    maximum: 0.27\n  lead_len:\n    minimum: 0.35\n    maximum: 0.45\n\n  EP_size_x_min: 1.4\n  EP_size_x: 1.55\n  EP_size_x_max: 1.7\n  EP_size_y_min: 1.4\n  EP_size_y: 1.55\n  EP_size_y_max: 1.7\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.45\n  num_pins_x: 5\n  num_pins_y: 5\n  chamfer_edge_pins: 0.15\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nVQFN-24-1EP_4x4mm_P0.5mm_EP2.45x2.45mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/msp430f1101a.pdf'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    minimum: 3.9\n    nominal: 4.0\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    nominal: 4.0\n    maximum: 4.1\n  overall_height:\n    maximum: 1\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.35\n    nominal: 2.45\n    maximum: 2.55\n  EP_size_y:\n    minimum: 2.35\n    nominal: 2.45\n    maximum: 2.55\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  heel_reduction: 0.1 #for relatively large EP pads (increase clearance)\n  #EP_size_limit_x: 2.7  #for relatively large EP pads (increase clearance)\n  #EP_size_limit_y: 2.7  #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    EP_paste_coverage: 0.55\n    # grid:\n    # bottom_pad_size:\n    # paste_avoid_via: True\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nVQFN-28-1EP_4x4mm_P0.45mm_EP2.4x2.4mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-9505-AT42-QTouch-BSW-AT42QT1060_Datasheet.pdf#page=28'\n  ipc_class: 'qfn'\n  #ipc_density: 'least'\n  body_size_x:\n    minimum: 3.95\n    nominal: 4\n    maximum: 4.05\n  body_size_y:\n    minimum: 3.95\n    nominal: 4\n    maximum: 4.05\n  overall_height:\n    minimum: 0.8\n    nominal: 0.9\n    maximum: 1\n  lead_width:\n    minimum: 0.17\n    nominal: 0.22\n    maximum: 0.27\n  lead_len:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.45\n\n  EP_size_x:\n    minimum: 2.35\n    nominal: 2.4\n    maximum: 2.45\n  EP_size_y:\n    minimum: 2.35\n    nominal: 2.4\n    maximum: 2.45\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3,3]\n    drill: 0.3\n    paste_via_clearance: 0.1\n    paste_avoid_via: False\n    EP_paste_coverage: 0.7\n\n\n  pitch: 0.45\n  num_pins_x: 7\n  num_pins_y: 7\n\nVQFN-28-1EP_4x5mm_P0.5mm_EP2.55x3.55mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/lm5175.pdf#page=40'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 4.9\n    maximum: 5.1\n  overall_height:\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.55\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 3.55\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 3]\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    # EP_paste_coverage: 0.75\n    # grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\n\nVQFN-32-1EP_5x5mm_P0.5mm_EP3.1x3.1mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/devicedoc/atmel-9520-at42-qtouch-bsw-at42qt1110_datasheet.pdf#page=42'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 4.9\n    nominal: 5\n    maximum: 5.1\n  body_size_y:\n    minimum: 4.9\n    nominal: 5\n    maximum: 5.1\n  overall_height:\n    minimum: 0.8\n    nominal: 0.85\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    nominal: 0.23\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    nominal: 0.4\n    maximum: 0.5\n\n  EP_size_x:\n    minimum: 2.95\n    nominal: 3.1\n    maximum: 3.25\n  EP_size_y:\n    minimum: 2.95\n    nominal: 3.1\n    maximum: 3.25\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.33\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    grid: [1.2, 1.2]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nVQFN-32-1EP_5x5mm_P0.5mm_EP3.15x3.15mm:\n  device_type: 'VQFN'\n  size_source: 'https://www.ti.com/lit/ds/slvs589d/slvs589d.pdf#page=33'\n  ipc_class: 'qfn'\n  body_size_x: 5.0 +/- 0.15\n  body_size_y: 5.0 +/- 0.15\n  overall_height:\n    minimum: 0.8\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x: 3.15 +/- 0.1\n  EP_size_y: 3.15 +/- 0.1\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n\nVQFN-32-1EP_5x5mm_P0.5mm_EP3.5x3.5mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT4222H.pdf#page=40'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 5\n    tolerance: 0\n  body_size_y:\n    nominal: 5\n    tolerance: 0\n  overall_height:\n    nominal: 0.85\n    tolerance: 0.05\n  lead_width:\n    nominal: 0.25\n    tolerance: [+0.05, -0.07]\n  lead_len:\n    nominal: 0.4\n    tolerance: 0.05\n\n  EP_size_x:\n    nominal: 3.5\n    tolerance: 0.05\n  EP_size_y:\n    nominal: 3.5\n    tolerance: 0.05\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 8\n  num_pins_y: 8\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nVQFN-46-1EP_5x6mm_P0.4mm_EP2.8x3.8mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/lp5036.pdf#page=59'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x: 4.9 .. 5.1\n  body_size_y: 5.9 .. 6.1\n  overall_height: 1.0\n  lead_width: 0.15 .. 0.25\n  lead_len: 0.25 .. 0.45\n\n  EP_size_x:\n    nominal: 2.8\n    tolerance: 0.05\n  EP_size_y:\n    nominal: 3.8\n    tolerance: 0.05\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 3]\n\n  thermal_vias:\n    count: [3, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.4\n  num_pins_x: 10\n  num_pins_y: 13\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nVQFN-48-1EP_7x7mm_P0.5mm_EP5.15x5.15mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/cc1312r.pdf#page=48'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 6.9\n    #nominal: 7\n    maximum: 7.1\n  body_size_y:\n    minimum: 6.9\n    #nominal: 7\n    maximum: 7.1\n  overall_height:\n    #minimum: 0.8\n    #nominal: 0.85\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    #nominal: 0.24\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    #nominal: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 5.15\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 5.15\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [5, 5]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    #EP_paste_coverage: 0.7\n    #grid: [1.2, 1.2]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nVQFN-48-1EP_7x7mm_P0.5mm_EP4.1x4.1mm:\n  device_type: 'VQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/cc430f5137.pdf#page=128'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 6.85\n    #nominal: 7\n    maximum: 7.15\n  body_size_y:\n    minimum: 6.85\n    #nominal: 7\n    maximum: 7.15\n  overall_height:\n    maximum: 1\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 4.1\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 4.1\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [3, 3]\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [4, 4]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    # EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    #EP_paste_coverage: 0.7\n    #grid: [1.2, 1.2]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 12\n  num_pins_y: 12\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/qfn/wqfn.yaml",
    "content": "WQFN-14-1EP_2.5x2.5mm_P0.5mm_EP1.45x1.45mm:\n  device_type: 'WQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.onsemi.com/pub/Collateral/FUSB302B-D.PDF#page=32'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 2.5\n    tolerance: 0.05\n  body_size_y:\n    nominal: 2.5\n    tolerance: 0.05\n  overall_height:\n    nominal: 0.75\n    tolerance: 0.05\n\n  lead_width:\n    nominal: 0.24\n    tolerance: 0.06\n  lead_len:\n    nominal: 0.3\n    tolerance: 0 # no tolerance given in datasheet\n\n  EP_size_x:\n    nominal: 1.45\n    tolerance: 0.05\n  EP_size_y:\n    nominal: 1.45\n    tolerance: 0.05\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.7\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 3\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nWQFN-16-1EP_3x3mm_P0.5mm_EP1.6x1.6mm:\n  device_type: 'WQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.ti.com/lit/ds/symlink/tpa6132a2.pdf#page=24'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 2.85\n    maximum: 3.15\n  body_size_y:\n    minimum: 2.85\n    maximum: 3.15\n  overall_height:\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 1.6\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 1.6\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nWQFN-16-1EP_3x3mm_P0.5mm_EP1.75x1.75mm:\n  device_type: 'WQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'https://www.onsemi.com/pub/Collateral/FUSB307B-D.PDF#page=56'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 3\n    tolerance: 0\n  body_size_y:\n    nominal: 3\n    tolerance: 0\n  overall_height:\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.18\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.4\n\n  EP_size_x:\n    minimum: 1.65\n    maximum: 1.75\n  EP_size_x_overwrite: 1.75\n  EP_size_y:\n    minimum: 1.65\n    maximum: 1.75\n  EP_size_y_overwrite: 1.75\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nWQFN-16-1EP_4x4mm_P0.5mm_EP2.6x2.6mm:\n  device_type: 'WQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/ldc1312.pdf#page=59'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    maximum: 4.1\n  overall_height:\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.6\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.6\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nWQFN-24-1EP_4x4mm_P0.5mm_EP2.6x2.6mm:\n  device_type: 'WQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/lm26480.pdf#page=39'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    maximum: 4.1\n  overall_height:\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.6\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.6\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nWQFN-24-1EP_4x4mm_P0.5mm_EP2.45x2.45mm:\n  device_type: 'WQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/ts3a27518e.pdf#page=33'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    maximum: 4.1\n  overall_height:\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.24\n    maximum: 0.34\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.45\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.45\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 6\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nWQFN-42-1EP_3.5x9mm_P0.5mm_EP2.05x7.55mm:\n  device_type: 'WQFN'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/ts3l501e.pdf#page=23'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  body_size_x:\n    minimum: 3.4\n    maximum: 3.6\n  body_size_y:\n    minimum: 8.9\n    maximum: 9.1\n  overall_height:\n    minimum: 0.7\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.05\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 7.55\n    tolerance: 0.1\n  EP_num_paste_pads: [2, 7]\n\n  thermal_vias:\n    count: [3, 8]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 4\n  num_pins_y: 17\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/vson.yaml",
    "content": "VSON-10_3x3mm_P0.5mm_EP1.2x2mm:\n  device_type: 'VSON'\n  library: Package_SON\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://rohmfs.rohm.com/en/products/databook/datasheet/ic/power/switching_regulator/bd8314nuv-e.pdf (Page 20)'\n  ipc_class: 'qfn' # 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  # custom_name_format:\n  body_size_x:\n    nominal: 3\n    tolerance: 0.1\n  body_size_y:\n    nominal: 3\n    tolerance: 0.1\n  lead_width_min: 0.21\n  lead_width_max: 0.3\n  lead_len_min: 0.3\n  lead_len_max: 0.5\n\n  # heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  EP_size_x_min: 1.1\n  EP_size_x: 1.2\n  EP_size_x_max: 1.3\n  EP_size_y_min: 1.9\n  EP_size_y: 2.0\n  EP_size_y_max: 2.2\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n  #heel_reduction: 0.05 #for relatively large EP pads (increase clearance)\n\n  thermal_vias:\n    count: [1, 2]\n    drill: 0.3\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [2, 2]\n    #paste_between_vias: 1\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/wdfn-8.yml",
    "content": "WDFN-8-1EP_6x5mm_P1.27mm_EP3.4x4mm:\n  device_type: 'WDFN'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/8L_WDFN_5x6mm_MF_C04210B.pdf'\n  ipc_class: 'qfn'\n  body_size_x:\n    nominal: 6.0\n    tolerance: 0\n  body_size_y:\n    nominal: 5.0\n    tolerance: 0\n  lead_width_min: 0.35\n  lead_width_max: 0.48\n  lead_len_min: 0.50\n  lead_len_max: 0.70\n  EP_size_x: 3.4\n  EP_size_y: 4\n  EP_num_paste_pads: [2, 2]\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n"
  },
  {
    "path": "scripts/Packages/Package_NoLead__DFN_QFN_LGA_SON/size_definitions/wson.yaml",
    "content": "WSON-6-1EP_2x2mm_P0.65mm_EP1x1.6mm:\n  device_type: 'WSON'\n  library: Package_SON\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/tps61040.pdf#page=35'\n  ipc_class: 'qfn_pull_back' #'qfn' | 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n\n  body_size_x:\n    minimum: 1.9\n    maximum: 2.1\n  body_size_y:\n    minimum: 1.9\n    maximum: 2.1\n\n  lead_width:\n    minimum: 0.25\n    maximum: 0.35\n  lead_len:\n    minimum: 0.2\n    maximum: 0.3\n\n\n  EP_size_x:\n    nominal: 1\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 1.6\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [1, 2]\n\n  thermal_vias:\n    count: [1, 2]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    EP_num_paste_pads: [1, 2]\n    # paste_between_vias: 1\n    # paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    grid: [1.1, 1.1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.65\n  num_pins_x: 0\n  num_pins_y: 3\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nSON-8-1EP_3.0x2.0mm_P0.5mm_EP1.4x1.6mm:\n  device_type: 'SON'\n  library: Package_SON\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.fujitsu.com/downloads/MICRO/fsa/pdf/products/memory/fram/MB85RS16-DS501-00014-6v0-E.pdf'\n  ipc_class: 'qfn_pull_back' #'qfn' | 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  #body_size_x_min: 2.85\n  body_size_x:\n    nominal: 3.0\n    tolerance: 0.07\n  #body_size_x_max: 3.15\n  #body_size_y_min: 2.85\n  body_size_y:\n    nominal: 2.0\n    tolerance: 0.07\n  #body_size_y_max: 3.15\n  lead_width_min: 0.20\n  lead_width_max: 0.30\n  lead_len_min: 0.33\n  lead_len_max: 0.47\n\n\n  EP_size_x: 1.4\n  EP_size_y: 1.6\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.50\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nWSON-8-1EP_3.0x2.5mm_P0.5mm_EP1.2x1.5mm:\n  device_type: 'WSON'\n  suffix: '_PullBack'\n  library: Package_SON\n  size_source: 'http://www.ti.com/lit/ml/mpds400/mpds400.pdf'\n  ipc_class: 'qfn_pull_back' #'qfn' | 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    nominal: 3.0\n    tolerance: 0.1\n  body_size_y:\n    nominal: 2.5\n    tolerance: 0.1\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    nominal: 0.5\n    tolerance: 0.1\n  lead_to_edge: 0.1\n\n  EP_size_x:\n    nominal: 1.2\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 1.5\n    tolerance: 0.1\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 0.50\n  num_pins_x: 0\n  num_pins_y: 4\n\n  thermal_vias:\n    count: [2, 2]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    EP_paste_coverage: 0.75\n    paste_avoid_via: False\n\nWSON-8-1EP_6x5mm_P1.27mm_EP3.4x4.0mm:\n  device_type: 'WSON'\n  library: Package_SON\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/AppNotes/S72030.pdf'\n  ipc_class: 'qfn_pull_back' #'qfn' | 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  #body_size_x_min: 2.85\n  body_size_x:\n    nominal: 6\n    tolerance: 0\n  #body_size_x_max: 3.15\n  #body_size_y_min: 2.85\n  body_size_y:\n    nominal: 5\n    tolerance: 0\n  #body_size_y_max: 3.15\n  lead_width_min: 0.35\n  lead_width_max: 0.48\n  lead_len_min: 0.5\n  lead_len_max: 0.75\n\n\n  EP_size_x: 3.4\n  EP_size_y: 4.0\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nWSON-8-1EP_6x5mm_P1.27mm_E3.4x4.3mm:\n  device_type: 'WSON'\n  library: Package_SON\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.winbond.com/resource-files/w25q32jv%20revg%2003272018%20plus.pdf (page 68)'\n  ipc_class: 'qfn_pull_back' #'qfn' | 'qfn_pull_back'\n  #ipc_density: 'least' #overwrite global value for this device.\n  #body_size_x_min: 2.85\n  body_size_x:\n    minimum: 5.9\n    nominal: 6\n    maximum: 6.1\n  body_size_y:\n    minimum: 4.9\n    nominal: 5\n    maximum: 5.1\n  overall_height:\n    minimum: 0.70\n    nominal: 0.75\n    maximum: 0.80\n  lead_width:\n    minimum: 0.35\n    nominal: 0.4\n    maximum: 0.48\n  lead_len:\n    minimum: 0.55\n    nominal: 0.6\n    maximum: 0.65\n\n  EP_size_x:\n    minimum: 3.35\n    nominal: 3.4\n    maximum: 3.45\n  EP_size_y:\n    minimum: 4.25\n    nominal: 4.3\n    maximum: 4.35\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  pitch: 1.27\n  num_pins_x: 0\n  num_pins_y: 4\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nWSON-8-1EP_4x4mm_P0.8mm_EP2.2x3mm:\n  device_type: 'WSON'\n  library: Package_SON\n  size_source: 'https://www.ti.com/lit/ds/symlink/lp2987.pdf#page=26' # NGN0008A\n  ipc_class: 'qfn_pull_back'\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    maximum: 4.1\n  overall_height:\n    maximum: 0.8\n\n  lead_width:\n    maximum: 0.35\n    minimum: 0.25\n  lead_len:\n    minimum: 0.4\n    maximum: 0.6\n\n  # This value is tricky. The recommended footprint has pad-center-to-center as 3.3mm\n  # But Adding EP + EP-Pad-Distance + Pad (2.2 + (0.2+0.15)*2 + 0.5 gives 3.4mm.\n  # The above addition works on reference-dimensions. So is not to be trusted.\n  lead_center_to_center_x: 3.3\n\n  EP_size_x:\n    nominal: 2.2\n    tolerance: 0.05\n  EP_size_y:\n    nominal: 3\n    tolerance: 0.05\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [1, 3]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    paste_avoid_via: True\n\n  pitch: 0.8\n  num_pins_x: 0\n  num_pins_y: 4\n\nWSON-8-1EP_4x4mm_P0.8mm_EP1.98x3mm:\n  device_type: 'WSON'\n  library: Package_SON\n  size_source: 'https://www.ti.com/lit/ds/symlink/lm5017.pdf#page=34'\n  ipc_class: 'qfn' #'qfn' | 'qfn_pull_back'\n  body_size_x:\n    nominal: 4.0\n    tolerance: 0.1\n  body_size_y:\n    nominal: 4.0\n    tolerance: 0.1\n  overall_height:\n    maximum: 0.8\n\n  lead_width: 0.3 +/- 0.05\n  lead_len: 0.4 +/- 0.1\n\n  EP_size_x:\n    nominal: 1.98\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 3\n    tolerance: 0.1\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [1, 3]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    paste_avoid_via: True\n\n  pitch: 0.8\n  num_pins_x: 0\n  num_pins_y: 4\n\nWSON-8-1EP_4x4mm_P0.8mm_EP2.6x3mm:\n  device_type: 'WSON'\n  library: Package_SON\n  size_source: 'https://www.ti.com/lit/ds/symlink/lp2951-n.pdf#page=43'\n  ipc_class: 'qfn' #'qfn' | 'qfn_pull_back'\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    maximum: 4.1\n  overall_height:\n    maximum: 0.8\n\n  lead_width:\n    maximum: 0.35\n    minimum: 0.25\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.6\n    tolerance: 0.05\n  EP_size_y:\n    nominal: 3\n    tolerance: 0.05\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [1, 3]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    paste_avoid_via: True\n\n  pitch: 0.8\n  num_pins_x: 0\n  num_pins_y: 4\n\nWSON-8-1EP_3x3mm_P0.5mm_EP1.2x2mm:\n  device_type: 'WSON'\n  library: Package_SON\n  size_source: 'http://www.ti.com/lit/ds/symlink/lp2951.pdf#page=27'\n  ipc_class: 'qfn' #'qfn' | 'qfn_pull_back'\n  body_size_x:\n    minimum: 2.9\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    maximum: 3.1\n  overall_height:\n    minimum: 0.7\n    maximum: 0.8\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    minimum: 0.4\n    maximum: 0.6\n\n  EP_size_x:\n    nominal: 1.2\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2\n    tolerance: 0.1\n  EP_num_paste_pads: [1, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    EP_paste_coverage: 0.75\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n  \nWSON-8-1EP_3x3mm_P0.5mm_EP1.45x2.4mm:\n  device_type: 'WSON'\n  library: Package_SON\n  size_source: 'https://www.ti.com/lit/ds/symlink/ina333.pdf#page=30'\n  ipc_class: 'qfn' #'qfn' | 'qfn_pull_back'\n  body_size_x:\n    minimum: 2.9\n    maximum: 3.1\n  body_size_y:\n    minimum: 2.9\n    maximum: 3.1\n  overall_height:\n    minimum: 0.7\n    maximum: 0.8\n\n  lead_width:\n    nominal: 0.25\n    tolerance: 0.05\n  lead_len:\n    minimum: 0.4\n    maximum: 0.6\n\n  EP_size_x:\n    nominal: 1.45\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2.4\n    tolerance: 0.1\n  EP_num_paste_pads: [1, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    paste_via_clearance: 0.1\n    EP_paste_coverage: 0.75\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 4\n\nWSON-10-1EP_2.5x2.5mm_P0.5mm_EP1.2x2mm:\n  device_type: 'WSON'\n  library: Package_SON\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/gpn/tps63030#page=24'\n  ipc_class: 'qfn' #'qfn' | 'qfn_pull_back'\n  #custom_name_format: 'Texas_S-PWSON-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    minimum: 2.4\n    maximum: 2.6\n  body_size_y:\n    minimum: 2.4\n    maximum: 2.6\n  overall_height:\n    minimum: 0.6\n    maximum: 0.8\n\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.35\n    maximum: 0.45\n\n  EP_size_x:\n    nominal: 1.2\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 2\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [2, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 5\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n\nWSON-12-1EP_4x4mm_P0.5mm_EP2.6x3mm:\n  device_type: 'WSON'\n  library: Package_SON\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.ti.com/lit/ds/symlink/ldc1312.pdf#page=62'\n  ipc_class: 'qfn' #'qfn' | 'qfn_pull_back'\n  #custom_name_format: 'Texas_S-PWSON-N{pincount}_EP{ep_size_x:g}x{ep_size_y:g}mm{vias:s}'\n  #ipc_density: 'least' #overwrite global value for this device.\n  body_size_x:\n    minimum: 3.9\n    maximum: 4.1\n  body_size_y:\n    minimum: 3.9\n    maximum: 4.1\n  overall_height:\n    minimum: 0.8\n    maximum: 1\n\n  lead_width:\n    minimum: 0.2\n    maximum: 0.3\n  lead_len:\n    minimum: 0.3\n    maximum: 0.5\n\n  EP_size_x:\n    nominal: 2.6\n    tolerance: 0.1\n  EP_size_y:\n    nominal: 3\n    tolerance: 0.1\n  # EP_paste_coverage: 0.65\n  EP_num_paste_pads: [2, 2]\n\n  thermal_vias:\n    count: [3, 3]\n    drill: 0.2\n    # min_annular_ring: 0.15\n    paste_via_clearance: 0.1\n    #EP_num_paste_pads: [2, 2]\n    # paste_between_vias: 2\n    #paste_rings_outside: 1\n    EP_paste_coverage: 0.75\n    #grid: [1, 1]\n    # bottom_pad_size:\n    paste_avoid_via: False\n\n  pitch: 0.5\n  num_pins_x: 0\n  num_pins_y: 6\n  #chamfer_edge_pins: 0.25\n  #pin_count_grid:\n  #pad_length_addition: 0.5\n  #suffix: '_PullBack'\n  #include_suffix_in_3dpath: 'False'\n  #include_pad_size: 'fp_name_only' # 'both' | 'none' (default)\n"
  },
  {
    "path": "scripts/Packages/Package_PLCC/ipc_plcc_jLead_generator.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport argparse\nimport yaml\nimport math\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"..\"))  # load parent path of KicadModTree\n\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\n\nipc_density = 'nominal'\nipc_doc_file = '../ipc_definitions.yaml'\ncategory = 'LCC'\n\ndef roundToBase(value, base):\n    return round(value/base) * base\n\ndef params_inch_to_metric(device_params):\n    for key in device_params:\n        if type(device_params[key]) in [int, float] and 'num_' not in key:\n            device_params[key] = device_params[key]*25.4\n\nclass QFP():\n    def __init__(self, configuration):\n        self.configuration = configuration\n        with open(ipc_doc_file, 'r') as ipc_stream:\n            try:\n                self.ipc_defintions = yaml.safe_load(ipc_stream)\n            except yaml.YAMLError as exc:\n                print(exc)\n\n\n\n    def calcPadDetails(self, device_params, ipc_data, ipc_round_base):\n        # Zmax = Lmin + 2JT + √(CL^2 + F^2 + P^2)\n        # Gmin = Smax − 2JH − √(CS^2 + F^2 + P^2)\n        # Xmax = Wmin + 2JS + √(CW^2 + F^2 + P^2)\n\n        # Some manufacturers do not list the terminal spacing (S) in their datasheet but list the terminal lenght (T)\n        # Then one can calculate\n        # Stol(RMS) = √(Ltol^2 + 2*^2)\n        # Smin = Lmin - 2*Tmax\n        # Smax(RMS) = Smin + Stol(RMS)\n\n        F = self.configuration.get('manufacturing_tolerance', 0.1)\n        P = self.configuration.get('placement_tolerance', 0.05)\n\n        lead_width_tol = device_params['lead_width_max'] - device_params['lead_width_min']\n\n        def calcPadLength(overall, body, lead_inside=None, lead_center=None):\n            overall_tol = overall['max']-overall['min']\n            if lead_inside:\n                Tmin = (overall['max'] - lead_inside['max'])/2\n                Tmax = (overall['min'] - lead_inside['min'])/2\n                Ttol = Tmax - Tmin\n                inside_tol = lead_inside['max'] - lead_inside['min']\n                Stol_RMS = math.sqrt(overall_tol**2+inside_tol**2)\n                Smax_RMS = lead_inside['min'] + Stol_RMS\n            elif lead_center:\n                body_tol = body['max']-body['min']\n                Tmin = (body['max'] - lead_center['max'])\n                Tmax = (body['min'] - lead_center['min'])\n                Ttol = Tmax - Tmin\n                center_tol = lead_center['max'] - lead_center['min']\n                Stol_RMS = math.sqrt(body_tol**2+center_tol**2)\n                Smax_RMS = body['max'] - 2*Tmin + Stol_RMS\n            else:\n                lead_len_tol = device_params['lead_len_max'] - device_params['lead_len_min']\n                Stol_RMS = math.sqrt(overall_tol**2+2*(lead_len_tol**2))\n                Smin = overall['min'] - 2*device_params['lead_len_max']\n                Smax_RMS = Smin + Stol_RMS\n\n            Gmin = Smax_RMS - 2*ipc_data['heel'] - math.sqrt(Stol_RMS**2 + F**2 + P**2)\n\n            Zmax = overall['min'] + 2*ipc_data['toe'] + math.sqrt(overall_tol**2 + F**2 + P**2)\n\n            Zmax = roundToBase(Zmax, ipc_round_base['toe'])\n            Gmin = roundToBase(Gmin, ipc_round_base['heel'])\n\n            Zmax += device_params.get('pad_length_addition', 0)\n\n            return Gmin, Zmax\n        overall_x={\n            'min':device_params.get('overall_size_x_min', device_params.get('overall_size_x')),\n            'max':device_params.get('overall_size_x_max', device_params.get('overall_size_x'))\n            }\n        overall_y={\n            'min':device_params.get('overall_size_y_min', device_params.get('overall_size_y')),\n            'max':device_params.get('overall_size_y_max', device_params.get('overall_size_y'))\n            }\n\n        body_x={\n            'min':device_params.get('body_size_x_min', device_params.get('body_size_x')),\n            'max':device_params.get('body_size_x_max', device_params.get('body_size_x'))\n            }\n        body_y={\n            'min':device_params.get('body_size_y_min', device_params.get('body_size_y')),\n            'max':device_params.get('body_size_y_max', device_params.get('body_size_y'))\n            }\n\n        if 'lead_inside_x_min' in device_params:\n            Gmin_x, Zmax_x = calcPadLength(\n                overall=overall_x,\n                body=body_x,\n                lead_inside={\n                    'min':device_params['lead_inside_x_min'],\n                    'max':device_params['lead_inside_x_max']}\n                 )\n            Gmin_y, Zmax_y = calcPadLength(\n                overall=overall_y,\n                body=body_y,\n                lead_inside={\n                    'min':device_params['lead_inside_y_min'],\n                    'max':device_params['lead_inside_y_max']}\n                )\n        elif 'lead_center_distance_x_min' in device_params:\n            Gmin_x, Zmax_x = calcPadLength(\n                overall=overall_x,\n                body=body_x,\n                lead_center={\n                    'min':device_params['lead_center_distance_x_min'],\n                    'max':device_params['lead_center_distance_x_max']}\n                 )\n            Gmin_y, Zmax_y = calcPadLength(\n                overall=overall_y,\n                body=body_y,\n                lead_center={\n                    'min':device_params['lead_center_distance_y_min'],\n                    'max':device_params['lead_center_distance_y_max']}\n                 )\n        else:\n            Gmin_x, Zmax_x = calcPadLength(\n                overall=overall_x,\n                body=body_x\n                )\n\n            Gmin_y, Zmax_y = calcPadLength(\n                overall=overall_y,\n                body=body_y\n                )\n\n\n        Xmax = device_params['lead_width_min'] + 2*ipc_data['side'] + math.sqrt(lead_width_tol**2 + F**2 + P**2)\n        Xmax = roundToBase(Xmax, ipc_round_base['side'])\n\n        Pad = {}\n        Pad['first'] = {'start':[-((device_params['num_pins_x']-1)%2)/2*device_params['pitch'], -(Zmax_y+Gmin_y)/4], 'size':[Xmax,(Zmax_y-Gmin_y)/2]}\n\n        Pad['left'] = {'center':[-(Zmax_x+Gmin_x)/4, 0], 'size':[(Zmax_x-Gmin_x)/2,Xmax]}\n        Pad['right'] = {'center':[(Zmax_x+Gmin_x)/4, 0], 'size':[(Zmax_x-Gmin_x)/2,Xmax]}\n        Pad['top'] = {'start':[(device_params['num_pins_x']-1)/2*device_params['pitch'],-(Zmax_y+Gmin_y)/4], 'size':[Xmax,(Zmax_y-Gmin_y)/2]}\n        Pad['bottom'] = {'center':[0,(Zmax_y+Gmin_y)/4], 'size':[Xmax,(Zmax_y-Gmin_y)/2]}\n\n        return Pad\n\n    def generateFootprint(self, device_params):\n        fab_line_width = self.configuration.get('fab_line_width', 0.1)\n        silk_line_width = self.configuration.get('silk_line_width', 0.12)\n\n        lib_name = self.configuration['lib_name_format_string'].format(category=category)\n\n        if 'body_size_x' in device_params:\n            size_x = device_params['body_size_x']\n        else:\n            size_x = (device_params['body_size_x_max'] + device_params['body_size_x_min'])/2\n\n        if 'body_size_y' in device_params:\n            size_y = device_params['body_size_y']\n        else:\n            size_y = (device_params['body_size_y_max'] + device_params['body_size_y_min'])/2\n\n        pincount = device_params['num_pins_x']*2 + device_params['num_pins_y']*2\n\n        ipc_reference = 'ipc_spec_j_lead'\n\n        ipc_data_set = self.ipc_defintions[ipc_reference][ipc_density]\n        ipc_round_base = self.ipc_defintions[ipc_reference]['round_base']\n\n        pad_details = self.calcPadDetails(device_params, ipc_data_set, ipc_round_base)\n\n\n        suffix = device_params.get('suffix', '').format(pad_x=pad_details['left']['size'][0],\n            pad_y=pad_details['left']['size'][1])\n        suffix_3d = suffix if device_params.get('include_suffix_in_3dpath', 'True') == 'True' else \"\"\n\n        model3d_path_prefix = self.configuration.get('3d_model_prefix','${KISYS3DMOD}')\n        name_format = self.configuration['fp_name_format_string']\n\n        fp_name = name_format.format(\n            man=device_params.get('manufacturer',''),\n            mpn=device_params.get('part_number',''),\n            pkg=device_params['device_type'],\n            pincount=pincount,\n            size_y=size_y,\n            size_x=size_x,\n            pitch=device_params['pitch'],\n            suffix=suffix\n            ).replace('__','_').lstrip('_')\n\n        fp_name_2 = name_format.format(\n            man=device_params.get('manufacturer',''),\n            mpn=device_params.get('part_number',''),\n            pkg=device_params['device_type'],\n            pincount=pincount,\n            size_y=size_y,\n            size_x=size_x,\n            pitch=device_params['pitch'],\n            suffix=suffix_3d\n            ).replace('__','_').lstrip('_')\n\n        model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'\\\n            .format(\n                model3d_path_prefix=model3d_path_prefix, lib_name=lib_name,\n                fp_name=fp_name_2)\n        #print(fp_name)\n        #print(pad_details)\n\n        kicad_mod = Footprint(fp_name)\n\n                # init kicad footprint\n        kicad_mod.setDescription(\n            \"{manufacturer} {mpn} {package}, {pincount} Pin ({datasheet}), generated with kicad-footprint-generator {scriptname}\"\\\n            .format(\n                manufacturer = device_params.get('manufacturer',''),\n                package = device_params['device_type'],\n                mpn = device_params.get('part_number',''),\n                pincount = pincount,\n                datasheet = device_params['size_source'],\n                scriptname = os.path.basename(__file__).replace(\"  \", \" \")\n                ).lstrip())\n\n        kicad_mod.setTags(self.configuration['keyword_fp_string']\\\n            .format(\n                man=device_params.get('manufacturer',''),\n                package=device_params['device_type'],\n                category=category\n            ).lstrip())\n        kicad_mod.setAttribute('smd')\n\n        pad_shape_details = {}\n        pad_shape_details['shape'] = Pad.SHAPE_ROUNDRECT\n        pad_shape_details['radius_ratio'] = configuration.get('round_rect_radius_ratio', 0)\n        if 'round_rect_max_radius' in configuration:\n            pad_shape_details['maximum_radius'] = configuration['round_rect_max_radius']\n\n        init = 1\n        kicad_mod.append(PadArray(\n            initial= init,\n            type=Pad.TYPE_SMT,\n            layers=Pad.LAYERS_SMT,\n            pincount=int(math.ceil(device_params['num_pins_x']/2)),\n            x_spacing=-device_params['pitch'], y_spacing=0,\n            **pad_details['first'], **pad_shape_details))\n\n        init += int(math.ceil(device_params['num_pins_x']/2))\n        kicad_mod.append(PadArray(\n            initial= init,\n            type=Pad.TYPE_SMT,\n            layers=Pad.LAYERS_SMT,\n            pincount=device_params['num_pins_y'],\n            x_spacing=0, y_spacing=device_params['pitch'],\n            **pad_details['left'], **pad_shape_details))\n\n        init += device_params['num_pins_y']\n        kicad_mod.append(PadArray(\n            initial= init,\n            type=Pad.TYPE_SMT,\n            layers=Pad.LAYERS_SMT,\n            pincount=device_params['num_pins_x'],\n            y_spacing=0, x_spacing=device_params['pitch'],\n            **pad_details['bottom'], **pad_shape_details))\n\n        init += device_params['num_pins_x']\n        kicad_mod.append(PadArray(\n            initial= init,\n            type=Pad.TYPE_SMT,\n            layers=Pad.LAYERS_SMT,\n            pincount=device_params['num_pins_y'],\n            x_spacing=0, y_spacing=-device_params['pitch'],\n            **pad_details['right'], **pad_shape_details))\n\n        init += device_params['num_pins_y']\n        kicad_mod.append(PadArray(\n            initial= init,\n            type=Pad.TYPE_SMT,\n            layers=Pad.LAYERS_SMT,\n            pincount=int(math.floor(device_params['num_pins_x']/2)),\n            y_spacing=0, x_spacing=-device_params['pitch'],\n            **pad_details['top'], **pad_shape_details))\n\n\n        body_edge = {\n            'left': -size_x/2,\n            'right': size_x/2,\n            'top': -size_y/2,\n            'bottom': size_y/2\n            }\n\n        bounding_box = {\n            'left': pad_details['left']['center'][0] - pad_details['left']['size'][0]/2,\n            'right': pad_details['right']['center'][0] + pad_details['right']['size'][0]/2,\n            'top': pad_details['top']['start'][1] - pad_details['top']['size'][1]/2,\n            'bottom': pad_details['bottom']['center'][1] + pad_details['bottom']['size'][1]/2\n        }\n\n\n        pad_width = pad_details['top']['size'][0]\n        p1_x = pad_details['first']['start'][0]\n\n        # ############################ SilkS ##################################\n\n        silk_pad_offset = configuration['silk_pad_clearance'] + configuration['silk_line_width']/2\n        silk_offset = configuration['silk_fab_offset']\n\n        sx1 = -(device_params['pitch']*(device_params['num_pins_x']-1)/2.0\n            + pad_width/2.0 + silk_pad_offset)\n\n        sy1 = -(device_params['pitch']*(device_params['num_pins_y']-1)/2.0\n            + pad_width/2.0 + silk_pad_offset)\n\n        poly_silk = [\n            {'x': sx1, 'y': body_edge['top']-silk_offset},\n            {'x': body_edge['left']-silk_offset, 'y': body_edge['top']-silk_offset},\n            {'x': body_edge['left']-silk_offset, 'y': sy1}\n        ]\n        kicad_mod.append(PolygoneLine(\n            polygone=poly_silk,\n            width=configuration['silk_line_width'],\n            layer=\"F.SilkS\", x_mirror=0))\n        kicad_mod.append(PolygoneLine(\n            polygone=poly_silk,\n            width=configuration['silk_line_width'],\n            layer=\"F.SilkS\", y_mirror=0))\n        kicad_mod.append(PolygoneLine(\n            polygone=poly_silk,\n            width=configuration['silk_line_width'],\n            layer=\"F.SilkS\", x_mirror=0, y_mirror=0))\n\n        silk_off_45 = silk_offset/sqrt(2)\n        poly_silk_tl = [\n            {'x': sx1, 'y': body_edge['top']-silk_offset},\n            {'x': body_edge['left']+device_params['body_chamfer']-silk_off_45, 'y': body_edge['top']-silk_offset},\n            {'x': body_edge['left']-silk_offset, 'y': body_edge['top']+device_params['body_chamfer']-silk_off_45},\n            {'x': body_edge['left']-silk_offset, 'y': sy1}\n        ]\n        kicad_mod.append(PolygoneLine(\n            polygone=poly_silk_tl,\n            width=configuration['silk_line_width'],\n            layer=\"F.SilkS\"))\n\n        # # ######################## Fabrication Layer ###########################\n\n        fab_bevel_size = min(configuration['fab_bevel_size_absolute'], configuration['fab_bevel_size_relative']*min(size_x, size_y))\n        fab_bevel_y = fab_bevel_size/sqrt(2)\n        poly_fab = [\n            {'x': p1_x, 'y': body_edge['top']+fab_bevel_y},\n            {'x': p1_x+fab_bevel_size/2, 'y': body_edge['top']},\n            {'x': body_edge['right'], 'y': body_edge['top']},\n            {'x': body_edge['right'], 'y': body_edge['bottom']},\n            {'x': body_edge['left'], 'y': body_edge['bottom']},\n            {'x': body_edge['left'], 'y': body_edge['top']+device_params['body_chamfer']},\n            {'x': body_edge['left']+device_params['body_chamfer'], 'y': body_edge['top']},\n            {'x': p1_x-fab_bevel_size/2, 'y': body_edge['top']},\n            {'x': p1_x, 'y': body_edge['top']+fab_bevel_y}\n        ]\n\n        kicad_mod.append(PolygoneLine(\n            polygone=poly_fab,\n            width=configuration['fab_line_width'],\n            layer=\"F.Fab\"))\n\n        # # ############################ CrtYd ##################################\n\n        off = ipc_data_set['courtyard']\n        grid = configuration['courtyard_grid']\n        off_45 = off*math.tan(math.radians(45.0/2))\n\n        cy1=roundToBase(bounding_box['top']-off, grid)\n        cy2=roundToBase(body_edge['top']-off, grid)\n        cy3=-roundToBase(\n            device_params['pitch']*(device_params['num_pins_y']-1)/2.0\n            + pad_width/2.0 + off, grid)\n        cy4=roundToBase(body_edge['top']+device_params['body_chamfer']-off_45, grid)\n\n\n\n        cx1=-roundToBase(\n            device_params['pitch']*(device_params['num_pins_x']-1)/2.0\n            + pad_width/2.0 + off, grid)\n        cx2=roundToBase(body_edge['left']-off, grid)\n        cx3=roundToBase(bounding_box['left']-off, grid)\n        cx4=roundToBase(body_edge['left']+device_params['body_chamfer']-off_45, grid)\n\n\n        crty_poly_tl = [\n            {'x':0, 'y':cy1},\n            {'x':cx1, 'y':cy1},\n            {'x':cx1, 'y':cy2},\n            {'x':cx2, 'y':cy2},\n            {'x':cx2, 'y':cy3},\n            {'x':cx3, 'y':cy3},\n            {'x':cx3, 'y':0}\n        ]\n\n        kicad_mod.append(PolygoneLine(polygone=crty_poly_tl,\n            layer='F.CrtYd', width=configuration['courtyard_line_width'],\n            x_mirror=0))\n        kicad_mod.append(PolygoneLine(polygone=crty_poly_tl,\n            layer='F.CrtYd', width=configuration['courtyard_line_width'],\n            y_mirror=0))\n        kicad_mod.append(PolygoneLine(polygone=crty_poly_tl,\n            layer='F.CrtYd', width=configuration['courtyard_line_width'],\n            x_mirror=0, y_mirror=0))\n\n        crty_poly_tl_ch = [\n            {'x':0, 'y':cy1},\n            {'x':cx1, 'y':cy1},\n            {'x':cx1, 'y':cy2},\n            {'x':cx4, 'y':cy2},\n            {'x':cx2, 'y':cy4},\n            {'x':cx2, 'y':cy3},\n            {'x':cx3, 'y':cy3},\n            {'x':cx3, 'y':0}\n        ]\n        kicad_mod.append(PolygoneLine(polygone=crty_poly_tl_ch,\n            layer='F.CrtYd', width=configuration['courtyard_line_width']))\n\n        # ######################### Text Fields ###############################\n\n        addTextFields(kicad_mod=kicad_mod, configuration=configuration, body_edges=body_edge,\n            courtyard={'top': cy1, 'bottom': -cy1}, fp_name=fp_name, text_y_inside_position='center')\n\n        ##################### Output and 3d model ############################\n\n        kicad_mod.append(Model(filename=model_name))\n\n        output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n        if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n            os.makedirs(output_dir)\n        filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=fp_name)\n\n        file_handler = KicadFileHandler(kicad_mod)\n        file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('files', metavar='file', type=str, nargs='+',\n                        help='list of files holding information about what devices should be created.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='../package_config_KLCv3.yaml')\n    parser.add_argument('--density', type=str, nargs='?', help='Density level (L,N,M)', default='N')\n    parser.add_argument('--ipc_doc', type=str, nargs='?', help='IPC definition document', default='../ipc_definitions.yaml')\n    parser.add_argument('--force_rectangle_pads', action='store_true', help='Force the generation of rectangle pads instead of rounded rectangle')\n    args = parser.parse_args()\n\n    if args.density == 'L':\n        ipc_density = 'least'\n    elif args.density == 'M':\n        ipc_density = 'most'\n\n    ipc_doc_file = args.ipc_doc\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    if args.force_rectangle_pads:\n        configuration['round_rect_max_radius'] = None\n        configuration['round_rect_radius_ratio'] = 0\n\n    for filepath in args.files:\n        qfp = QFP(configuration)\n\n        with open(filepath, 'r') as command_stream:\n            try:\n                cmd_file = yaml.safe_load(command_stream)\n            except yaml.YAMLError as exc:\n                print(exc)\n        for pkg in cmd_file:\n            if cmd_file[pkg].get('units', 'mm') == 'inches':\n                params_inch_to_metric(cmd_file[pkg])\n            qfp.generateFootprint(cmd_file[pkg])\n"
  },
  {
    "path": "scripts/Packages/Package_PLCC/plcc_jLead_definitions.yaml",
    "content": "PLCC_32:\n  device_type: 'PLCC'\n  # units: 'inches'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://ww1.microchip.com/downloads/en/DeviceDoc/doc0015.pdf'\n  #overall_size_x: 0.69\n  overall_size_x_min: 12.319\n  overall_size_x_max: 12.573\n  #overall_size_y: 0.69\n  overall_size_y_min: 14.859\n  overall_size_y_max: 15.113\n  #body_size_x: 0.653\n  body_size_x_min: 11.354\n  body_size_x_max: 11.506\n  #body_size_y: 0.653\n  body_size_y_min: 13.894\n  body_size_y_max: 14.046\n  body_chamfer: 1.14\n  lead_width_min: 0.330\n  lead_width_max:  0.533\n  # lead_len_min: 0.45\n  # lead_len_max: 0.75\n  # lead_inside_x: 0.61\n  # lead_inside_x_min: 0.59\n  # lead_inside_x_max: 0.63\n  # lead_inside_y: 0.61\n  # lead_inside_y_min: 0.59\n  # lead_inside_y_max: 0.63\n  lead_center_distance_x_min: 9.906\n  lead_center_distance_x_max: 10.922\n  lead_center_distance_y_min: 12.471\n  lead_center_distance_y_max: 13.487\n  pitch: 1.27\n  num_pins_x: 7\n  num_pins_y: 9\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nPLCC_44:\n  device_type: 'PLCC'\n  units: 'inches'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  overall_size_x: 0.69\n  overall_size_x_min: 0.685\n  overall_size_x_max: 0.695\n  overall_size_y: 0.69\n  overall_size_y_min: 0.685\n  overall_size_y_max: 0.695\n  body_size_x: 0.653\n  body_size_x_min: 0.65\n  body_size_x_max: 0.656\n  body_size_y: 0.653\n  body_size_y_min: 0.65\n  body_size_y_max: 0.656\n  body_chamfer: 0.045\n  lead_width_min: 0.013\n  lead_width_max: 0.021\n  # lead_len_min: 0.45\n  # lead_len_max: 0.75\n  lead_inside_x: 0.61\n  lead_inside_x_min: 0.59\n  lead_inside_x_max: 0.63\n  lead_inside_y: 0.61\n  lead_inside_y_min: 0.59\n  lead_inside_y_max: 0.63\n  pitch: 0.05\n  num_pins_x: 11\n  num_pins_y: 11\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nPLCC_68:\n  device_type: 'PLCC'\n  units: 'inches'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  overall_size_x: 0.99\n  overall_size_x_min: 0.985\n  overall_size_x_max: 0.995\n  overall_size_y: 0.99\n  overall_size_y_min: 0.985\n  overall_size_y_max: 0.995\n  body_size_x: 0.954\n  body_size_x_min: 0.95\n  body_size_x_max: 0.958\n  body_size_y: 0.954\n  body_size_y_min: 0.95\n  body_size_y_max: 0.958\n  body_chamfer: 0.045\n  lead_width_min: 0.013\n  lead_width_max: 0.021\n  # lead_len_min: 0.45\n  # lead_len_max: 0.75\n  lead_inside_x: 0.91\n  lead_inside_x_min: 0.89\n  lead_inside_x_max: 0.93\n  lead_inside_y: 0.91\n  lead_inside_y_min: 0.89\n  lead_inside_y_max: 0.93\n  pitch: 0.05\n  num_pins_x: 17\n  num_pins_y: 17\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n\nPLCC_84:\n  device_type: 'PLCC'\n  units: 'inches'\n  #manufacturer: 'man'\n  #part_number: 'mpn'\n  size_source: 'http://www.microsemi.com/index.php?option=com_docman&task=doc_download&gid=131095'\n  overall_size_x: 1.19\n  overall_size_x_min: 1.185\n  overall_size_x_max: 1.195\n  overall_size_y: 1.19\n  overall_size_y_min: 1.185\n  overall_size_y_max: 1.195\n  body_size_x: 1.154\n  body_size_x_min: 1.15\n  body_size_x_max: 1.158\n  body_size_y: 1.154\n  body_size_y_min: 1.15\n  body_size_y_max: 1.158\n  body_chamfer: 0.045\n  lead_width_min: 0.013\n  lead_width_max: 0.021\n  # lead_len_min: 0.45\n  # lead_len_max: 0.75\n  lead_inside_x: 1.11\n  lead_inside_x_min: 1.09\n  lead_inside_x_max: 1.13\n  lead_inside_y: 1.11\n  lead_inside_y_min: 1.09\n  lead_inside_y_max: 1.13\n  pitch: 0.05\n  num_pins_x: 21\n  num_pins_y: 21\n  #pad_length_addition: 0.5\n  #suffix: '_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder'\n  #include_suffix_in_3dpath: 'False'\n"
  },
  {
    "path": "scripts/Packages/TO_SOT_Packages_SMD/DPAK.py",
    "content": "import sys\nimport os\nimport argparse\nimport yaml\nimport pprint\n\nsys.path.append(os.path.join(sys.path[0], \"../../..\"))  # enable package import from parent directory\n\nfrom KicadModTree import *  # NOQA\n\n\nclass Dimensions(object):\n\n    def __init__(self, base, variant, cut_pin=False, tab_linked=False):\n        # FROM KLC\n        self.fab_line_width_mm = 0.1\n        self.silk_line_width_mm = 0.12\n        self.courtyard_line_width_mm = 0.05\n        self.courtyard_clearance_mm = 0.25\n        self.courtyard_precision_mm = 0.01\n\n        # PIN NUMBERING\n        self.centre_pin = 1 + variant['pins'] // 2\n        self.tab_pin_number= self.centre_pin if (tab_linked or cut_pin) else variant['pins'] + 1\n\n        # NAME\n        self.name = self.footprint_name(base['series'], (variant['pins'] - 1) if cut_pin else variant['pins'],\n                                        not cut_pin, self.tab_pin_number)\n        # PADS\n        self.pad_1_centre_x_mm = (variant['pad']['x_mm'] / 2.0) - (base['footprint']['x_mm'] / 2.0)\n        self.pad_1_centre_y_mm = -variant['pitch_mm'] * (variant['pins'] - 1) / 2.0\n        self.tab_centre_x_mm = (base['footprint']['x_mm'] - base['footprint']['tab']['x_mm']) / 2.0\n        self.tab_centre_y_mm = 0.0\n        self.split_paste = (base['footprint']['split_paste'] == 'on')\n\n        # FAB OUTLINE\n        self.device_offset_x_mm = base['device']['x_mm'] / 2.0  # x coordinate of RHS of device\n        self.tab_project_x_mm = base['device']['tab']['project_x_mm']\n        self.tab_offset_y_mm = base['device']['tab']['y_mm'] / 2.0  # y coordinate of bottom of tab\n        self.body_x_mm = base['device']['body']['x_mm']\n        self.body_offset_y_mm = base['device']['body']['y_mm'] / 2.0  # y coordinate of bottom of body\n        self.corner_mm = 1.0  #  x and y size of chamfered corner on top left of body -- from KLC\n\n        # COURTYARD\n        self.biggest_x_mm = base['footprint']['x_mm']\n        self.biggest_y_mm = max(base['footprint']['tab']['y_mm'], base['device']['body']['y_mm'],\n                                       2.0 * self.pad_1_centre_y_mm + variant['pad']['y_mm'])\n        self.courtyard_offset_x_mm = self.round_to(self.courtyard_clearance_mm + self.biggest_x_mm / 2.0,\n                                                   self.courtyard_precision_mm)\n        self.courtyard_offset_y_mm = self.round_to(self.courtyard_clearance_mm + self.biggest_y_mm / 2.0,\n                                                   self.courtyard_precision_mm)\n        # SILKSCREEN\n        self.label_centre_x_mm = 0\n        self.label_centre_y_mm = self.courtyard_offset_y_mm + 1\n        self.silk_line_nudge_mm = 0.20  #  amount to shift to stop silkscreen lines overlapping fab lines\n\n\n    def round_to(self, n, precision):\n        correction = 0.5 if n >= 0 else -0.5\n        return int(n / precision + correction) * precision\n\n\n    def footprint_name(self, series, num_pins, add_tab, tab_number):\n        tab_suffix = '_TabPin' if add_tab else ''\n        pins = str(num_pins)\n        tab = str(tab_number) if add_tab else ''\n        name = '{p:s}-{ps:s}{ts:s}{tn:s}'.format(p=series, ps=pins, ts=tab_suffix, tn=tab)\n        return name\n\n\nclass DPAK(object):\n\n    def __init__(self, config_file):\n        self.SERIES = None\n        self.config = None\n\n\n    def load_config(self, config_file):\n        try:\n            devices = yaml.safe_load_all(open(config_file))\n        except FileNotFoundError as fnfe:\n            print(fnfe)\n            return\n        config = None\n        for dev in devices:\n            if dev['base']['series'] == self.SERIES:\n                config = dev\n                break\n        return config\n\n\n    def add_properties(self, m, variant):\n        m.setDescription('{bd:s}, {vd:s}'.format(bd=self.config['base']['description'], vd=variant['datasheet']))\n        m.setTags('{bk:s} {vk:s}'.format(bk=self.config['base']['keywords'], vk=variant['keywords']))\n        m.setAttribute('smd')\n        return m\n\n\n    def add_labels(self, m, variant, dim):\n        m.append(Text(type='reference', text='REF**', size=[1,1], at=[dim.label_centre_x_mm, -dim.label_centre_y_mm],\n                      layer='F.SilkS'))\n        m.append(Text(type='user', text='%R', size=[1,1], at=[0, 0], layer='F.Fab'))\n        m.append(Text(type='value', text=dim.name, at=[dim.label_centre_x_mm, dim.label_centre_y_mm], layer='F.Fab'))\n        return m\n\n\n    def draw_tab(self, m, dim):\n        right_x = dim.device_offset_x_mm\n        left_x = right_x - dim.tab_project_x_mm\n        top_y = -dim.tab_offset_y_mm\n        bottom_y = -top_y\n        tab_outline = [[left_x, top_y], [right_x, top_y], [right_x, bottom_y], [left_x, bottom_y]]\n        m.append(PolygoneLine(polygone=tab_outline, layer='F.Fab', width=dim.fab_line_width_mm))\n        return m\n\n\n    def draw_body(self, m, dim):\n        right_x = dim.device_offset_x_mm - dim.tab_project_x_mm\n        left_x = right_x - dim.body_x_mm\n        top_y = -dim.body_offset_y_mm\n        bottom_y = -top_y\n        body_outline = [[right_x, top_y], [right_x, bottom_y], [left_x, bottom_y],\\\n                        [left_x, top_y + dim.corner_mm], [left_x + dim.corner_mm, top_y], [right_x, top_y]]\n        m.append(PolygoneLine(polygone=body_outline, layer='F.Fab', width=dim.fab_line_width_mm))\n        return m\n\n\n    def draw_pins(self, m, variant, dim, cut_pin):\n        right_x = dim.device_offset_x_mm - dim.tab_project_x_mm - dim.body_x_mm\n        left_x = right_x - variant['pin']['x_mm']\n        pin_1_top_y = dim.pad_1_centre_y_mm - (variant['pin']['y_mm'] / 2.0)\n        body_corner_bottom_y = -dim.body_offset_y_mm + dim.corner_mm\n        pin_1_extend = (body_corner_bottom_y - pin_1_top_y) if (pin_1_top_y < body_corner_bottom_y) else 0.0\n        for pin in range(1, variant['pins'] + 1):\n            if not (pin == dim.centre_pin and cut_pin):\n                top_y = dim.pad_1_centre_y_mm + ((pin - 1) * variant['pitch_mm']) - (variant['pin']['y_mm'] / 2.0)\n                bottom_y = dim.pad_1_centre_y_mm + ((pin - 1) * variant['pitch_mm']) + (variant['pin']['y_mm'] / 2.0)\n                pin_outline = [[right_x + (pin_1_extend if pin == 1 else 0), top_y],\n                               [left_x , top_y], [left_x, bottom_y], [right_x, bottom_y]]\n                m.append(PolygoneLine(polygone=pin_outline, layer='F.Fab', width=dim.fab_line_width_mm))\n        return m\n\n\n    def draw_outline(self, m, variant, dim, cut_pin=False):\n        m = self.draw_tab(m, dim)\n        m = self.draw_body(m, dim)\n        m = self.draw_pins(m, variant, dim, cut_pin)\n        return m\n\n\n    def draw_markers(self, m, variant, dim):\n        magic_number = 1.3  # TODO needs better name\n        other_magic_number = 1.5  #  TODO needs better name\n        right_x = dim.device_offset_x_mm - dim.tab_project_x_mm - dim.body_x_mm + magic_number\n        middle_x = dim.device_offset_x_mm - dim.tab_project_x_mm - dim.body_x_mm - dim.silk_line_nudge_mm\n        left_x = dim.pad_1_centre_x_mm - variant['pad']['x_mm'] / 2.0\n        top_y = -dim.body_offset_y_mm - dim.silk_line_nudge_mm\n        bottom_y = dim.pad_1_centre_y_mm - variant['pad']['y_mm'] / 2.0 - other_magic_number * dim.silk_line_nudge_mm\n        top_marker = [[right_x, top_y], [middle_x, top_y], [middle_x, bottom_y], [left_x, bottom_y]]\n        m.append(PolygoneLine(polygone=top_marker, layer='F.SilkS', width=dim.silk_line_width_mm))\n        top_y = -top_y\n        bottom_y = -bottom_y\n        left_x = dim.device_offset_x_mm - dim.tab_project_x_mm - dim.body_x_mm - magic_number\n        bottom_marker = [[right_x, top_y], [middle_x, top_y], [middle_x, bottom_y], [left_x, bottom_y]]\n        m.append(PolygoneLine(polygone=bottom_marker, layer='F.SilkS', width=dim.silk_line_width_mm))\n        return m\n\n\n    def draw_pads(self, m, base, variant, dim, cut_pin):\n        for pin in range(1, variant['pins'] + 1):\n            if not (pin == dim.centre_pin and cut_pin):\n                m.append(Pad(number=pin, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                                     at=[dim.pad_1_centre_x_mm, dim.pad_1_centre_y_mm + (pin - 1) * variant['pitch_mm']],\n                                     size=[variant['pad']['x_mm'], variant['pad']['y_mm']],\n                                     layers=Pad.LAYERS_SMT))\n        tab_layers = Pad.LAYERS_SMT[:]\n        if dim.split_paste:\n            tab_layers.remove('F.Paste')\n        paste_layers = Pad.LAYERS_SMT[:]\n        paste_layers.remove('F.Mask')\n        m.append(Pad(number=dim.tab_pin_number, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                             at=[dim.tab_centre_x_mm, dim.tab_centre_y_mm],\n                             size=[base['footprint']['tab']['x_mm'], base['footprint']['tab']['y_mm']],\n                             layers=tab_layers))\n        if dim.split_paste:\n            gutter = base['footprint']['paste_gutter_mm']\n            paste_x_mm = (base['footprint']['tab']['x_mm'] - gutter) / 2.0\n            paste_y_mm = (base['footprint']['tab']['y_mm'] - gutter) / 2.0\n            paste_offset_x = (paste_x_mm + gutter) / 2.0\n            paste_offset_y = (paste_y_mm + gutter) / 2.0\n            left_x = dim.tab_centre_x_mm - paste_offset_x\n            right_x = dim.tab_centre_x_mm + paste_offset_x\n            top_y = dim.tab_centre_y_mm - paste_offset_y\n            bottom_y = dim.tab_centre_y_mm + paste_offset_y\n            for pad_xy in [[right_x, bottom_y], [left_x, top_y], [right_x, top_y], [left_x, bottom_y]]:\n                m.append(Pad(number=dim.tab_pin_number, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                                     at=pad_xy, size=[paste_x_mm, paste_y_mm], layers=paste_layers))\n        return m\n\n\n    def add_3D_model(self, m, base, dim):\n        m.append(\n            Model(filename=\"{p:s}/{n:s}.wrl\".format(p=base['3d_prefix'], n=dim.name), at=[0, 0, 0], scale=[1, 1, 1],\n                  rotate=[0, 0, 0]))\n        return m\n\n\n    def draw_courtyard(self, m ,dim):\n        m.append(RectLine(start=[-dim.courtyard_offset_x_mm, -dim.courtyard_offset_y_mm],\n                                  end=[dim.courtyard_offset_x_mm, dim.courtyard_offset_y_mm], layer='F.CrtYd',\n                                  width=dim.courtyard_line_width_mm))\n        return m\n\n\n    def build_footprint(self, base, variant, cut_pin=False, tab_linked=False, verbose=False):\n\n        # calculate dimensions and other attributes specific to this variant\n        dim = Dimensions(base, variant, cut_pin, tab_linked)\n\n        # initialise footprint\n        kicad_mod = Footprint(dim.name)\n        kicad_mod = self.add_properties(kicad_mod, variant)\n        kicad_mod = self.add_labels(kicad_mod, variant, dim)\n\n        # create pads\n        kicad_mod = self.draw_pads(kicad_mod, base, variant, dim, cut_pin)\n\n        # create fab outline\n        kicad_mod = self.draw_outline(kicad_mod, variant, dim, cut_pin)\n\n        # create silkscreen marks and pin 1 marker\n        kicad_mod = self.draw_markers(kicad_mod, variant, dim)\n\n        # create courtyard\n        kicad_mod = self.draw_courtyard(kicad_mod, dim)\n\n        # add 3D model\n        kicad_mod = self.add_3D_model(kicad_mod, base, dim)\n\n        # print render tree\n        if verbose:\n            print(kicad_mod.getRenderTree())\n\n        # write file\n        file_handler = KicadFileHandler(kicad_mod)\n        file_handler.writeFile('{:s}.kicad_mod'.format(dim.name))\n\n\n    def build_series(self, verbose=False):\n        print('Building {p:s}'.format(p=self.config['base']['description']))\n        base = self.config['base']\n        for variant in self.config['variants']:\n            if 'uncut' in variant['centre_pin']:\n                self.build_footprint(base, variant, verbose=verbose)\n                self.build_footprint(base, variant, tab_linked=True, verbose=verbose)\n            if 'cut' in variant['centre_pin']:\n                self.build_footprint(base, variant, cut_pin=True, verbose=verbose)\n\n\nclass TO252(DPAK):\n\n    def __init__(self, config_file):\n        self.SERIES = 'TO-252'\n        self.config = self.load_config(config_file)\n\n\nclass TO263(DPAK):\n\n    def __init__(self, config_file):\n        self.SERIES = 'TO-263'\n        self.config = self.load_config(config_file)\n\n\nclass TO268(DPAK):\n\n    def __init__(self, config_file):\n        self.SERIES = 'TO-268'\n        self.config = self.load_config(config_file)\n\nclass ATPAK(DPAK):\n\n    def __init__(self, config_file):\n        self.SERIES = 'ATPAK'\n        self.config = self.load_config(config_file)\n"
  },
  {
    "path": "scripts/Packages/TO_SOT_Packages_SMD/DPAK_README.md",
    "content": "# DPAK footprint generator\n\nProgram to generate KiCad footprints using KicadModTree from https://github.com/pointhi/kicad-footprint-generator\n\nDevices included:\n- TO252 / DPAK\n- TO263 / D2PAK / DDPAK\n- TO268 / D3PAK\n- ATPAK\n\n## Usage\n\nDownload `kicad-footprint-generator` from https://github.com/pointhi/kicad-footprint-generator\n\nInstall the following files in the folder `.../kicad-footprint-generator/scripts/<category>/`.\n\n```\nDPAK.py\nDPAK_config.yaml\nmake_DPAK.py\n```\n\nTo generate the footprints, run one of the following commands:\n\n```\n$ python3 ./make_DPAK.py         # builds all device types\n$ python3 ./make_DPAK.py <type>  # builds specified type only, where type is one of TO252, TO263, TO268 or ATPAK\n```\n\n## Configuration\n\nThe program `make_DPAK.py` uses classes in `DPAK.py` to build the models.  Design parameters for each device type and its variants (for example, number of pins, whether centre pin is cut) are contained in `DPAK_config.yaml`.\n\nThe configuration for each device type is a separate YAML document in the configuration file (separated by `---`).  The document for each type is broken into a `base:` section (values that apply to all devices in the family) and a `variants:` section with separate entries for each individual device.\n\n*The configuration file is shared with the 3D model generator program.  Configuration items required for the 3D models are marked with `# 3D` in the descriptions below.*\n\n### `base:` configuration\n\n```\nseries: TO-252                   # 3D\n```\n\nThe package name is included in the names of the module files generated by the program. It can also be passed as a command line argument to limit which devices are generated.\n\n```\ndescription: 'TO-252 / DPAK SMD package'\nkeywords: 'DPAK TO-252'\n```\n\nThese strings are combined with the device-specific description and keywords (see below) and are included in the module file.\n\n```\nfootprint:\n    x_mm: 10.6\n```\n\nThe next part of the configuration file is about the footprint (i.e. the land pattern of copper pads). `x_mm` is the overall size of the footprint: the X distance between the left hand edge of the pin pads and the right hand edge of the tab pads.\n\n```\ntab:\n    x_mm: 6.4\n    y_mm: 5.8\n```\n\nThis defines the size of the tab pad.\n\n```\nsplit_paste: 'on'\npaste_gutter_mm: 0.3\n```\n\nIf `split_paste` is `on`, the paste mask for the tab will be divided into four parts with a gap (gutter) between them.\n\n```\ndevice:\n    x_mm: 9.9                    # 3D\n```\n\nThe next part of the configuration file is about the phyical device that sits on the footprint. `x_mm` is the overall size of the device: the X distance between the end of the pins and the right hand edge of the tab.\n\n```\nbody:\n    x_mm: 6.22                   # 3D\n    y_mm: 6.5                    # 3D\n    z_mm: 2.3                    # 3D\n    waist_z_mm: 1.2              # 3D\n    marker_offset_x_mm: -1.5     # 3D\n    colour: 'black body'         # 3D\ntab:\n    x_mm: 1.0                    # 3D\n    y_mm: 5.4                    # 3D\n    z_mm: 1.0                    # 3D\n    project_x_mm: 1.0            # 3D\n    colour: 'metal grey pins'    # 3D\n```\n\nThese define the size of the body and tab. Tab `x_mm` includes the part of the tab under the body. `project_x_mm` is the part of the tab that projects outside the body.\n\n```\nmarker:\n    x_mm: 1.5                    # 3D\n    z_mm: 0.1                    # 3D\n```\n\nThese define the diameter and depth of the marker on top of the body.\n\n```\npins:\n    colour: 'metal grey pins'    # 3D\n```\n\nUsed for the 3D model. See below for configuration data for the pins on each variant.\n\n```\n3d_prefix: '${KISYS3DMOD}/TO_SOT_Packages_SMD.3dshapes'\n```\n\nThis string is added to the module to set the path to the 3D models folder.\n\n\n### `variants:` configuration\n\nThe variants section contains a list of one or more device definitions.\n\n```\n- pins: 3                        # 3D\n  pitch_mm: 2.28                 # 3D\n```\n\nThe `-` character starts the device definition. The first two settings are the number of pins and the pitch (Y distance between them).\n\n```\n  pad:\n      x_mm: 2.2\n      y_mm: 1.2\n  pin:\n      x_mm: 2.7\n      y_mm: 0.75                 # 3D\n      z_mm: 0.5                  # 3D\n      cut_x_mm: 0.8              # 3D\n```\n\nThese define the size of the pads and pins.  The pin `x_mm` is the X distance from the end of an uncut pin to the device body, while `cut_x_mm` is the equivalent for a cut pin.\n\n```\n   centre_pin: ['cut', 'uncut']  # 3D\n```\n\nThis parameter contains either one or both of `'cut'` or '`uncut`'. If both are present, the program will generate two modules, one with a pad for the centre pin and one without.  If just one is present, only one module will be generated.\n\n```\n  keywords: 'DPAK-3 TO-252-3 SOT-428'\n  datasheet: http://www.infineon.com/cms/en/product/packages/PG-TO252/PG-TO252-3-1/\n```\n\nThese strings are added to the base-level description and keywords (see above) and are included in the module.\n\n"
  },
  {
    "path": "scripts/Packages/TO_SOT_Packages_SMD/DPAK_config.yaml",
    "content": "# TO-252/DPAK SMD packages\nbase:\n    series: TO-252                                                   \n    description: 'TO-252/DPAK SMD package'\n    keywords: 'DPAK TO-252'\n    footprint:\n        x_mm: 10.6\n        tab:\n            x_mm: 6.4\n            y_mm: 5.8\n        split_paste: 'on'\n        paste_gutter_mm: 0.3\n    device:\n        x_mm: 9.9                                                    \n        body:\n            x_mm: 6.22                                               \n            y_mm: 6.5\n            z_mm: 2.3                                                \n            waist_z_mm: 0.9                                          \n            marker_offset_x_mm: -1.5                                 \n            colour: 'black body'                                     \n        tab:\n            x_mm: 5.24                                               \n            y_mm: 5.4\n            z_mm: 0.5                                                \n            project_x_mm: 1.0\n            colour: 'metal grey pins'                                \n        marker:\n            x_mm: 1.0                                                \n            z_mm: 0.1                                                \n        pins:\n            colour: 'metal grey pins'                                \n    3d_prefix: '${KISYS3DMOD}/TO_SOT_Packages_SMD.3dshapes'\nvariants:\n    - pins: 3                                                        \n      pitch_mm: 2.28\n      pad:\n          x_mm: 2.2\n          y_mm: 1.2\n      pin:\n          x_mm: 2.7\n          y_mm: 0.75\n          z_mm: 0.5                                                  \n      centre_pin: ['cut', 'uncut']\n      keywords: 'DPAK-3 TO-252-3 SOT-428'\n      datasheet: http://www.infineon.com/cms/en/product/packages/PG-TO252/PG-TO252-3-1/\n    - pins: 5                                                        \n      pitch_mm: 1.14\n      pad:\n          x_mm: 2.2\n          y_mm: 0.8\n      pin:\n          x_mm: 2.7\n          y_mm: 0.6\n          z_mm: 0.5                                                  \n      centre_pin: ['cut', 'uncut']\n      keywords: 'DPAK-5 TO-252-5'\n      datasheet: http://www.infineon.com/cms/en/product/packages/PG-TO252/PG-TO252-5-11/\n---\n# TO-263/D2PAK SMD packages\nbase:\n    series: TO-263                                                   \n    description: 'TO-263/D2PAK/DDPAK SMD package'\n    keywords: 'D2PAK DDPAK TO-263'\n    footprint:\n        x_mm: 16.15\n        tab:\n            x_mm: 9.4\n            y_mm: 10.8\n        split_paste: 'on'\n        paste_gutter_mm: 0.3\n    device:\n        x_mm: 15.0\n        body:\n            x_mm: 9.25\n            y_mm: 10.0\n            z_mm: 4.4                                                 \n            waist_z_mm: 2.4                                           \n            marker_offset_x_mm: 0.0                                  \n            colour: 'black body'                                     \n        tab:\n            x_mm: 7.55                                                \n            y_mm: 10.0\n            z_mm: 1.27                                                \n            project_x_mm: 1.0\n            colour: 'metal grey pins'                                \n        marker:\n            x_mm: 2.5                                                 \n            z_mm: 0.1                                                 \n        pins:\n            colour: 'metal grey pins'                                \n    3d_prefix: '${KISYS3DMOD}/TO_SOT_Packages_SMD.3dshapes'\nvariants:\n    - pins: 3                                                        \n      pitch_mm: 2.54\n      pad:\n          x_mm: 4.6\n          y_mm: 1.1\n      pin:\n          x_mm: 4.7\n          y_mm: 1.0\n          z_mm: 0.5                                                   \n      centre_pin: ['cut', 'uncut']\n      keywords: 'D2PAK-3 TO-263-3 SOT-404'\n      datasheet: http://www.infineon.com/cms/en/product/packages/PG-TO263/PG-TO263-3-1/\n    - pins: 5                                                        \n      pitch_mm: 1.7\n      pad:\n          x_mm: 4.6\n          y_mm: 1.1\n      pin:\n          x_mm: 4.7\n          y_mm: 0.8\n          z_mm: 0.5                                                   \n      centre_pin: ['cut', 'uncut']\n      keywords: 'D2PAK-5 TO-263-5 SOT-426'\n      datasheet: http://www.infineon.com/cms/en/product/packages/PG-TO263/PG-TO263-5-1/\n    - pins: 7\n      pitch_mm: 1.27\n      pad:\n          x_mm: 4.6\n          y_mm: 0.8\n      pin:\n          x_mm: 4.7\n          y_mm: 0.6\n          z_mm: 0.5                                                   \n      centre_pin: ['cut', 'uncut']\n      keywords: 'D2PAK-7 TO-263-7 SOT-427'\n      datasheet: http://www.infineon.com/cms/en/product/packages/PG-TO263/PG-TO263-7-1/\n---\n# TO-268/D3PAK SMD packages\nbase:\n    series: TO-268                                                   \n    description: 'TO-268/D3PAK SMD package'\n    keywords: 'D3PAK TO-268'\n    footprint:\n        x_mm: 21.95\n        tab:\n            x_mm: 13.5\n            y_mm: 16.6\n        split_paste: 'on'\n        paste_gutter_mm: 0.3\n    device:\n        x_mm: 19.0\n        body:\n            x_mm: 14.0\n            y_mm: 15.9\n            z_mm: 5.0                                                 \n            waist_z_mm: 2.8                                           \n            marker_offset_x_mm: -1.0                                  \n            colour: 'black body'                                     \n        tab:\n            x_mm: 12.5                                                \n            y_mm: 15.9\n            z_mm: 1.5                                                 \n            project_x_mm: 1.0\n            colour: 'metal grey pins'                                \n        marker:\n            x_mm: 2.5                                                 \n            z_mm: 0.1                                                 \n        pins:\n            colour: 'metal grey pins'                                \n    3d_prefix: '${KISYS3DMOD}/TO_SOT_Packages_SMD.3dshapes'\nvariants:\n    - pins: 3                                                        \n      pitch_mm: 5.45\n      pad:\n          x_mm: 5.0\n          y_mm: 3.0\n      pin:\n          x_mm: 3.9\n          y_mm: 1.3\n          z_mm: 0.5                                                  \n      centre_pin: ['cut']\n      keywords: 'D3PAK-3 TO-268-3'\n      datasheet: http://www.icbank.com/icbank_data/semi_package/to268aa_dim.pdf\n---\n# ATPAK SMD packages\nbase:\n    series: ATPAK                                                   \n    description: 'ATPAK SMD package'\n    keywords: 'ATPAK'\n    footprint:\n        x_mm: 10.3\n        tab:\n            x_mm: 6.7\n            y_mm: 6.5\n        split_paste: 'on'\n        paste_gutter_mm: 0.3\n    device:\n        x_mm: 9.5\n        body:\n            x_mm: 7.3\n            y_mm: 6.5\n            z_mm: 1.5                                                 \n            waist_z_mm: 0.4                                           \n            marker_offset_x_mm: 2.0                                  \n            colour: 'black body'                                     \n        tab:\n            x_mm: 6.05                                             \n            y_mm: 6.5\n            z_mm: 0.4                                                \n            project_x_mm: 0.5\n            colour: 'metal grey pins'                                \n        marker:\n            x_mm: 1.0                                                 \n            z_mm: 0.1                                                 \n        pins:\n            colour: 'metal grey pins'                                \n    3d_prefix: '${KISYS3DMOD}/TO_SOT_Packages_SMD.3dshapes'\nvariants:\n    - pins: 3                                                        \n      pitch_mm: 2.3\n      pad:\n          x_mm: 1.6\n          y_mm: 1.5\n      pin:\n          x_mm: 1.7\n          y_mm: 0.6\n          z_mm: 0.4                                                   \n      centre_pin: ['cut']\n      keywords: ''\n      datasheet: http://www.onsemi.com/pub/Collateral/ENA2192-D.PDF\n\n"
  },
  {
    "path": "scripts/Packages/TO_SOT_Packages_SMD/make_DPAK.py",
    "content": "#!/usr/bin/env python\n\n# KicadModTree is free software: you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# KicadModTree is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n#\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\n\nimport sys\nimport os\nimport argparse\nimport yaml\nimport pprint\n\nsys.path.append(os.path.join(sys.path[0], \"../../..\"))  # enable package import from parent directory\n\nfrom KicadModTree import *  # NOQA\n\n\ndef get_args():\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--family', help='device type to build: TO-252 | TO-263 | TO-268  (default is all)',\n                        type=str, nargs=1)\n    parser.add_argument('-v', '--verbose', help='show extra information while generating the footprint',\n                        action='store_true')\n    return parser.parse_args()\n\n\nif __name__ == '__main__':\n\n    print('Building DPAK')\n\n    args = get_args()\n\n    print('Rebuilding DPAK')\n\n    from DPAK import DPAK, TO252, TO263, TO268, ATPAK\n\n    CONFIG = 'DPAK_config.yaml'\n\n    if args.family:\n        if args.family[0] == 'TO252':\n            build_list = [TO252(CONFIG)]\n        elif args.family[0] == 'TO263':\n            build_list = [TO263(CONFIG)]\n        elif args.family[0] == 'TO268':\n            build_list = [TO268(CONFIG)]\n        elif args.family[0] == 'ATPAK':\n            build_list = [ATPAK(CONFIG)]\n        else:\n            print('ERROR: family not recognised')\n            build_list = []\n    else:\n        build_list = [TO252(CONFIG), TO263(CONFIG), TO268(CONFIG), ATPAK(CONFIG)]\n\n    for package in build_list:\n        package.build_series(verbose=args.verbose)\n"
  },
  {
    "path": "scripts/Packages/TO_SOT_THT/TO_SOT_THT_generate.py",
    "content": "#usr/bin/env python\n\nimport sys\nimport os\nimport math\nimport time\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"..\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom tools import *\nfrom TO_THT_packages import *\n\n\n# vertical symbols for rectangular transistors\ndef makeVERT(lib_name, pck, has3d=False, x_3d=[0, 0, 0], s_3d=[1,1,1], lptext=\"_LargePads\", r_3d=[0, 0, 0]):\n    padsize=pck.pad\n    l_fabp = -pck.pin_offset_x\n    t_fabp = -pck.pin_offset_z\n    if pck.staggered_type >0:\n        t_fabp=-pck.staggered_pin_offset_z\n\n    w_fabp = pck.plastic[0]\n    h_fabp = pck.plastic[2]\n\n    w_fabm = pck.metal[0]\n    h_fabm = pck.metal[2]\n\n    l_slkp = l_fabp - slk_offset\n    t_slkp = t_fabp - slk_offset\n    w_slkp = w_fabp + 2 * slk_offset\n    h_slkp = h_fabp + 2 * slk_offset\n    w_slkm = w_fabm + 2 * slk_offset\n    h_slkm = h_fabm + 2 * slk_offset\n\n    l_mounth = l_fabp + pck.mounting_hole_pos[0]\n\n    txt_x = l_slkp + max(w_slkp, w_slkm) / 2\n\n    # calculate pad positions\n    pads=[]\n    yshift=0\n    y1=0\n    y2=0\n    maxpiny=0\n    if pck.staggered_type == 1:\n        y1 = pck.staggered_rm[0]\n        yshift = -pck.staggered_rm[0]\n        y2 = 0\n        maxpiny = pck.staggered_rm[0]\n        if len(pck.staggered_pad)>0:\n            padsize=pck.staggered_pad\n    elif pck.staggered_type == 2:\n        y1 = 0\n        yshift = 0\n        y2=pck.staggered_rm[0]\n        maxpiny = pck.staggered_rm[0]\n        if len(pck.staggered_pad) > 0:\n            padsize = pck.staggered_pad\n\n    pinwid = (pck.pins - 1) * pck.rm\n    if len(pck.rm_list) > 0:\n        pinwid = 0\n        for rm in pck.rm_list:\n            pinwid = pinwid + rm\n\n    l_crt = min(-padsize[0] / 2, l_fabp) - crt_offset\n    t_crt = min(-padsize[1] / 2, t_fabp) - crt_offset\n    w_crt = max(max(w_fabp, w_fabm), pinwid + padsize[0]) + 2 * crt_offset\n    h_crt = max(t_fabp+max(h_fabp, h_fabm)+ crt_offset-t_crt, -t_crt + maxpiny + padsize[1] / 2 + crt_offset)\n\n    y=y1\n    x = 0\n    for p in range(1, pck.pins + 1):\n        if (p % 2) == 1:\n            y = y1\n        else:\n            y = y2\n        pads.append([x, y])\n        if len(pck.rm_list)>0 and p<=len(pck.rm_list):\n            x = x + pck.rm_list[p-1]\n        else:\n            x = x + pck.rm\n\n\n    tag_items = [\"Vertical\", \"RM {0}mm\".format(pck.rm)]\n\n    footprint_name = pck.name\n    for t in pck.more_packnames:\n        footprint_name = footprint_name + \"_\" + t\n    footprint_name = footprint_name + \"_Vertical\"\n    for t in pck.fpnametags:\n        footprint_name = footprint_name + \"_\" + t\n    if pck.staggered_type>0:\n        footprint_name = footprint_name + \"_Py{0}mm\".format(pck.staggered_rm[0],3)\n    if pck.largepads:\n        tag_items.append(\"large Pads\")\n        footprint_name = footprint_name + lptext\n\n    print(footprint_name)\n\n    description = pck.name\n    tags = pck.name\n    for t in tag_items:\n        description = description + \", \" + t\n        tags = tags + \" \" + t\n    for t in pck.tags:\n        description = description + \", \" + t\n        tags = tags + \" \" + t\n    if len(pck.webpage)>0:\n        description = description + \", see \" + pck.webpage\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n\n    kicad_modt = Translation(0, yshift)\n    kicad_mod.append(kicad_modt)\n\n    # set general values\n    kicad_modt.append(Text(type='reference', text='REF**', at=[txt_x, t_slkp - txt_offset], layer='F.SilkS'))\n    kicad_modt.append(Text(type='user', text='%R', at=[txt_x, t_slkp - txt_offset], layer='F.Fab'))\n    kicad_modt.append(\n        Text(type='value', text=footprint_name, at=[txt_x, t_slkp + max(h_slkm, h_slkp, -t_slkp+h_crt+t_crt) + txt_offset], layer='F.Fab'))\n\n    # create FAB-layer\n    kicad_modt.append(\n        RectLine(start=[l_fabp, t_fabp], end=[l_fabp + w_fabp, t_fabp + h_fabp], layer='F.Fab', width=lw_fab))\n    if (pck.metal[2] > 0):\n        kicad_modt.append(\n            Line(start=[l_fabp, t_fabp + h_fabm], end=[l_fabp + w_fabp, t_fabp + h_fabm], layer='F.Fab', width=lw_fab))\n        if pck.mounting_hole_diameter > 0:\n            kicad_modt.append(Line(start=[l_mounth - pck.mounting_hole_diameter / 2, t_fabp],\n                                  end=[l_mounth - pck.mounting_hole_diameter / 2, t_fabp + h_fabm], layer='F.Fab',\n                                  width=lw_fab))\n            kicad_modt.append(Line(start=[l_mounth + pck.mounting_hole_diameter / 2, t_fabp],\n                                  end=[l_mounth + pck.mounting_hole_diameter / 2, t_fabp + h_fabm], layer='F.Fab',\n                                  width=lw_fab))\n    else:\n        if pck.mounting_hole_diameter > 0:\n            kicad_modt.append(Line(start=[l_mounth - pck.mounting_hole_diameter / 2, t_fabp],\n                                  end=[l_mounth - pck.mounting_hole_diameter / 2, t_fabp + h_fabp], layer='F.Fab',\n                                  width=lw_fab))\n            kicad_modt.append(Line(start=[l_mounth + pck.mounting_hole_diameter / 2, t_fabp],\n                                  end=[l_mounth + pck.mounting_hole_diameter / 2, t_fabp + h_fabp], layer='F.Fab',\n                                  width=lw_fab))\n    for p in range(0, len(pads)):\n        yl1=t_fabp + h_fabp\n        yl2=pads[p][1]\n        if yl2>yl1:\n            kicad_modt.append(Line(start=[pads[p][0], yl1], end=[pads[p][0], yl2], layer='F.Fab', width=lw_fab))\n\n    # create SILKSCREEN-layer\n    keepouts = []\n    for p in range(0,len(pads)):\n        if p==0:\n            keepouts=keepouts+addKeepoutRect(pads[p][0],pads[p][1],padsize[0]+2*slk_dist,padsize[1]+2*slk_dist)\n        else:\n            keepouts=keepouts+addKeepoutRound(pads[p][0],pads[p][1],padsize[0]+2*slk_dist,padsize[1]+2*slk_dist)\n\n    #for ko in keepouts:\n    #    kicad_modt.append(\n    #        RectLine(start=[ko[0],ko[2]], end=[ko[1],ko[3]], layer='B.Fab', width=lw_fab))\n\n    addHLineWithKeepout(kicad_modt, l_slkp, l_slkp + w_slkp, t_slkp, 'F.SilkS', lw_slk, keepouts)\n    addHLineWithKeepout(kicad_modt, l_slkp, l_slkp + w_slkp, t_slkp + h_slkp, 'F.SilkS', lw_slk, keepouts)\n    addVLineWithKeepout(kicad_modt, l_slkp, t_slkp, t_slkp + h_slkp, 'F.SilkS', lw_slk, keepouts)\n    addVLineWithKeepout(kicad_modt, l_slkp + w_slkp, t_slkp, t_slkp + h_slkp, 'F.SilkS', lw_slk, keepouts)\n    if (pck.metal[2] > 0):\n        addHLineWithKeepout(kicad_modt, l_slkp, l_slkp + w_slkp, t_slkp + h_slkm, 'F.SilkS', lw_slk, keepouts)\n        if pck.mounting_hole_diameter > 0:\n            addVLineWithKeepout(kicad_modt, l_mounth - pck.mounting_hole_diameter / 2, t_slkp, t_slkp + h_slkm,\n                                'F.SilkS', lw_slk, keepouts)\n            addVLineWithKeepout(kicad_modt, l_mounth + pck.mounting_hole_diameter / 2, t_slkp, t_slkp + h_slkm,\n                                'F.SilkS', lw_slk, keepouts)\n    else:\n        if pck.mounting_hole_diameter > 0:\n            addVLineWithKeepout(kicad_modt, l_mounth - pck.mounting_hole_diameter / 2, t_slkp, t_slkp + h_slkp,\n                                'F.SilkS', lw_slk, keepouts)\n            addVLineWithKeepout(kicad_modt, l_mounth + pck.mounting_hole_diameter / 2, t_slkp, t_slkp + h_slkp,\n                                'F.SilkS', lw_slk, keepouts)\n    for p in range(0, len(pads)):\n        yl1 = t_slkp + h_slkp\n        yl2 = pads[p][1]\n        if yl2>yl1:\n            addVLineWithKeepout(kicad_modt,pads[p][0], yl1, yl2, 'F.SilkS', lw_slk, keepouts)\n\n    # create courtyard\n    kicad_mod.append(\n        RectLine(start=[roundCrt(l_crt), roundCrt(t_crt+yshift)], end=[roundCrt(l_crt + w_crt), roundCrt(t_crt + h_crt+yshift)],\n                 layer='F.CrtYd', width=lw_crt))\n\n    # create pads\n    for p in range(0,len(pads)):\n        if p==0:\n            kicad_modt.append(\n                Pad(number=p+1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=pads[p], size=padsize, drill=pck.drill,\n                    layers=['*.Cu', '*.Mask']))\n        else:\n            kicad_modt.append(\n                Pad(number=p+1, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=pads[p], size=padsize, drill=pck.drill,\n                    layers=['*.Cu', '*.Mask']))\n\n\n    # add model\n    if (has3d):\n        kicad_modt.append(\n            Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=r_3d))\n\n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(footprint_name + '.kicad_mod')\n\n\n\n# horizontal symbols for rectangular transistors\ndef makeHOR(lib_name, pck, has3d=False, x_3d=[0, 0, 0], s_3d=[1,1,1], lptext=\"_LargePads\", r_3d=[0, 0, 0]):\n    padsize = pck.pad\n    l_fabp = -pck.pin_offset_x\n    t_fabp = -pck.pin_minlength\n    if pck.staggered_type >0:\n        t_fabp=-pck.staggered_pin_minlength\n    w_fabp = pck.plastic[0]\n    h_fabp = pck.plastic[1]\n\n    w_fabm = pck.metal[0]\n    h_fabm = pck.metal[1]\n\n    l_mounth = l_fabp + pck.mounting_hole_pos[0]\n    t_mounth = t_fabp - pck.mounting_hole_pos[1]\n\n    # calculate pad positions\n    pads = []\n    yshift = 0\n    y1 = 0\n    y2 = 0\n    maxpiny = 0\n    if pck.staggered_type == 1:\n        y1 = pck.staggered_rm[1]\n        yshift = -pck.staggered_rm[1]\n        y2 = 0\n        maxpiny = pck.staggered_rm[1]\n        if len(pck.staggered_pad) > 0:\n            padsize = pck.staggered_pad\n    elif pck.staggered_type == 2:\n        y1 = 0\n        yshift = 0\n        y2 = pck.staggered_rm[1]\n        maxpiny = pck.staggered_rm[1]\n        if len(pck.staggered_pad) > 0:\n            padsize = pck.staggered_pad\n\n    y=y1\n    x = 0\n    for p in range(1, pck.pins + 1):\n        if (p % 2) == 1:\n            y = y1\n        else:\n            y = y2\n        pads.append([x, y])\n        if len(pck.rm_list)>0 and p<=len(pck.rm_list):\n            x = x + pck.rm_list[p-1]\n        else:\n            x = x + pck.rm\n\n    pinwid = (pck.pins - 1) * pck.rm\n    if len(pck.rm_list) > 0:\n        pinwid = 0\n        for rm in pck.rm_list:\n            pinwid = pinwid + rm\n\n    l_slkp = l_fabp - slk_offset\n    t_slkp = t_fabp + slk_offset\n    w_slkp = w_fabp + 2 * slk_offset\n    h_slkp = h_fabp + 2 * slk_offset\n    w_slkm = w_fabm + 2 * slk_offset\n    h_slkm = h_fabm + 2 * slk_offset\n    addpad = 0\n    l_crt = min(-padsize[0] / 2, l_fabp) - crt_offset\n    t_crt = t_fabp - max(h_fabp, h_fabm) - crt_offset\n    h_crt = (-t_crt + maxpiny+padsize[1] / 2) + crt_offset\n    if len(pck.additional_pin_pad_size) > 0:\n        h_crt = h_crt + (pck.additional_pin_pad[1] + pck.additional_pin_pad_size[1] / 2 - h_fabm)\n        t_crt = t_crt - (pck.additional_pin_pad[1] + pck.additional_pin_pad_size[1] / 2 - h_fabm)\n        addpad = pck.additional_pin_pad_size[0]\n        addpadx = l_fabp + pck.additional_pin_pad[0]\n        addpady = t_fabp - pck.additional_pin_pad[1]\n    w_crt = max(max(max(w_fabp, w_fabm), pinwid + padsize[0]), addpad) + 2 * crt_offset\n\n\n    txt_x = l_slkp + max(w_slkp, w_slkm) / 2\n    txt_t = (t_slkp - max(h_slkm, h_slkp)) - txt_offset\n    txt_b = maxpiny+padsize[1] / 2 + txt_offset\n    if len(pck.additional_pin_pad_size) > 0:\n        txt_t = txt_t - (pck.additional_pin_pad[1] + pck.additional_pin_pad_size[1] / 2 - h_fabm)\n    tag_items = [\"Horizontal\", \"RM {0}mm\".format(pck.rm)]\n\n    footprint_name = pck.name\n    if len(pck.additional_pin_pad_size) > 0:\n        footprint_name = footprint_name + \"-1EP\"\n    for t in pck.more_packnames:\n        footprint_name = footprint_name + \"_\" + t\n    footprint_name = footprint_name + \"_Horizontal_TabDown\"\n    for t in pck.fpnametags:\n        footprint_name = footprint_name + \"_\" + t\n\n    if pck.staggered_type>0:\n        footprint_name = footprint_name + \"_Py{0}mm\".format(pck.staggered_rm[1],3)\n\n    if pck.largepads:\n        tag_items.append(\"large Pads\")\n        footprint_name = footprint_name + lptext\n    print(footprint_name)\n\n    description = pck.name\n    tags = pck.name\n    for t in tag_items:\n        description = description + \", \" + t\n        tags = tags + \" \" + t\n    for t in pck.tags:\n        description = description + \", \" + t\n        tags = tags + \" \" + t\n    if len(pck.webpage)>0:\n        description = description + \", see \" + pck.webpage\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n\n    kicad_modt = Translation(0, yshift)\n    kicad_mod.append(kicad_modt)\n\n    # set general values\n    kicad_modt.append(Text(type='reference', text='REF**', at=[txt_x, txt_t], layer='F.SilkS'))\n    kicad_modt.append(Text(type='user', text='%R', at=[txt_x, txt_t], layer='F.Fab'))\n    kicad_modt.append(Text(type='value', text=footprint_name, at=[txt_x, txt_b], layer='F.Fab'))\n\n    # create FAB-layer\n    if (h_fabm > 0):\n        if len(pck.plastic_angled)>0:\n            if len(pck.metal_angled) > 0:\n                addRectAngledTopNoBottom(kicad_modt, [l_fabp + pck.metal_offset_x, t_fabp - h_fabp+pck.plastic_angled[1]],\n                                 [l_fabp + pck.metal_offset_x + w_fabm, t_fabp - h_fabm], pck.metal_angled, 'F.Fab',\n                                 lw_fab)\n            else:\n                kicad_modt.append(RectLine(start=[l_fabp + pck.metal_offset_x, t_fabp - h_fabp-pck.plastic_angled[1]],\n                                           end=[l_fabp + pck.metal_offset_x + w_fabm, t_fabp - h_fabm], layer='F.Fab',\n                                           width=lw_fab))\n        else:\n            if len(pck.metal_angled)>0:\n                addRectAngledTop(kicad_modt, [l_fabp + pck.metal_offset_x, t_fabp - h_fabp], [l_fabp + pck.metal_offset_x + w_fabm, t_fabp - h_fabm], pck.metal_angled, 'F.Fab', lw_fab)\n            else:\n                kicad_modt.append(RectLine(start=[l_fabp + pck.metal_offset_x, t_fabp - h_fabp],\n                                      end=[l_fabp + pck.metal_offset_x + w_fabm, t_fabp - h_fabm], layer='F.Fab',\n                                      width=lw_fab))\n\n    if len(pck.plastic_angled)>0:\n         addRectAngledTop(kicad_modt, [l_fabp, t_fabp],\n                         [l_fabp + w_fabp, t_fabp - h_fabp], pck.plastic_angled, 'F.Fab', lw_fab)\n    else:\n        kicad_modt.append(\n            RectLine(start=[l_fabp, t_fabp], end=[l_fabp + w_fabp, t_fabp - h_fabp], layer='F.Fab', width=lw_fab))\n    if pck.mounting_hole_diameter > 0:\n        kicad_modt.append(\n            Circle(center=[l_mounth, t_mounth], radius=pck.mounting_hole_diameter / 2, layer='F.Fab', width=lw_fab))\n\n    for p in range(0, len(pads)):\n        kicad_modt.append(Line(start=[pads[p][0], t_fabp], end=[pads[p][0], pads[p][1]], layer='F.Fab', width=lw_fab))\n\n    # create SILKSCREEN-layer\n    keepouts = []\n    for p in range(0,len(pads)):\n        if p==0:\n            keepouts=keepouts+addKeepoutRect(pads[p][0],pads[p][1],padsize[0]+2*slk_dist,padsize[1]+2*slk_dist)\n        else:\n            keepouts=keepouts+addKeepoutRound(pads[p][0],pads[p][1],padsize[0]+2*slk_dist,padsize[1]+2*slk_dist)\n\n    if len(pck.additional_pin_pad_size) > 0:\n        keepouts.append([addpadx - pck.additional_pin_pad_size[0] / 2 - slk_dist,\n                         addpadx + pck.additional_pin_pad_size[0] / 2 + slk_dist,\n                         addpady - pck.additional_pin_pad_size[1] / 2 - slk_dist,\n                         addpady + pck.additional_pin_pad_size[1] / 2 + slk_dist])\n\n    addHLineWithKeepout(kicad_modt, l_slkp, l_slkp + w_slkp, t_slkp, 'F.SilkS', lw_slk, keepouts)\n    if h_fabm > 0:\n        addHLineWithKeepout(kicad_modt, l_slkp, l_slkp + w_slkp, t_slkp - h_slkm, 'F.SilkS', lw_slk, keepouts)\n        addVLineWithKeepout(kicad_modt, l_slkp, t_slkp, t_slkp - h_slkm, 'F.SilkS', lw_slk, keepouts)\n        addVLineWithKeepout(kicad_modt, l_slkp + w_slkp, t_slkp, t_slkp - h_slkm, 'F.SilkS', lw_slk, keepouts)\n    else:\n        addHLineWithKeepout(kicad_modt, l_slkp, l_slkp + w_slkp, t_slkp - h_slkp, 'F.SilkS', lw_slk, keepouts)\n        addVLineWithKeepout(kicad_modt, l_slkp, t_slkp, t_slkp - h_slkp, 'F.SilkS', lw_slk, keepouts)\n        addVLineWithKeepout(kicad_modt, l_slkp + w_slkp, t_slkp, t_slkp - h_slkp, 'F.SilkS', lw_slk, keepouts)\n\n\n\n    for p in range(0, len(pads)):\n        addVLineWithKeepout(kicad_modt, pads[p][0], t_slkp, pads[p][1], 'F.SilkS', lw_slk, keepouts)\n\n    # create courtyard\n    kicad_mod.append(\n        RectLine(start=[roundCrt(l_crt), roundCrt(t_crt+yshift)], end=[roundCrt(l_crt + w_crt), roundCrt(t_crt + h_crt+yshift)],\n                 layer='F.CrtYd', width=lw_crt))\n\n    # create mounting hole\n    if pck.mounting_hole_drill > 0:\n        kicad_modt.append(Pad(type=Pad.TYPE_NPTH, shape=Pad.SHAPE_OVAL, at=[l_mounth, t_mounth],\n                             size=[pck.mounting_hole_drill, pck.mounting_hole_drill], drill=pck.mounting_hole_drill,\n                             layers=['*.Cu', '*.Mask']))\n\n    if len(pck.additional_pin_pad_size) > 0:\n        kicad_modt.append(Pad(number=pck.pins + 1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, at=[addpadx, addpady],\n                             size=pck.additional_pin_pad_size, drill=0, layers=['F.Cu', 'F.Mask', 'F.Paste']))\n\n    # create pads\n    for p in range(0,len(pads)):\n        if p==0:\n            kicad_modt.append(\n                Pad(number=p+1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=pads[p], size=padsize, drill=pck.drill,\n                    layers=['*.Cu', '*.Mask']))\n        else:\n            kicad_modt.append(\n                Pad(number=p+1, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=pads[p], size=padsize, drill=pck.drill,\n                    layers=['*.Cu', '*.Mask']))\n\n\n    # add model\n    if (has3d):\n        kicad_modt.append(\n            Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=r_3d))\n\n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(footprint_name + '.kicad_mod')\n\n\n# vertical, mounted-from-Lowerside symbols for rectangular transistors\ndef makeVERTLS(lib_name, pck, has3d=False, x_3d=[0, 0, 0], s_3d=[1,1,1], lptext=\"_LargePads\", r_3d=[0, 0, 0]):\n    l_fabp = -pck.pin_offset_x\n    t_fabp = -pck.pin_offset_z\n    w_fabp = pck.plastic[0]\n    h_fabp = pck.plastic[2]\n\n    w_fabm = pck.metal[0]\n    h_fabm = pck.metal[2]\n\n    pinwid=(pck.pins - 1) * pck.rm\n    if len(pck.rm_list)>0:\n        pinwid=0\n        for rm in pck.rm_list:\n            pinwid=pinwid+rm\n\n    l_slkp = l_fabp - slk_offset\n    t_slkp = t_fabp - slk_offset\n    w_slkp = w_fabp + 2 * slk_offset\n    h_slkp = h_fabp + 2 * slk_offset\n    w_slkm = w_fabm + 2 * slk_offset\n    h_slkm = h_fabm + 2 * slk_offset\n\n    l_crt = min(-pck.pad[0] / 2, l_fabp) - crt_offset\n    t_crt = min(-pck.pad[1] / 2, t_fabp) - crt_offset\n    w_crt = max(max(w_fabp, w_fabm), pinwid + pck.pad[0]) + 2 * crt_offset\n    h_crt = max(t_fabp+max(h_fabp, h_fabm) +  crt_offset-t_crt, -t_crt + pck.pad[1] / 2+crt_offset)\n\n    l_mounth = l_fabp + pck.mounting_hole_pos[0]\n\n    txt_x = l_slkp + max(w_slkp, w_slkm) / 2\n\n    tag_items = [\"Vertical\", \"RM {0}mm\".format(pck.rm), \"mount on lower-side of PCB\"]\n\n    footprint_name = pck.name\n    for t in pck.more_packnames:\n        footprint_name = footprint_name + \"_\" + t\n    footprint_name = footprint_name + \"_Vertical\"\n    for t in pck.fpnametags:\n        footprint_name = footprint_name + \"_\" + t\n    footprint_name = footprint_name + \"_MountFromLS\"\n    if pck.largepads:\n        tag_items.append(\"large Pads\")\n        footprint_name = footprint_name + lptext\n\n    print(footprint_name)\n\n    description = pck.name\n    tags = pck.name\n    for t in tag_items:\n        description = description + \", \" + t\n        tags = tags + \" \" + t\n    for t in pck.tags:\n        description = description + \", \" + t\n        tags = tags + \" \" + t\n    if len(pck.webpage)>0:\n        description = description + \", see \" + pck.webpage\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n\n    kicad_modt = Translation(-pinwid, 0)\n    kicad_mod.append(kicad_modt)\n\n    # set general values\n    kicad_modt.append(Text(type='reference', text='REF**', at=[txt_x, t_slkp - txt_offset], layer='F.SilkS'))\n    kicad_modt.append(Text(type='user', text='%R', at=[txt_x, t_slkp - txt_offset], layer='B.Fab'))\n    kicad_modt.append(\n        Text(type='value', text=footprint_name, at=[txt_x, t_slkp + max(h_slkm, h_slkp) + txt_offset], layer='B.Fab'))\n\n    # create FAB-layer\n    kicad_modt.append(\n        RectLine(start=[l_fabp, t_fabp], end=[l_fabp + w_fabp, t_fabp + h_fabp], layer='B.Fab', width=lw_fab))\n    if (pck.metal[2] > 0):\n        kicad_modt.append(\n            Line(start=[l_fabp, t_fabp + h_fabm], end=[l_fabp + w_fabp, t_fabp + h_fabm], layer='B.Fab', width=lw_fab))\n        if pck.mounting_hole_diameter > 0:\n            kicad_modt.append(Line(start=[l_mounth - pck.mounting_hole_diameter / 2, t_fabp],\n                                   end=[l_mounth - pck.mounting_hole_diameter / 2, t_fabp + h_fabm], layer='B.Fab',\n                                   width=lw_fab))\n            kicad_modt.append(Line(start=[l_mounth + pck.mounting_hole_diameter / 2, t_fabp],\n                                   end=[l_mounth + pck.mounting_hole_diameter / 2, t_fabp + h_fabm], layer='B.Fab',\n                                   width=lw_fab))\n    else:\n        if pck.mounting_hole_diameter > 0:\n            kicad_modt.append(Line(start=[l_mounth - pck.mounting_hole_diameter / 2, t_fabp],\n                                   end=[l_mounth - pck.mounting_hole_diameter / 2, t_fabp + h_fabp], layer='B.Fab',\n                                   width=lw_fab))\n            kicad_modt.append(Line(start=[l_mounth + pck.mounting_hole_diameter / 2, t_fabp],\n                                   end=[l_mounth + pck.mounting_hole_diameter / 2, t_fabp + h_fabp], layer='B.Fab',\n                                   width=lw_fab))\n\n    # create SILKSCREEN-layer\n    keepouts = []\n    x = pinwid\n\n    for p in range(1, pck.pins + 1):\n        if p == 1:\n            keepouts = keepouts + addKeepoutRect(x, 0, pck.pad[0] + 2 * slk_dist, pck.pad[1] + 2 * slk_dist)\n        else:\n            keepouts = keepouts + addKeepoutRound(x, 0, pck.pad[0] + 2 * slk_dist, pck.pad[1] + 2 * slk_dist)\n        if len(pck.rm_list)>0 and p<=len(pck.rm_list):\n            x = x - pck.rm_list[p-1]\n        else:\n            x = x - pck.rm\n\n\n    #for ko in keepouts:\n    #    kicad_modt.append(\n    #        RectLine(start=[ko[0], ko[2]],\n    #                 end=[ko[1], ko[3]],\n    #                 layer='F.CrtYd', width=0.01))\n\n    addHDLineWithKeepout(kicad_modt, l_slkp, 3 * lw_slk, l_slkp + w_slkp, t_slkp, 'F.SilkS', lw_slk, keepouts)\n    addHDLineWithKeepout(kicad_modt, l_slkp, 3 * lw_slk, l_slkp + w_slkp, t_slkp + h_slkp, 'F.SilkS', lw_slk, keepouts)\n    addVDLineWithKeepout(kicad_modt, l_slkp, t_slkp, 3 * lw_slk, t_slkp + h_slkp, 'F.SilkS', lw_slk, keepouts)\n    addVDLineWithKeepout(kicad_modt, l_slkp + w_slkp, t_slkp, 3 * lw_slk, t_slkp + h_slkp, 'F.SilkS', lw_slk, keepouts)\n    if (pck.metal[2] > 0):\n        addHDLineWithKeepout(kicad_modt, l_slkp, 3 * lw_slk, l_slkp + w_slkp, t_slkp + h_slkm, 'F.SilkS', lw_slk,\n                             keepouts)\n        if pck.mounting_hole_diameter > 0:\n            addVDLineWithKeepout(kicad_modt, l_mounth - pck.mounting_hole_diameter / 2, t_slkp, 3 * lw_slk,\n                                 t_slkp + h_slkm,\n                                 'F.SilkS', lw_slk, keepouts)\n            addVDLineWithKeepout(kicad_modt, l_mounth + pck.mounting_hole_diameter / 2, t_slkp, 3 * lw_slk,\n                                 t_slkp + h_slkm,\n                                 'F.SilkS', lw_slk, keepouts)\n    else:\n        if pck.mounting_hole_diameter > 0:\n            addVDLineWithKeepout(kicad_modt, l_mounth - pck.mounting_hole_diameter / 2, t_slkp, 3 * lw_slk,\n                                 t_slkp + h_slkp,\n                                 'F.SilkS', lw_slk, keepouts)\n            addVDLineWithKeepout(kicad_modt, l_mounth + pck.mounting_hole_diameter / 2, t_slkp, 3 * lw_slk,\n                                 t_slkp + h_slkp,\n                                 'F.SilkS', lw_slk, keepouts)\n\n    # create courtyard\n    kicad_mod.append(\n        RectLine(start=[roundCrt(l_crt-pinwid), roundCrt(t_crt)], end=[roundCrt(l_crt + w_crt-pinwid), roundCrt(t_crt + h_crt)],\n                 layer='B.CrtYd', width=lw_crt))\n\n    # create pads\n    x = pinwid\n    for p in range(1, pck.pins + 1):\n        if (p == 1):\n            kicad_modt.append(\n                Pad(number=p, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=[x, 0], size=pck.pad, drill=pck.drill,\n                    layers=['*.Cu', '*.Mask']))\n        else:\n            kicad_modt.append(\n                Pad(number=p, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=[x, 0], size=pck.pad, drill=pck.drill,\n                    layers=['*.Cu', '*.Mask']))\n        if len(pck.rm_list)>0 and p<=len(pck.rm_list):\n            x = x - pck.rm_list[p-1]\n        else:\n            x = x - pck.rm\n\n\n    # add model\n    if (has3d):\n        kicad_modt.append(\n            Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=r_3d))\n\n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(footprint_name + '.kicad_mod')\n\n\n# horizontal, mounted-from-Lowerside symbols for rectangular transistors\ndef makeHORLS(lib_name, pck, has3d=False, x_3d=[0, 0, 0], s_3d=[1,1,1], lptext=\"_LargePads\", r_3d=[0, 0, 0]):\n    l_fabp = -pck.pin_offset_x\n    t_fabp = -pck.pin_minlength\n    w_fabp = pck.plastic[0]\n    h_fabp = pck.plastic[1]\n\n    w_fabm = pck.metal[0]\n    h_fabm = pck.metal[1]\n\n    l_slkp = l_fabp - slk_offset\n    t_slkp = t_fabp + slk_offset\n    w_slkp = w_fabp + 2 * slk_offset\n    h_slkp = h_fabp + 2 * slk_offset\n    w_slkm = w_fabm + 2 * slk_offset\n    h_slkm = h_fabm + 2 * slk_offset\n\n    pinwid = (pck.pins - 1) * pck.rm\n    if len(pck.rm_list) > 0:\n        pinwid = 0\n        for rm in pck.rm_list:\n            pinwid = pinwid + rm\n\n    l_crt = min(-pck.pad[0] / 2, l_fabp) - crt_offset\n    t_crt = t_fabp - max(h_fabp, h_fabm) - crt_offset\n    h_crt = (-t_crt + pck.pad[1] / 2) + crt_offset\n    addpad = 0\n    if len(pck.additional_pin_pad_size) > 0:\n        h_crt = h_crt + (pck.additional_pin_pad[1] + pck.additional_pin_pad_size[1] / 2 - h_fabm)\n        t_crt = t_crt - (pck.additional_pin_pad[1] + pck.additional_pin_pad_size[1] / 2 - h_fabm)\n        addpad = pck.additional_pin_pad_size[0]\n        addpadx = l_fabp + pck.additional_pin_pad[0]\n        addpady = t_fabp - pck.additional_pin_pad[1]\n    w_crt = max(max(max(w_fabp, w_fabm), pinwid + pck.pad[0]), addpad) + 2 * crt_offset\n\n    l_mounth = l_fabp + pck.mounting_hole_pos[0]\n    t_mounth = t_fabp - pck.mounting_hole_pos[1]\n\n    txt_x = l_slkp + max(w_slkp, w_slkm) / 2\n    txt_t = (t_slkp - max(h_slkm, h_slkp)) - txt_offset\n    txt_b = pck.pad[1] / 2 + txt_offset\n    if len(pck.additional_pin_pad_size) > 0:\n        txt_t = txt_t - (pck.additional_pin_pad[1] + pck.additional_pin_pad_size[1] / 2 - h_fabm)\n    tag_items = [\"Horizontal\", \"RM {0}mm\".format(pck.rm), \"mount on lower-side of PCB\", \"mount with cooling pad pointing away from PCB\", \"Reversed\"]\n\n    footprint_name = pck.name\n    if len(pck.additional_pin_pad_size) > 0:\n        footprint_name = footprint_name + \"-1EP\"\n    for t in pck.more_packnames:\n        footprint_name = footprint_name + \"_\" + t\n    footprint_name = footprint_name + \"_Horizontal\"\n    for t in pck.fpnametags:\n        footprint_name = footprint_name + \"_\" + t\n    footprint_name = footprint_name + \"_TabUp_MountFromLS\"\n    if pck.largepads:\n        tag_items.append(\"large Pads\")\n        footprint_name = footprint_name + lptext\n    print(footprint_name)\n\n    description = pck.name\n    tags = pck.name\n    for t in tag_items:\n        description = description + \", \" + t\n        tags = tags + \" \" + t\n    for t in pck.tags:\n        description = description + \", \" + t\n        tags = tags + \" \" + t\n    if len(pck.webpage)>0:\n        description = description + \", see \" + pck.webpage\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n\n    kicad_modt=Translation(0,0)#-(pck.pins - 1) * pck.rm,0)\n    kicad_mod.append(kicad_modt)\n\n    # set general values\n    kicad_modt.append(Text(type='reference', text='REF**', at=[txt_x, txt_t], layer='F.SilkS'))\n    kicad_modt.append(Text(type='user', text='%R', at=[txt_x, txt_t], layer='B.Fab'))\n    kicad_modt.append(Text(type='value', text=footprint_name, at=[txt_x, txt_b], layer='B.Fab'))\n\n    # create FAB-layer\n\n    if (h_fabm > 0):\n        if len(pck.metal_angled) > 0:\n            addRectAngledTop(kicad_modt, [l_fabp + pck.metal_offset_x, t_fabp - h_fabp],\n                             [l_fabp + pck.metal_offset_x + w_fabm, t_fabp - h_fabm], pck.metal_angled, 'B.Fab', lw_fab)\n        else:\n            kicad_modt.append(RectLine(start=[l_fabp + pck.metal_offset_x, t_fabp - h_fabp],\n                                       end=[l_fabp + pck.metal_offset_x + w_fabm, t_fabp - h_fabm], layer='B.Fab',\n                                       width=lw_fab))\n\n    if len(pck.plastic_angled) > 0:\n        addRectAngledTop(kicad_modt, [l_fabp, t_fabp],\n                         [l_fabp + w_fabp, t_fabp - h_fabp], pck.plastic_angled, 'B.Fab', lw_fab)\n    else:\n        kicad_modt.append(\n            RectLine(start=[l_fabp, t_fabp], end=[l_fabp + w_fabp, t_fabp - h_fabp], layer='B.Fab', width=lw_fab))\n\n#    if (h_fabm > 0):\n#        kicad_modt.append(RectLine(start=[l_fabp + pck.metal_offset_x, t_fabp - h_fabp],\n#                                  end=[l_fabp + pck.metal_offset_x + w_fabm, t_fabp - h_fabm], layer='B.Fab',\n#                                  width=lw_fab))\n#    kicad_modt.append(\n#        RectLine(start=[l_fabp, t_fabp], end=[l_fabp + w_fabp, t_fabp - h_fabp], layer='B.Fab', width=lw_fab))\n#    kicad_modt.append(\n#        RectLine(start=[l_fabp, t_fabp], end=[l_fabp + w_fabp, t_fabp - h_fabp], layer='B.Fab', width=lw_fab))\n    if pck.mounting_hole_diameter > 0:\n        kicad_modt.append(\n            Circle(center=[l_mounth, t_mounth], radius=pck.mounting_hole_diameter / 2, layer='B.Fab', width=lw_fab))\n    x = 0\n    for p in range(1, pck.pins + 1):\n        kicad_modt.append(Line(start=[x, t_fabp], end=[x, 0], layer='B.Fab', width=lw_fab))\n        if len(pck.rm_list)>0 and p<=len(pck.rm_list):\n            x = x + pck.rm_list[p-1]\n        else:\n            x = x + pck.rm\n\n\n    # create SILKSCREEN-layer\n    keepouts = []\n    x = 0\n    for p in range(1, pck.pins + 1):\n        if p == 1:\n            keepouts = keepouts + addKeepoutRect(x, 0, pck.pad[0] + 2 * slk_dist, pck.pad[1] + 2 * slk_dist)\n        else:\n            keepouts = keepouts + addKeepoutRound(x, 0, pck.pad[0] + 2 * slk_dist, pck.pad[1] + 2 * slk_dist)\n        if len(pck.rm_list)>0 and p<=len(pck.rm_list):\n            x = x + pck.rm_list[p-1]\n        else:\n            x = x + pck.rm\n\n\n    if len(pck.additional_pin_pad_size) > 0:\n        keepouts.append([addpadx - pck.additional_pin_pad_size[0] / 2 - slk_dist,\n                         addpadx + pck.additional_pin_pad_size[0] / 2 + slk_dist,\n                         addpady - pck.additional_pin_pad_size[1] / 2 - slk_dist,\n                         addpady + pck.additional_pin_pad_size[1] / 2 + slk_dist])\n\n    addHDLineWithKeepout(kicad_modt, l_slkp, 3 * lw_slk, l_slkp + w_slkp, t_slkp, 'F.SilkS', lw_slk, keepouts)\n    if h_fabm > 0:\n        addHDLineWithKeepout(kicad_modt, l_slkp, 3 * lw_slk, l_slkp + w_slkp, t_slkp - h_slkm, 'F.SilkS', lw_slk, keepouts)\n        addHDLineWithKeepout(kicad_modt, l_slkp, 3 * lw_slk, l_slkp + w_slkp, t_fabp - h_fabp, 'F.SilkS', lw_slk, keepouts)\n        addVDLineWithKeepout(kicad_modt, l_slkp, t_slkp, 3 * lw_slk, t_slkp - h_slkm, 'F.SilkS', lw_slk, keepouts)\n        addVDLineWithKeepout(kicad_modt, l_slkp + w_slkp, t_slkp, 3 * lw_slk, t_slkp - h_slkm, 'F.SilkS', lw_slk, keepouts)\n    else:\n        addHDLineWithKeepout(kicad_modt, l_slkp, 3 * lw_slk, l_slkp + w_slkp, t_slkp - h_slkp, 'F.SilkS', lw_slk, keepouts)\n        addVDLineWithKeepout(kicad_modt, l_slkp, t_slkp, 3 * lw_slk, t_slkp - h_slkp, 'F.SilkS', lw_slk, keepouts)\n        addVDLineWithKeepout(kicad_modt, l_slkp + w_slkp, t_slkp, 3 * lw_slk, t_slkp - h_slkp, 'F.SilkS', lw_slk, keepouts)\n\n    x = 0\n    for p in range(1, pck.pins + 1):\n        addVDLineWithKeepout(kicad_modt, x, t_slkp, 3 * lw_slk, -(pck.pad[1]/2+slk_dist), 'F.SilkS', lw_slk, keepouts)\n        if len(pck.rm_list)>0 and p<=len(pck.rm_list):\n            x = x + pck.rm_list[p-1]\n        else:\n            x = x + pck.rm\n\n\n    # create courtyard\n    kicad_modt.append(\n        RectLine(start=[roundCrt(l_crt), roundCrt(t_crt)], end=[roundCrt(l_crt + w_crt), roundCrt(t_crt + h_crt)],\n                 layer='B.CrtYd', width=lw_crt))\n\n    # create mounting hole\n    if pck.mounting_hole_drill > 0:\n        kicad_modt.append(Pad(type=Pad.TYPE_NPTH, shape=Pad.SHAPE_OVAL, at=[l_mounth, t_mounth],\n                             size=[pck.mounting_hole_drill, pck.mounting_hole_drill], drill=pck.mounting_hole_drill,\n                             layers=['*.Cu', '*.Mask']))\n\n    if len(pck.additional_pin_pad_size) > 0:\n        kicad_modt.append(Pad(number=pck.pins + 1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, at=[addpadx, addpady],\n                             size=pck.additional_pin_pad_size, drill=0, layers=['B.Cu', 'F.Mask', 'B.Paste']))\n\n    # create pads\n    x = 0\n    for p in range(1, pck.pins + 1):\n        if (p == 1):\n            kicad_modt.append(\n                Pad(number=p, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=[x, 0], size=pck.pad, drill=pck.drill,\n                    layers=['*.Cu', '*.Mask']))\n        else:\n            kicad_modt.append(\n                Pad(number=p, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=[x, 0], size=pck.pad, drill=pck.drill,\n                    layers=['*.Cu', '*.Mask']))\n        if len(pck.rm_list)>0 and p<=len(pck.rm_list):\n            x = x + pck.rm_list[p-1]\n        else:\n            x = x + pck.rm\n\n    # add model\n    if (has3d):\n        kicad_modt.append(\n            Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=r_3d))\n\n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(footprint_name + '.kicad_mod')\n\n\n# horizontal reversed symbols for rectangular transistors\ndef makeHORREV(lib_name, pck, has3d=False, x_3d=[0, 0, 0], s_3d=[1 ,1,1], lptext=\"_LargePads\", r_3d=[0, 0, 0]):\n    l_fabp = -pck.pin_offset_x\n    t_fabp = pck.pin_minlength\n    w_fabp = pck.plastic[0]\n    h_fabp = pck.plastic[1]\n\n    w_fabm = pck.metal[0]\n    h_fabm = pck.metal[1]\n\n    l_slkp = l_fabp - slk_offset\n    t_slkp = t_fabp - slk_offset\n    w_slkp = w_fabp + 2 * slk_offset\n    h_slkp = h_fabp + 2 * slk_offset\n    w_slkm = w_fabm + 2 * slk_offset\n    h_slkm = h_fabm + 2 * slk_offset\n\n    pinwid = (pck.pins - 1) * pck.rm\n    if len(pck.rm_list) > 0:\n        pinwid = 0\n        for rm in pck.rm_list:\n            pinwid = pinwid + rm\n\n    l_crt = min(-pck.pad[0] / 2, l_fabp) - crt_offset\n    t_crt = -pck.pad[1]/2- crt_offset\n    w_crt = max(max(w_fabp, w_fabm), pinwid + pck.pad[0]) + 2 * crt_offset\n    h_crt = -t_crt + t_fabp+max(h_fabp, h_fabm) +  crt_offset\n\n    l_mounth = l_fabp + pck.mounting_hole_pos[0]\n    t_mounth = t_fabp + pck.mounting_hole_pos[1]\n\n    txt_x = l_slkp + max(w_slkp, w_slkm) / 2\n    txt_t = (t_slkp + max(h_slkm, h_slkp)) + txt_offset\n    txt_b = -pck.pad[1] / 2 - txt_offset\n\n    tag_items = [\"Horizontal\", \"RM {0}mm\".format(pck.rm)]\n\n    footprint_name = pck.name\n    for t in pck.more_packnames:\n        footprint_name = footprint_name + \"_\" + t\n    footprint_name = footprint_name + \"_Horizontal\" + \"_TabUp\"\n    for t in pck.fpnametags:\n        footprint_name = footprint_name + \"_\" + t\n    if pck.largepads:\n        tag_items.append(\"large Pads\")\n        footprint_name = footprint_name + lptext\n    print(footprint_name)\n\n    description = pck.name\n    tags = pck.name\n    for t in tag_items:\n        description = description + \", \" + t\n        tags = tags + \" \" + t\n    for t in pck.tags:\n        description = description + \", \" + t\n        tags = tags + \" \" + t\n    if len(pck.webpage)>0:\n        description = description + \", see \" + pck.webpage\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n\n    # set general values\n    kicad_mod.append(Text(type='reference', text='REF**', at=[txt_x, txt_t], layer='F.SilkS'))\n    kicad_mod.append(Text(type='user', text='%R', at=[txt_x, txt_t], layer='F.Fab'))\n    kicad_mod.append(Text(type='value', text=footprint_name, at=[txt_x, txt_b], layer='F.Fab'))\n\n\n    if (h_fabm > 0):\n        if len(pck.metal_angled) > 0:\n            addRectAngledBottom(kicad_mod, [l_fabp + pck.metal_offset_x, t_fabp + h_fabp],\n                                [l_fabp + pck.metal_offset_x + w_fabm, t_fabp + h_fabm], pck.metal_angled, 'F.Fab', lw_fab)\n        else:\n            kicad_mod.append(RectLine(start=[l_fabp + pck.metal_offset_x, t_fabp + h_fabp],\n                                       end=[l_fabp + pck.metal_offset_x + w_fabm, t_fabp + h_fabm], layer='F.Fab',\n                                       width=lw_fab))\n\n    if len(pck.plastic_angled) > 0:\n        addRectAngledBottom(kicad_mod, [l_fabp, t_fabp],\n                            [l_fabp + w_fabp, t_fabp + h_fabp], pck.plastic_angled, 'F.Fab', lw_fab)\n    else:\n        kicad_mod.append(\n            RectLine(start=[l_fabp, t_fabp], end=[l_fabp + w_fabp, t_fabp + h_fabp], layer='F.Fab', width=lw_fab))\n\n    if pck.mounting_hole_diameter > 0:\n        kicad_mod.append(Circle(center=[l_mounth, t_mounth], radius=pck.mounting_hole_diameter / 2, layer='F.Fab', width=lw_fab))\n    x = 0\n    for p in range(1, pck.pins + 1):\n        kicad_mod.append(Line(start=[x, t_fabp], end=[x, 0], layer='F.Fab', width=lw_fab))\n        if len(pck.rm_list)>0 and p<=len(pck.rm_list):\n            x = x + pck.rm_list[p-1]\n        else:\n            x = x + pck.rm\n\n\n    # create SILKSCREEN-layer\n    keepouts = []\n    x = 0\n    for p in range(1, pck.pins + 1):\n        if p==1:\n            keepouts=keepouts+addKeepoutRect(x,0,pck.pad[0]+2*slk_dist,pck.pad[1]+2*slk_dist)\n        else:\n            keepouts=keepouts+addKeepoutRound(x,0,pck.pad[0]+2*slk_dist,pck.pad[1]+2*slk_dist)\n        x = x + pck.rm\n\n    addHLineWithKeepout(kicad_mod, l_slkp, l_slkp + w_slkp, t_slkp, 'F.SilkS', lw_slk, keepouts)\n    addHLineWithKeepout(kicad_mod, l_slkp, l_slkp + w_slkp, t_slkp + h_slkp, 'F.SilkS', lw_slk, keepouts)\n    addVLineWithKeepout(kicad_mod, l_slkp, t_slkp, t_slkp + h_slkp, 'F.SilkS', lw_slk, keepouts)\n    addVLineWithKeepout(kicad_mod, l_slkp + w_slkp, t_slkp, t_slkp + h_slkp, 'F.SilkS', lw_slk, keepouts)\n    if (h_fabm > 0):\n        addHDLineWithKeepout(kicad_mod, l_slkp + pck.metal_offset_x, 10*lw_slk, l_slkp + pck.metal_offset_x + w_slkm, t_slkp + h_slkm, 'F.SilkS', lw_slk, keepouts)\n        addVDLineWithKeepout(kicad_mod, l_slkp + pck.metal_offset_x, t_slkp + h_slkp+lw_slk*2, 10 * lw_slk, t_slkp + h_slkm, 'F.SilkS', lw_slk, keepouts)\n        addVDLineWithKeepout(kicad_mod, l_slkp + pck.metal_offset_x + w_slkm, t_slkp + h_slkp+lw_slk*2, 10 * lw_slk, t_slkp + h_slkm, 'F.SilkS', lw_slk, keepouts)\n    x = 0\n    for p in range(1, pck.pins + 1):\n        addVLineWithKeepout(kicad_mod, x, t_slkp, pck.pad[1]/2+slk_dist, 'F.SilkS', lw_slk, keepouts)\n        if len(pck.rm_list)>0 and p<=len(pck.rm_list):\n            x = x + pck.rm_list[p-1]\n        else:\n            x = x + pck.rm\n\n    # create courtyard\n    kicad_mod.append(\n        RectLine(start=[roundCrt(l_crt), roundCrt(t_crt)], end=[roundCrt(l_crt + w_crt), roundCrt(t_crt + h_crt)],\n                 layer='F.CrtYd', width=lw_crt))\n\n    # create mounting hole\n    if pck.mounting_hole_drill > 0:\n        kicad_mod.append(Pad(type=Pad.TYPE_NPTH, shape=Pad.SHAPE_OVAL, at=[l_mounth, t_mounth],\n                         size=[pck.mounting_hole_drill, pck.mounting_hole_drill], drill=pck.mounting_hole_drill,\n                         layers=['*.Cu', '*.Mask']))\n\n    # create pads\n    x = 0\n    for p in range(1, pck.pins + 1):\n        if (p==1):\n            kicad_mod.append(Pad(number=p, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=[x, 0], size=pck.pad, drill=pck.drill, layers=['*.Cu', '*.Mask']))\n        else:\n            kicad_mod.append(Pad(number=p, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=[x, 0], size=pck.pad, drill=pck.drill,layers=['*.Cu', '*.Mask']))\n        if len(pck.rm_list)>0 and p<=len(pck.rm_list):\n            x = x + pck.rm_list[p-1]\n        else:\n            x = x + pck.rm\n\n\n    # add model\n    if (has3d):\n        kicad_mod.append(\n            Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=r_3d))\n\n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(footprint_name + '.kicad_mod')\n\n\n# horizontal symbols for rectangular transistors\ndef makeTORound(lib_name, pck, has3d=False, x_3d=[0, 0, 0], s_3d=[1,1,1], lptext=\"_LargePads\"):\n    padsize = pck.pad\n    d_fab=pck.diameter_outer\n    d_slk=pck.diameter_outer+2*slk_offset\n\n    # calculate pad positions\n    pads = []\n    yshift = 0\n    xshift = 0\n    a=pck.pin1_angle\n    firstPin=True\n    for p in range(1, pck.pins + 1):\n        x=pck.pin_circle_diameter/2*math.cos(a/180*math.pi)\n        y=pck.pin_circle_diameter/2*math.sin(a/180*math.pi)\n        a = a + pck.pin_dangle\n        if (len(pck.used_pins)<=0) or ((p-1) in pck.used_pins):\n            pads.append([x, y])\n            if firstPin:\n                xshift=-x\n                yshift=-y\n                firstPin=False\n\n\n    txt_t = -d_slk/2 - txt_offset\n    txt_b = d_slk/2 + txt_offset\n    tag_items = []\n\n    footprint_name = pck.name\n    for t in pck.more_packnames:\n        footprint_name = footprint_name + \"_\" + t\n    for t in pck.fpnametags:\n        footprint_name = footprint_name + \"_\" + t\n    if pck.largepads:\n        tag_items.append(\"large Pads\")\n        footprint_name = footprint_name + lptext\n    print(footprint_name)\n\n    description = pck.name\n    tags = pck.name\n    for t in tag_items:\n        description = description + \", \" + t\n        tags = tags + \" \" + t\n    for t in pck.tags:\n        description = description + \", \" + t\n        tags = tags + \" \" + t\n    if len(pck.webpage)>0:\n        description = description + \", see \" + pck.webpage\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n\n    kicad_modt = Translation(xshift, yshift)\n    kicad_mod.append(kicad_modt)\n\n    # set general values\n    kicad_modt.append(Text(type='reference', text='REF**', at=[0, txt_t], layer='F.SilkS'))\n    kicad_modt.append(Text(type='user', text='%R', at=[0, txt_t], layer='F.Fab'))\n    kicad_modt.append(Text(type='value', text=footprint_name, at=[0, txt_b], layer='F.Fab'))\n\n    # create FAB-layer\n    kicad_modt.append(Circle(center=[0, 0], radius=pck.diameter_inner / 2, layer='F.Fab', width=lw_fab))\n    if pck.mark_width > 0 and pck.mark_len > 0:\n        a=pck.mark_angle\n        da=math.asin(pck.mark_width/d_fab)/math.pi*180\n        a1=a+da\n        a2=a-da\n        x1 = [(pck.diameter_outer / 2) * math.cos(a1 / 180 * math.pi), (pck.diameter_outer / 2) * math.sin(a1 / 180 * math.pi)]\n        x3 = [(pck.diameter_outer / 2) * math.cos(a2 / 180 * math.pi), (pck.diameter_outer / 2) * math.sin(a2 / 180 * math.pi)]\n        dx1=  (pck.mark_len) * math.cos(a / 180 * math.pi)\n        dx2 = (pck.mark_len) * math.sin(a / 180 * math.pi)\n        x2 = [x1[0] + dx1, x1[1] + dx2]\n        x4 = [x3[0] + dx1, x3[1] + dx2]\n        minx=min(x2[0],x4[0])\n        miny=min(x2[1],x4[1])\n        kicad_modt.append(Arc(center=[0, 0], start=x1, angle=(360-2*da), layer='F.Fab', width=lw_fab))\n        kicad_modt.append(Line(start=x1, end=x2, angle=0, layer='F.Fab', width=lw_fab))\n        kicad_modt.append(Line(start=x2, end=x4, angle=0, layer='F.Fab', width=lw_fab))\n        kicad_modt.append(Line(start=x4, end=x3, angle=0, layer='F.Fab', width=lw_fab))\n    else:\n        kicad_modt.append(Circle(center=[0, 0], radius=pck.diameter_outer / 2, layer='F.Fab', width=lw_fab))\n    if pck.window_diameter>0:\n        addCircleLF(kicad_modt, [0,0], pck.window_diameter/2, 'F.Fab', lw_fab, 4*lw_fab)\n\n\n    # create SILKSCREEN-layer\n    if pck.mark_width>0 and pck.mark_len>0:\n        a=pck.mark_angle\n        da=math.asin((pck.mark_width+2*slk_offset)/d_slk)/math.pi*180\n        a1=a+da\n        a2=a-da\n        x1 = [(d_slk / 2) * math.cos(a1 / 180 * math.pi), (d_slk / 2) * math.sin(a1 / 180 * math.pi)]\n        x3 = [(d_slk / 2) * math.cos(a2 / 180 * math.pi), (d_slk / 2) * math.sin(a2 / 180 * math.pi)]\n        dx1=  (pck.mark_len+slk_offset) * math.cos(a / 180 * math.pi)\n        dx2 = (pck.mark_len+slk_offset) * math.sin(a / 180 * math.pi)\n        x2 = [x1[0] + dx1, x1[1] + dx2]\n        x4 = [x3[0] + dx1, x3[1] + dx2]\n        #minx=min(x2[0],x4[0])\n        #miny=min(x2[1],x4[1])\n        kicad_modt.append(Arc(center=[0, 0], start=x1, angle=(360-2*da), layer='F.SilkS', width=lw_slk))\n        kicad_modt.append(Line(start=x1, end=x2, angle=0, layer='F.SilkS', width=lw_slk))\n        kicad_modt.append(Line(start=x2, end=x4, angle=0, layer='F.SilkS', width=lw_slk))\n        kicad_modt.append(Line(start=x4, end=x3, angle=0, layer='F.SilkS', width=lw_slk))\n    else:\n        kicad_modt.append(Circle(center=[0, 0], radius=d_slk/2, layer='F.SilkS', width=lw_slk))\n\n\n\n    if pck.mark_width > 0 and pck.mark_len > 0:\n        kicad_mod.append(\n            RectLine(start=[roundCrt(xshift+min(minx-crt_offset,-d_fab/2-crt_offset)), roundCrt(yshift+min(miny-crt_offset,-d_fab/2-crt_offset))], end=[roundCrt(xshift+d_fab/2+crt_offset), roundCrt(yshift+d_fab/2+crt_offset)],\n                     layer='F.CrtYd', width=lw_crt))\n    else:\n        kicad_mod.append(Circle(center=[roundCrt(xshift), roundCrt(yshift)], radius=roundCrt(d_fab / 2+crt_offset), layer='F.CrtYd', width=lw_crt))\n\n\n    # create pads\n    for p in range(0, len(pads)):\n        if p == 0:\n            kicad_modt.append(\n                Pad(number=p + 1, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=pads[p], size=[roundG(padsize[0]*1.3,0.1),padsize[1]], drill=pck.drill,\n                    layers=['*.Cu', '*.Mask']))\n        else:\n            kicad_modt.append(\n                Pad(number=p + 1, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=pads[p], size=padsize, drill=pck.drill,\n                    layers=['*.Cu', '*.Mask']))\n\n    # add model\n    if (has3d):\n        kicad_modt.append(\n            Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=[0, 0, 0]))\n\n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(footprint_name + '.kicad_mod')\n\n\nif __name__ == '__main__':\n    # make standard packages\n    packs = [\"TO-264\", \"TO-247\", \"TO-218\", \"TO-251\", \"TO-126\", \"TO-220\", \"TO-3P\", \"TO-262\", \"SIPAK\",\"TO-3PB\", \"TO-220F\"]\n    pins = [[2, 3,5], [2, 3,4,5], [2, 3], [2, 3], [2, 3], [2, 3, 4,5], [3], [3,5], [3],  [3], [2, 3, 4, 5, ]]\n    rms = [ [0, 0,3.81], [0, 0,2.54,2.54], [0, 0], [0, 0], [0, 0], [0, 0, 2.54,1.7], [0], [0,1.7], [0],  [0], [0, 0, 2.54,1.7]]\n\n    #makeVERTLS(\"${KISYS3DMOD}/Package_TO_SOT_THT\", pack(\"SOT93\", 2, 0, 0, False),False, [0, 0, 0], [0, 0, 0])\n    #exit()\n    for p in range(0, len(packs)):\n        for pidx in range(0, len(pins[p])):\n            o3d = [0, 0, 0]\n            o3dh = [0, 0, 0]\n            o3dls = [0, 0, 0]\n            o3dvls = [0, 0, 0]\n            s3d = [1,1,1]\n            r3d=[0,0,0]\n            r3dr=r3d\n\n            pack_norm = pack(packs[p], pins[p][pidx], rms[p][pidx], 0, False)\n            libn = \"${KISYS3DMOD}/Package_TO_SOT_THT\"\n            makeVERT(libn, pack_norm, True, o3d, s3d, \"_LargePads\", r3d)\n            #makeVERTLS(libn, pack_norm, True, o3dvls, s3d, \"_LargePads\", r3d)\n            makeHOR(libn, pack_norm, True, o3dh, s3d, \"_LargePads\", r3d)\n            if (len(pack_norm.additional_pin_pad) <= 0):\n                #makeHORLS(libn, pack_norm, True, o3dls, s3d, \"_LargePads\", r3d)\n                makeHORREV(libn, pack_norm, True, o3d, s3d, \"_LargePads\", r3dr)\n\n\n    # make staggered packages\n    packs =       [ \"TO-220\",                                         \"TO-220F\",                              ]\n    pins =        [ [4,      5,     7,     9,     11,       15,    ], [ 4,    4,      5,     5,      7,    9,  11,   15 ], ]\n    rms =         [ [2.54, 1.7,  1.27,  0.97,    1.7,    1.27,     ], [ 2.54, 2.54, 1.7,   1.7,   1.27,  0.9, 1.7, 1.27 ], ]\n    pitchys =     [ [],                                               [    0, 2.05,   0,  2.06,      0,    0,   0,    0 ], ]\n    ypinoffsets = [ [],                                               [    0,    0,   0,   4.5,      0,    0,   0,    0 ], ]\n    for p in range(0, len(packs)):\n        for pidx in range(0, len(pins[p])):\n            o3d = [0, 0, 0]\n            s3d = [1,1,1]\n            pitchy=0\n            if p<len(pitchys):\n                if pidx<len(pitchys[p]):\n                    pitchy=pitchys[p][pidx]\n            ypinoffset=0\n            if p<len(ypinoffsets):\n                if pidx<len(ypinoffsets[p]):\n                    ypinoffset=ypinoffsets[p][pidx]\n\n            pack_norm1 = pack(packs[p], pins[p][pidx], rms[p][pidx], 1, False, pitchy,ypinoffset)\n            pack_norm2 = pack(packs[p], pins[p][pidx], rms[p][pidx], 2, False, pitchy,ypinoffset)\n            libn = \"${KISYS3DMOD}/Package_TO_SOT_THT\"\n            makeVERT(libn, pack_norm1, True, o3d, s3d)\n            makeVERT(libn, pack_norm2, True, o3d, s3d)\n            makeHOR(libn, pack_norm1, True, o3d, s3d)\n            makeHOR(libn, pack_norm2, True, o3d, s3d)\n\n\n\n                            #pack_largepins=pack(packs[p], pins[p][pidx], rms[p][pidx], True)\n            #makeVERT(\"${KISYS3DMOD}/Package_TO_SOT_THT\", pack_largepins, True, o3d, s3d)\n            #makeHOR(\"${KISYS3DMOD}/Package_TO_SOT_THT\", pack_largepins, True, o3d, s3d)\n            #if (len(pack_largepins.additional_pin_pad) <= 0):\n            #    makeHORREV(\"${KISYS3DMOD}/Package_TO_SOT_THT\", pack_largepins, True, o3d, s3d)\n\n    # make round packages\n    packs=[]\n    modifiers=[]\n    pins=[]\n    has3d=[]\n    off3d=[]\n    scale3d=[]\n\n    packs.append(\"TO-5\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([2, 3, 4, 6, 8, 10])\n    has3d.append([True, True, True, True, True, True])\n    off3d.append([])\n    scale3d.append([])\n\n    packs.append(\"TO-5_PD5.08\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([8])\n    has3d.append([True])\n    off3d.append([])\n    scale3d.append([])\n\n    packs.append(\"TO-8\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([2, 3])\n    has3d.append([True, True])\n    off3d.append([])\n    scale3d.append([])\n\n    packs.append(\"TO-11\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([2, 3])\n    has3d.append([True, True])\n    off3d.append([])\n    scale3d.append([])\n\n    packs.append(\"TO-12\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([4])\n    has3d.append([True])\n    off3d.append([[]])\n    scale3d.append([[]])\n\n    packs.append(\"TO-17\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([4])\n    has3d.append([True])\n    off3d.append([[]])\n    scale3d.append([[]])\n\n    packs.append(\"TO-18\")\n    modifiers.append([\"\", \"Window\", \"Lens\"])\n    pins.append([2, 3, 4])\n    has3d.append([True, True, True])\n    off3d.append([])\n    scale3d.append([])\n\n    packs.append(\"TO-33\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([4])\n    has3d.append([True])\n    off3d.append([[]])\n    scale3d.append([[]])\n\n    packs.append(\"TO-38\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([2, 3])\n    has3d.append([True, True])\n    off3d.append([])\n    scale3d.append([])\n\n    packs.append(\"TO-39\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([2, 3, 4, 6, 8, 10])\n    has3d.append([True, True, True, True, True, True])\n    off3d.append([])\n    scale3d.append([])\n\n    packs.append(\"TO-46\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([2, 3, 4])\n    has3d.append([True, True, True])\n    off3d.append([])\n    scale3d.append([])\n\n    packs.append(\"TO-52\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([2, 3])\n    has3d.append([True, True])\n    off3d.append([])\n    scale3d.append([])\n\n    packs.append(\"TO-72\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([4])\n    has3d.append([True])\n    off3d.append([[]])\n    scale3d.append([[]])\n\n    packs.append(\"TO-78\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([6, 8, 10])\n    has3d.append([True, True, True])\n    off3d.append([])\n    scale3d.append([])\n\n    packs.append(\"TO-99\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([6,8])\n    has3d.append([True,True])\n    off3d.append([])\n    scale3d.append([])\n\n    packs.append(\"TO-100\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([10])\n    has3d.append([True,True])\n    off3d.append([])\n    scale3d.append([])\n\n\n    packs.append(\"TO-75\")\n    modifiers.append([\"\", \"Window\"])\n    pins.append([6])\n    has3d.append([True])\n    off3d.append([[]])\n    scale3d.append([[]])\n\n\n\n\n    for p in range(0, len(packs)):\n        mi=0\n        for m in modifiers[p]:\n            for pidx in range(0, len(pins[p])):\n\n                o3d = [0, 0, 0]\n                s3d = [1,1,1]\n\n                pack = pack_round(packs[p], pins[p][pidx], m, False)\n                libn = \"${KISYS3DMOD}/Package_TO_SOT_THT\"\n                makeTORound(libn, pack, has3d[p][pidx], o3d, s3d)\n            mi=mi+1\n"
  },
  {
    "path": "scripts/Packages/TO_SOT_THT/TO_THT_packages.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\nimport time\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"..\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom tools import *\n\n\nclass pack_round:\n    #\n    #\n    #\n    #\n    #  |\\    ~~~~~~~\n    #  \\ \\/          \\\n    #   \\               \\\n    #  /                 \\\n    #  |  PP1        PP   |\n    #  \\                 /\n    #   \\               /\n    #     \\    PP    /\n    #        ~~~~~~~\n    def __init__(self):\n        self.diameter_inner = 0  # diameter of top can\n        self.diameter_outer = 0  # diameter of bottom can\n        self.mark_width=0 # width of marking\n        self.mark_len=0 # length of marking\n        self.pins = 0  # number of pins\n        self.pin_circle_diameter = 0  # pin circle diameterdistance\n        self.pin1_angle=0 # starting angle of first pin\n        self.pin_dangle=90 # angle between two pins (in degrees)\n        self.mark_angle=-45 # angular position of marking\n        self.pad = [0, 0]  # width/height of pads\n        self.drill = 0  # diameter of pad drills\n        self.name = \"\"  # name of package\n        self.tags = []  # description/keywords\n        self.largepads =False\n        self.fpnametags =[]\n        self.window_diameter=0 # diameter of an on-top glass window\n        self.used_pins=[] # if filled: the device may have up to self.pins pins, but only the given pin positions (0-based count) are actualy used\n        self.more_packnames=[] # additional package names, e.g. \"I2PAK\" for TO-262\n        self.webpage=\"\";\n\n    def __init__(self, name, pins=3, modifier=\"\", largepads=False):\n        self.diameter_inner = 0  # diameter of top can\n        self.diameter_outer = 0  # diameter of bottom can\n        self.mark_width = 0  # width of marking\n        self.mark_len = 0  # length of marking\n        self.pins = pins  # number of pins\n        self.pin_circle_diameter = 0  # pin circle diameterdistance\n        self.pin1_angle = 180  # starting angle of first pin\n        self.mark_angle = -45  # angular position of marking\n        self.pad = [0, 0]  # width/height of pads\n        self.drill = 0  # diameter of pad drills\n        self.name = \"\"  # name of package\n        self.tags = []  # description/keywords\n        self.largepads = largepads\n        self.fpnametags = []\n        self.window_diameter=0 # diameter of an on-top glass window\n        self.pin_dangle = -90  # angle between two pins (in degrees)\n        self.used_pins = []  # if filled: the device may have up to self.pins pins, but only the given pin positions (0-based count) are actualy used\n        self.more_packnames = []  # additional package names, e.g. \"I2PAK\" for TO-262\n        if pins == 2:\n            self.pin_dangle = -180\n        elif pins == 4:\n            self.pin_dangle = -90\n        elif pins >4:\n            self.pin_dangle = -360/pins\n        self.mark_angle = self.pin1_angle + 45  # angular position of marking\n        self.name = name\n        self.webpage=\"\";\n\n        if (name == \"TO-18\") or (name==\"TO-46\") or (name==\"TO-52\") or (name==\"TO-72\"):\n            self.diameter_inner = 4.8  # diameter of top can\n            self.diameter_outer = 5.8  # diameter of bottom can\n            self.mark_width = 1.16  # width of marking\n            self.mark_len = 1.17  # length of marking\n            self.pin_circle_diameter = 2.54  # pin circle diameterdistance\n            self.pad = [1.2,1.2]  # width/height of pads\n            self.drill = 0.7  # diameter of pad drills\n            self.name = self.name + \"-{0}\".format(pins)  # name of package\n            if len(modifier)>0:\n                self.name = self.name +\"_\"+modifier\n                self.tags.append(modifier)\n            if largepads:\n                self.pad = [1.5, 1.5]  # width/height of pads\n\n            if (modifier==\"Window\") or (modifier==\"Lens\"):\n                self.window_diameter = 4  # diameter of an on-top glass window\n\n\n        if (name == \"TO-5\") or (name == \"TO-5_PD5.08\") or (name == \"TO-11\") or (name == \"TO-12\") or (name == \"TO-33\") or (name == \"TO-39\") or (name == \"TO-99\") or (name == \"TO-78\") or (name == \"TO-100\") or (name == \"TO-75\"):\n            self.diameter_inner = 8.5  # diameter of top can\n            self.diameter_outer = 9.4  # diameter of bottom can\n            self.mark_width = 0.86  # width of marking\n            self.mark_len = 1.14  # length of marking\n            self.pin_circle_diameter = 5.08  # pin circle diameterdistance\n            if (pins==6):\n                self.pins=8\n                self.pin_dangle = -360 / self.pins\n                self.used_pins=[0,1,2,4,5,6]\n            elif (pins>6) and (name != \"TO-5_PD5.08\"):\n                self.pin_circle_diameter = 5.84  # pin circle diameterdistance\n            elif pins>8:\n                self.mark_angle = self.pin1_angle + 36  # angular position of marking\n            if (name == \"TO-100\"):\n                self.pin_circle_diameter = 5.84  # pin circle diameterdistance\n            self.pad = [1.2, 1.2]  # width/height of pads\n            self.drill = 0.7  # diameter of pad drills\n            if (name == \"TO-5_PD5.08\"):\n                self.name = \"TO-5\" + \"-{0}_PD5.08\".format(pins)  # name of package\n            else:\n                self.name = self.name + \"-{0}\".format(pins)  # name of package\n            if len(modifier) > 0:\n                self.name = self.name + \"_\" + modifier\n                self.tags.append(modifier)\n            if largepads:\n                self.pad = [1.5, 1.5]  # width/height of pads\n            if (modifier == \"Window\") or (modifier == \"Lens\"):\n                self.window_diameter = 5.9  # diameter of an on-top glass window\n\n\n\n        if (name == \"TO-8\"):\n            self.diameter_inner = 13.2  # diameter of top can\n            self.diameter_outer = 14.4  # diameter of bottom can\n            self.mark_width = 0.0  # width of marking\n            self.mark_len = 0  # length of marking\n            self.pin_circle_diameter = 7.1  # pin circle diameterdistance\n            self.pad = [1.6, 1.6]  # width/height of pads\n            self.drill = 1.1  # diameter of pad drills\n            self.name = self.name + \"-{0}\".format(pins)  # name of package\n            if len(modifier) > 0:\n                self.name = self.name + \"_\" + modifier\n                self.tags.append(modifier)\n            if largepads:\n                self.pad = [2, 2]  # width/height of pads\n            if (modifier == \"Window\") or (modifier == \"Lens\"):\n                self.window_diameter = 0.43*25.4  # diameter of an on-top glass window\n\n\n        if (name == \"TO-17\"):\n            self.diameter_inner = 4.2  # diameter of top can\n            self.diameter_outer = 5.2  # diameter of bottom can\n            self.mark_width = 0.76  # width of marking\n            self.mark_len = 0.75  # length of marking\n            self.pin_circle_diameter = 1.8  # pin circle diameterdistance\n            self.pad = [0.9,0.9]  # width/height of pads\n            self.drill = 0.6  # diameter of pad drills\n            self.name = self.name + \"-{0}\".format(pins)  # name of package\n            if len(modifier) > 0:\n                self.name = self.name + \"_\" + modifier\n                self.tags.append(modifier)\n            if largepads:\n                self.pad = [1.3, 1.3]  # width/height of pads\n            if (modifier == \"Window\") or (modifier == \"Lens\"):\n                self.window_diameter = 3.5  # diameter of an on-top glass window\n\n\n        if (name == \"TO-38\"):\n            self.diameter_inner = 12.3  # diameter of top can\n            self.diameter_outer = 17.3  # diameter of bottom can\n            self.mark_width = 0.0  # width of marking\n            self.mark_len = 0.0  # length of marking\n            self.pin_circle_diameter = 5.08  # pin circle diameterdistance\n            self.pad = [1.3, 1.3]  # width/height of pads\n            self.drill = 0.8  # diameter of pad drills\n            self.name = self.name + \"-{0}\".format(pins)  # name of package\n            if len(modifier) > 0:\n                self.name = self.name + \"_\" + modifier\n                self.tags.append(modifier)\n            if largepads:\n                self.pad = [1.6, 1.6]  # width/height of pads\n            if (modifier == \"Window\") or (modifier == \"Lens\"):\n                self.window_diameter = 8  # diameter of an on-top glass window\n\n\nclass pack:\n    #      metal_/plastic_                                        ^\n    #  <--------width------>                                      |\n    #  +-------------------+                 ^                    y\n    #  |                   |                 |                    x---->\n    #  |        OO         | mounting drill  |\n    #  |                   |                 |\n    #  |   METAL           |                 |\n    #  +-------------------+ ^               metal_height\n    #  |                   | |               |\n    #  |                   | |               |\n    #  |   PLASTIC         | plastic_height  |\n    #  |                   | |               |\n    #  |                   | |               |\n    #  |                   | |               |\n    #  0-------------------+ v  0= ref pos   v\n    #     |      |      |  ^\n    #     |      |      |  |\n    #     |      |      |  pin_minlength\n    #     |      |      |  |\n    #     |      |      |  v\n    #    PPP    PPP    PPP      PADs\n    #     <--rm-->\n    #   <->\n    #    pin_offset_x\n    #\n    #  0-------------------+  0= ref pos    ^             ^                z\n    #  |   METAL           |                metal_depth   |                |\n    #  +-------------------+ ^              v             pin_offset_z     |\n    #  |   PLASTIC         | plastic_depth                |                v\n    #  | PPP    PPP    PPP | |                            v\n    #  +-------------------+ v\n    #\n    def __init__(self):\n        self.plastic = [0, 0, 0]  # width,heigth,depth of plastic package, starting at bottom-left\n        self.metal = [0, 0, 0]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n        self. metal_offset_x =0 # offset of metal from left\n        self.pins = 0  # number of pins\n        self.rm = 0  # pin distance\n        self.pad = [0, 0]  # width/height of pads\n        self.drill = 0  # diameter of pad drills\n        self.name = \"\"  # name of package\n        self.mounting_hole_pos = [0, 0]  # position of mounting hole from bottom-left\n        self.mounting_hole_diameter = 0  # diameter of mounting hole in package\n        self.mounting_hole_drill = 0  # diameter of mounting hole drill\n        self.pin_minlength = 0  # min. elongation of pins before 90° bend\n        self.pinw = [0, 0];  # width,height of pins\n        self.tags = []  # description/keywords\n        self.pin_offset_x = 0\n        self.pin_offset_z = 0\n        self.largepads =False\n        self.fpnametags =[]\n        self.additional_pin_pad =[] # Position des Zusatz-SMD-Pads\n        self.additional_pin_pad_size = [] # Größe des Zusatz-SMD-Pads\n        self.plastic_angled=[]\n        self.metal_angled = []\n        self.staggered_type=0 # 0=no staggering, 1=type1-staggering (pin1=fron), 2=type2-staggering (pin1=back)\n        self.staggered_rm=[5.08,5.08] # y-distance between pins [vertical, horizontal]\n        self.staggered_pin_offset_z = 0 # z-offset of back-pins in staggered mode [vertical, horizontal]\n        self.staggered_pin_minlength = 0  # y-offset of back-pins in staggered mode\n        self.staggered_pad=[] # pad size in staggered mode\n        self.rm_list = []\n        self.more_packnames = []  # additional package names, e.g. \"I2PAK\" for TO-262\n        self.webpage=\"\";\n\n    def __init__(self ,name ,pins=3 ,rm=0, staggered_type=0,largepads=False,pitchy=0,ypinoffset=0):\n        self. additional_pin_pad =[] # Position des Zusatz-SMD-Pads\n        self.additional_pin_pad_size = [] # Größe des Zusatz-SMD-Pads\n        self.largepads =largepads\n        self.fpnametags = []\n        self.metal_offset_x = 0  # offset of metal from left\n        self.plastic_angled = []\n        self.metal_angled = []\n        self.staggered_type=staggered_type\n        self.staggering_rm=[5.08,2.54] # y-distance between pins\n        self.staggered_pin_offset_z=0\n        self.staggered_pin_minlength = 0 # y-offset of back-pins in staggered mode\n        self.staggered_pad = []  # pad size in staggered mode\n        self.addpinstext=True\n        self.rm_list = []\n        self.more_packnames = []  # additional package names, e.g. \"I2PAK\" for TO-262\n        self.webpage=\"\";\n\n        if (name == \"TO-218\"):\n            self.webpage=\"https://www.vishay.com/docs/95214/fto218.pdf\"\n            self.plastic = [14.94, 12.19, 4.8]  # width,heigth,depth of plastic package, starting at bottom-left\n            self.metal = [self.plastic[0], 12.19+7.79,\n                          1.27]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n            self.pins = 3  # number of pins\n            self.rm = 5.475  # pin distance\n            self.pad = [2.5, 3.5]  # width/height of pads\n            self.drill = 1.5  # diameter of pad drills\n            self.name = name  # name of package\n            self.mounting_hole_pos = [self.plastic[0] / 2, 16.2]  # position of mounting hole from bottom-left\n            self.mounting_hole_diameter = 4.23  # diameter of mounting hole in package\n            self.mounting_hole_drill = 4.04  # diameter of mounting hole drill\n            self.pin_minlength = 2.35  # min. elongation of pins before 90° bend\n            self.pinw = [1.15, 0.4];  # width,height of pins\n            self.tags = [\"SOT-93\"]  # description/keywords\n            #self.more_packnames.append(\"SOT-93\")\n            self.pin_offset_z = 3.17\n            if largepads:\n                self.pad = [3.5, 4.5]\n                self.largepads = True\n\n\n        elif (name == \"TO-3P\"):\n            self.webpage=\"https://toshiba.semicon-storage.com/ap-en/design-support/package/detail.TO-3P(N).html\"\n            self.plastic = [15.5, 19.3, 4.5]  # width,heigth,depth of plastic package, starting at bottom-left\n            self.metal = [self.plastic[0], 20, 1.5]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n            self.pins = 3  # number of pins\n            self.rm = 5.45  # pin distance\n            self.pad = [2.5, 4.5]  # width/height of pads\n            self.drill = 1.5  # diameter of pad drills\n            self.name = name  # name of package\n            self.mounting_hole_pos = [self.plastic[0] / 2,\n                                      self.plastic[1] - 3.5]  # position of mounting hole from bottom-left\n            self.mounting_hole_diameter = 3.2  # diameter of mounting hole in package\n            self.mounting_hole_drill = 3.4  # diameter of mounting hole drill\n            self.pin_minlength = 3.0  # min. elongation of pins before 90° bend\n            self.pinw = [1.0, 0.6];  # width,height of pins\n            self.tags = []\n            self.metal_angled=[1.15,2]\n            self.plastic_angled = [2.19, 3.5]\n            self.tags = [\"\"]  # description/keywords\n            self.pin_offset_z = 3.0\n            self.addpinstext=True\n            if largepads:\n                self.pad = [3.5, 5.5]\n                self.largepads = True\n\n        elif (name == \"TO-3PB\"):\n            self.webpage=\"http://www.onsemi.com/pub/Collateral/340AC.PDF\"\n            self.plastic = [15.6, 18.5, 4.8]  # width,heigth,depth of plastic package, starting at bottom-left\n            self.metal = [self.plastic[0], 20, 2]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n            self.pins = 3  # number of pins\n            self.rm = 5.45  # pin distance\n            self.pad = [2.5, 4.5]  # width/height of pads\n            self.drill = 1.5  # diameter of pad drills\n            self.name = name  # name of package\n            self.mounting_hole_pos = [self.plastic[0] / 2,\n                                      self.plastic[1] - 3.5]  # position of mounting hole from bottom-left\n            self.mounting_hole_diameter = 3.2  # diameter of mounting hole in package\n            self.mounting_hole_drill = 3.4  # diameter of mounting hole drill\n            self.pin_minlength = 1.6  # min. elongation of pins before 90° bend\n            self.pinw = [1.0, 0.6];  # width,height of pins\n            self.tags = []\n            self.metal_angled=[1.3,2.3]\n            self.plastic_angled = [2.7, 4.7]\n            self.tags = [\"\"]  # description/keywords\n            self.pin_offset_z = 1.7\n            self.addpinstext=True\n            if largepads:\n                self.pad = [3.5, 5.5]\n                self.largepads = True\n\n        elif (name == \"TO-264\"):\n            self.webpage=\"https://www.fairchildsemi.com/package-drawings/TO/TO264A03.pdf\"\n            if (pins==5):\n                self.webpage=\"https://www.onsemi.com/pub/Collateral/NJL3281D-D.PDF\"\n            self.plastic = [20, 26, 5]  # width,heigth,depth of plastic package, starting at bottom-left\n            self.metal = [self.plastic[0], 0,\n                          2]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n            self.pins = 3  # number of pins\n            self.rm = 5.45  # pin distance\n            self.pad = [2.5, 4.5]  # width/height of pads\n            self.drill = 1.5  # diameter of pad drills\n            self.name = name  # name of package\n            self.mounting_hole_pos = [self.plastic[0] / 2,\n                                      self.plastic[1] - 6]  # position of mounting hole from bottom-left\n            self.mounting_hole_diameter = 3.3  # diameter of mounting hole in package\n            self.mounting_hole_drill = 3.3  # diameter of mounting hole drill\n            self.pin_minlength = 5.08  # min. elongation of pins before 90° bend\n            self.pinw = [1, 0.6];  # width,height of pins\n            self.tags = []  # description/keywords\n            self.pin_offset_z = self.plastic[2] - (2.8 + 0.3)\n            if largepads:\n                self.pad = [3.5, 5.5]\n                self.largepads = True\n\n\n        elif (name == \"TO-247\"):\n            self.webpage=\"https://toshiba.semicon-storage.com/us/product/mosfet/to-247-4l.html\"\n            if (pins==5):\n                self.webpage=\"http://ww1.microchip.com/downloads/en/DeviceDoc/20005685A.pdf\"\n            self.plastic = [15.9, 20.95, 5.03]  # width,heigth,depth of plastic package, starting at bottom-left\n            self.metal = [0, 0,\n                          0]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n            self.pins = 3  # number of pins\n            self.rm = 5.45  # pin distance\n            self.pad = [2.5, 4.5]  # width/height of pads\n            self.drill = 1.5  # diameter of pad drills\n            self.name = name  # name of package\n            self.mounting_hole_pos = [self.plastic[0] / 2,\n                                      self.plastic[1] - 6.17]  # position of mounting hole from bottom-left\n            self.mounting_hole_diameter = 3.61  # diameter of mounting hole in package\n            self.mounting_hole_drill = 3.6  # diameter of mounting hole drill\n            self.pin_minlength = 5.08  # min. elongation of pins before 90° bend\n            self.pinw = [1.2, 0.6];  # width,height of pins\n            self.tags = []\n            if (pins==4):\n                self.rm_list = [5.08,2.54,2.54]\n            self.pin_offset_z = self.plastic[2] - (2.4 + 0.3)\n            if largepads:\n                self.pad = [3.5, 5.5]\n                self.largepads = True\n\n\n\n        elif (name == \"TO-220\"):\n            if pins==3:\n                self.webpage=\"https://www.vishay.com/docs/66542/to-220-1.pdf\"\n            if (pins==2):\n                self.webpage=\"https://www.centralsemi.com/PDFS/CASE/TO-220-2PD.PDF\"\n            #if (pins==4):\n            #    self.webpage=\"https://www.centralsemi.com/PDFS/CASE/TO-220-2PD.PDF\"\n            if (pins==5):\n                self.webpage=\"http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-to-220/to-220_5_05-08-1421.pdf?domain=www.linear.com, https://www.diodes.com/assets/Package-Files/TO220-5.pdf\"\n                if staggered_type==0:\n                    self.webpage=\"http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-to-220/to-220_5_05-08-1421_straight_lead.pdf\"\n            self.plastic = [10, 9.25, 4.4]  # width,heigth,depth of plastic package, starting at bottom-left\n            self.metal = [self.plastic[0], 15.65, 1.27]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n            self.pins = 3  # number of pins\n            self.rm = 2.54  # pin distance\n            self.pad = [2,2]  # width/height of pads\n            self.drill = 1.1  # diameter of pad drills\n            self.name = name  # name of package\n            self.mounting_hole_pos = [self.plastic[0] / 2,\n                                      self.metal[1] - 2.8]  # position of mounting hole from bottom-left\n            self.mounting_hole_diameter = 3.7  # diameter of mounting hole in package\n            self.mounting_hole_drill = 3.5  # diameter of mounting hole drill\n            self.pin_minlength = 3.81  # min. elongation of pins before 90° bend\n            self.pinw = [0.75, 0.5];  # width,height of pins\n            self.tags = []  # description/keywords\n            self.pin_offset_z = 3.15\n            self.staggered_rm = [3.7,3.8]# y-distance between pins\n            self.staggered_pin_offset_z = 4.5  # z-offset of back-pins in staggered mode\n            self.staggered_pin_minlength = 2.05  # y-offset of back-pins in staggered mode\n            self.staggered_pad = [1.8, 1.8]  # width/height of pads\n            if pins == 5:\n                self.tags.append(\"Pentawatt\")\n                self.tags.append(\"Multiwatt-5\")\n                #self.more_packnames.append(\"Pentawatt\")\n                #self.more_packnames.append(\"Multiwatt-5\")\n                self.staggered_pin_minlength = 2.05+1.28  # y-offset of back-pins in staggered mode\n                self.rm = 1.7\n                self.pad = [1.3, 1.8]\n            if pins == 9:\n                self.pinw = [0.5, 0.38];\n                self.drill = 0.7\n                self.pad = [1.3, 1.3]\n                self.staggered_pad = [1.5, 1.5]  # width/height of pads\n            if pins >5:\n                self.tags.append(\"Multiwatt-{0}\".format(pins))\n                #self.more_packnames.append(\"Multiwatt-{0}\".format(pins))\n            if pins>9:\n                if pins==11:\n                    self.webpage=\"http://www.st.com/resource/en/datasheet/tda7391lv.pdf\"\n                if pins==15:\n                    self.webpage=\"http://www.st.com/resource/en/datasheet/l298.pdf\"\n                self.plastic = [20.2, 10.7, 5]  # width,heigth,depth of plastic package, starting at bottom-left\n                self.metal = [self.plastic[0], 17.5,1.6]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n                self.metal_angled = [2.25,2.25]\n                self.pins = 15  # number of pins\n                self.rm = 1.3  # pin distance\n                self.pad = [1.8, 1.8]  # width/height of pads\n                self.drill = 1  # diameter of pad drills\n                self.name = name+\"-{0}\".format(pins)  # name of package\n                self.addpinstext=False\n                self.mounting_hole_pos = [self.plastic[0] / 2, 17.5-2.8]  # position of mounting hole from bottom-left\n                self.mounting_hole_diameter = 3.7  # diameter of mounting hole in package\n                self.mounting_hole_drill = 3.5  # diameter of mounting hole drill\n                self.pin_minlength = 3.81  # min. elongation of pins before 90° bend\n                self.pinw = [0.7, 0.5];  # width,height of pins\n                self.tags = []  # description/keywords\n                self.pin_offset_z = 4.55\n                self.staggered_rm = [5.08,2.54]  # y-distance between pins\n                self.staggered_pin_offset_z = 4.5  # z-offset of back-pins in staggered mode\n                self.staggered_pin_minlength= 3.3  # y-offset of back-pins in staggered mode\n                self.staggered_pad = [1.8, 1.8]  # width/height of pads            if largepads:\n            if largepads:\n                self.tags.append(\"large pads\")\n                self.pad = [2, 3.5]\n                self.largepads = True\n\n        elif (name == \"TO-220F\"):\n            if pins==2:\n                self.webpage=\"http://www.onsemi.com/pub/Collateral/FFPF10F150S-D.pdf\"\n            if pins==3:\n                self.webpage=\"http://www.st.com/resource/en/datasheet/stp20nm60.pdf\"\n            if pins==4:\n                self.webpage=\"https://www.njr.com/semicon/PDF/package/TO-220F-4_E.pdf\"\n            self.plastic = [10.26, 15.87-6.68, 4.7]  # width,heigth,depth of plastic package, starting at bottom-left\n            self.metal = [self.plastic[0], 15.87, 2.52]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n            self.pins = 3  # number of pins\n            self.rm = 2.54  # pin distance\n            self.pad = [2, 2]  # width/height of pads\n            self.drill = 1.2  # diameter of pad drills\n            self.name = name  # name of package\n            self.mounting_hole_pos = [self.plastic[0] / 2,\n                                      self.metal[1] - 3.3]  # position of mounting hole from bottom-left\n            self.mounting_hole_diameter = 3.7  # diameter of mounting hole in package\n            self.mounting_hole_drill = 3.5  # diameter of mounting hole drill\n            self.pin_minlength = 3.23  # min. elongation of pins before 90° bend\n            self.pinw = [0.6, 0.7];  # width,height of pins\n            self.tags = []  # description/keywords\n            self.pin_offset_z = 2.76+0.575/2\n            self.staggered_rm = [3.7,3.8]# y-distance between pins\n            self.staggered_pin_offset_z = 4.5  # z-offset of back-pins in staggered mode\n            self.staggered_pin_minlength = 2.05  # y-offset of back-pins in staggered mode\n            self.staggered_pad = [1.8, 1.8]  # width/height of pads\n            if pins == 5:\n                self.tags.append(\"PentawattF-\")\n                self.tags.append(\"MultiwattF-5\")\n                #self.more_packnames.append(\"Pentawatt\")\n                #self.more_packnames.append(\"Multiwatt-5\")\n                self.staggered_pin_minlength = 2.05+1.28  # y-offset of back-pins in staggered mode\n                self.rm = 1.7\n                self.pad = [1.3, 1.8]\n            if pins == 9:\n                self.pinw = [0.5, 0.38];\n                self.drill = 0.7\n                self.pad = [1.3, 1.3]\n                self.staggered_pad = [1.5, 1.5]  # width/height of pads\n            if pins >9:\n                if pins==11:\n                    self.webpage=\"http://www.ti.com/lit/ds/symlink/lm3886.pdf\"\n                self.plastic = [20.02, 10.64, 4.5]  # width,heigth,depth of plastic package, starting at bottom-left\n                self.metal = [self.plastic[0], 19.58,3.3]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n                self.metal_angled = [2.84,2.84]\n                self.pins = pins  # number of pins\n                self.rm = 1.7  # pin distance\n                self.pad = [1.8, 1.8]  # width/height of pads\n                self.drill = 1  # diameter of pad drills\n                self.name = name+\"-{0}\".format(pins)  # name of package\n                self.addpinstext=False\n                self.mounting_hole_pos = [self.plastic[0] / 2, 17.5-2.8]  # position of mounting hole from bottom-left\n                self.mounting_hole_diameter = 3.7  # diameter of mounting hole in package\n                self.mounting_hole_drill = 3.5  # diameter of mounting hole drill\n                self.pin_minlength = 3.81  # min. elongation of pins before 90° bend\n                self.pinw = [0.7, 0.5];  # width,height of pins\n                self.tags = []  # description/keywords\n                self.pin_offset_z = 4.29\n                self.staggered_rm = [5.08,2.54]  # y-distance between pins\n                self.staggered_pin_offset_z = 4.5  # z-offset of back-pins in staggered mode\n                self.staggered_pin_minlength= 3.3  # y-offset of back-pins in staggered mode\n                self.staggered_pad = [1.8, 1.8]  # width/height of pads\n                self.tags.append(\"MultiwattF-{0}\".format(pins))\n                #self.more_packnames.append(\"Multiwatt-{0}\".format(pins))\n            if largepads:\n                self.tags.append(\"large pads\")\n                self.pad = [2, 3.5]\n                self.largepads = True\n\n\n        elif (name == \"Multiwatt\"):\n            self.plastic = [20.2, 10.7, 5]  # width,heigth,depth of plastic package, starting at bottom-left\n            self.metal = [self.plastic[0], 17.5,1.6]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n            self.metal_angled = [2.25,2.25]\n            self.pins = 15  # number of pins\n            self.rm = 1.3  # pin distance\n            self.pad = [1.8, 1.8]  # width/height of pads\n            self.drill = 1  # diameter of pad drills\n            self.name = name+\"-{0}\".format(pins)  # name of package\n            self.addpinstext=False\n            self.mounting_hole_pos = [self.plastic[0] / 2, 17.5-2.8]  # position of mounting hole from bottom-left\n            self.mounting_hole_diameter = 3.7  # diameter of mounting hole in package\n            self.mounting_hole_drill = 3.5  # diameter of mounting hole drill\n            self.pin_minlength = 3.81  # min. elongation of pins before 90° bend\n            self.pinw = [0.7, 0.5];  # width,height of pins\n            self.tags = []  # description/keywords\n            self.pin_offset_z = 4.55\n            self.staggered_rm = [5.08,2.54]  # y-distance between pins\n            self.staggered_pin_offset_z = 4.5  # z-offset of back-pins in staggered mode\n            self.staggered_pin_minlength= 3.3  # y-offset of back-pins in staggered mode\n            self.staggered_pad = [1.8, 1.8]  # width/height of pads\n            if pins == 5:\n                self.tags.append(\"Pentawatt\")\n                self.more_packnames.append(\"Pentawatt\")\n            if pins != 5:\n                self.tags.append(\"Multiwatt-{0}\".format(pins))\n            if largepads:\n                self.tags.append(\"large pads\")\n                self.pad = [2, 3.5]\n                self.largepads = True\n\n        elif (name == \"TO-126\"):\n            self.webpage=\"https://www.diodes.com/assets/Package-Files/TO126.pdf\"\n            self.plastic = [8, 11, 3.25]  # width,heigth,depth of plastic package, starting at bottom-left\n            self.metal = [0, 0, 0]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n            self.pins = 3  # number of pins\n            self.rm = 2.54  # pin distance\n            self.pad = [1.8, 1.8]  # width/height of pads\n            self.drill = 1  # diameter of pad drills\n            self.name = name  # name of package\n            self.mounting_hole_pos = [self.plastic[0] / 2,\n                                      self.plastic[1] - 3.9]  # position of mounting hole from bottom-left\n            self.mounting_hole_diameter = 3.2  # diameter of mounting hole in package\n            self.mounting_hole_drill = 3.2  # diameter of mounting hole drill\n            self.pin_minlength = 4  # min. elongation of pins before 90° bend\n            self.pinw = [0.75, 0.5];  # width,height of pins\n            self.tags = []  # description/keywords\n            self.pin_offset_z = 2\n            if largepads:\n                self.tags.append(\"large pads\")\n                self.pad = [2.0, 2.3]\n                self.largepads = True\n\n        elif (name == \"TO-251\"):\n            self.webpage=\"https://www.diodes.com/assets/Package-Files/TO251.pdf\"\n            self.plastic = [6.58, 6.1, 2.3]  # width,heigth,depth of plastic package, starting at bottom-left\n            self.metal = [5.34, 7, 0.5]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n            self.pins = 3  # number of pins\n            self.rm = 2.29  # pin distance\n            self.pad = [1.8, 1.8]  # width/height of pads\n            self.drill = 1.1  # diameter of pad drills\n            self.name = name  # name of package\n            self.mounting_hole_pos = [self.plastic[0] / 2,\n                                      self.plastic[1] - 3.9]  # position of mounting hole from bottom-left\n            self.mounting_hole_diameter = 0  # diameter of mounting hole in package\n            self.mounting_hole_drill = 0  # diameter of mounting hole drill\n            self.pin_minlength = 2.5  # min. elongation of pins before 90° bend\n            self.pinw = [0.75, 0.5];  # width,height of pins\n            self.tags = [\"IPAK\"]  # description/keywords\n            #self.more_packnames.append(\"IPAK\")\n            self.pin_offset_z = 1.27\n            self.additional_pin_pad_size = [5.7, 6.2]  # Größe des Zusatz-SMD-Pads\n            self.metal_offset_x = (self.plastic[0] - self.metal[0]) / 2  # offset of metal from left\n            if largepads:\n                self.tags.append(\"large pads\")\n                self.pad = [1.8, 1.8]\n                self.additional_pin_pad_size = [6.3, 6.5]  # Größe des Zusatz-SMD-Pads\n                self.largepads = True\n            self.additional_pin_pad = [self.plastic[0] / 2, self.metal[1] - self.additional_pin_pad_size[\n                1] / 3]  # Position des Zusatz-SMD-Pads\n\n        elif (name == \"SIPAK\"):\n            self.plastic = [6.6, 6.4, 2.3]  # width,heigth,depth of plastic package, starting at bottom-left\n            self.metal = [5.33, 7.12, 0.4]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n            self.pins = 3  # number of pins\n            self.rm = 2.286  # pin distance\n            self.pad = [1.8, 1.8]  # width/height of pads\n            self.drill = 1.1  # diameter of pad drills\n            self.name = name  # name of package\n            self.mounting_hole_pos = [self.plastic[0] / 2,\n                                      self.plastic[1] - 3.9]  # position of mounting hole from bottom-left\n            self.mounting_hole_diameter = 0  # diameter of mounting hole in package\n            self.mounting_hole_drill = 0  # diameter of mounting hole drill\n            self.pin_minlength = 1.02  # min. elongation of pins before 90° bend\n            self.pinw = [0.9, 0.5];  # width,height of pins\n            self.tags = []   # description/keywords\n            self.pin_offset_z = 1.17+0.25\n            self.addpinstext=False\n            self.additional_pin_pad_size = [5.5, 6.2]  # Größe des Zusatz-SMD-Pads\n            self.metal_offset_x = (self.plastic[0] - self.metal[0]) / 2  # offset of metal from left\n            if largepads:\n                self.tags.append(\"large pads\")\n                self.pad = [1.8, 1.8]\n                self.additional_pin_pad_size = [6.3, 6.5]  # Größe des Zusatz-SMD-Pads\n                self.largepads = True\n            self.additional_pin_pad = [self.plastic[0] / 2, self.metal[1] - self.additional_pin_pad_size[\n                1] / 3]  # Position des Zusatz-SMD-Pads\n\n\n        elif (name == \"TO-262\"):\n            self.webpage=\"http://www.onsemi.com/pub/Collateral/EN8586-D.PDF\"\n            if pins==5:\n                self.webpage=\"http://pdf.datasheetcatalog.com/datasheet/irf/iris4011.pdf\"\n            self.plastic = [10, 9.2, 4.5]  # width,heigth,depth of plastic package, starting at bottom-left\n            self.metal = [10, 10.4, 1.3]  # width,heigth,thickness of metal plate, starting at metal_offset from bottom-left\n            self.pins = 3  # number of pins\n            self.rm = 2.54  # pin distance\n            self.pad = [2, 2]  # width/height of pads\n            self.drill = 1.1  # diameter of pad drills\n            self.name = name  # name of package\n            self.mounting_hole_pos = [self.plastic[0] / 2,\n                                      self.plastic[1] - 3.9]  # position of mounting hole from bottom-left\n            self.mounting_hole_diameter = 0  # diameter of mounting hole in package\n            self.mounting_hole_drill = 0  # diameter of mounting hole drill\n            self.pin_minlength = 3.25  # min. elongation of pins before 90° bend\n            self.pinw = [0.8, 0.5];  # width,height of pins\n            self.tags = [\"IIPAK\", \"I2PAK\"]  # description/keywords\n            #self.more_packnames.append(\"I2PAK\")\n            self.pin_offset_z = 2.65\n            self.additional_pin_pad_size = [10, 8]  # Größe des Zusatz-SMD-Pads\n            self.metal_offset_x = (self.plastic[0] - self.metal[0]) / 2  # offset of metal from left\n            if largepads:\n                self.tags.append(\"large pads\")\n                self.pad = [1.8, 1.8]\n                self.additional_pin_pad_size = [6.3, 6.5]  # Größe des Zusatz-SMD-Pads\n                self.largepads = True\n            self.additional_pin_pad = [self.plastic[0] / 2, self.metal[1] - self.additional_pin_pad_size[\n                1] / 3]  # Position des Zusatz-SMD-Pads\n        else:\n            print(\"DID NOT FIND '\", name,\"'\")\n            self.__init__()\n\n        if rm > 0:\n            self.rm = rm\n        if self.addpinstext:\n            self.name = \"{0}-{1}\".format(self.name, pins)\n        if pins != 3:\n            self.pins = pins\n            if rm <= 0:\n                self.rm = 2 * self.rm / (pins - 1)\n            else:\n                self.rm = rm;\n        self.pin_offset_x = (self.plastic[0] - (self.pins - 1) * self.rm) / 2\n        if len(self.rm_list)>0:\n            pl=0\n            for rm in self.rm_list:\n                pl=pl+rm\n            self.pin_offset_x = (self.plastic[0] - pl) / 2\n        self.pad[0] = min(self.pad[0], 0.75 * self.rm)\n        if self.largepads:\n            self.tags.append(\"large pads\")\n        if self.staggered_type==1:\n            self.tags.append(\"staggered type-1\")\n            self.fpnametags=[\"StaggeredType1\"]+self.fpnametags\n        if self.staggered_type==2:\n            self.tags.append(\"staggered type-2\")\n            self.fpnametags=[\"StaggeredType2\"] + self.fpnametags\n\n        if pitchy>0:\n            self.staggered_rm = [pitchy,pitchy]  # y-distance between pins\n\n        if ypinoffset!=0:\n            self.pin_offset_z = ypinoffset\n\ncrt_offset = 0.25\nslk_offset = 0.12\nslk_dist = 0.15\nlw_fab = 0.1\nlw_crt = 0.05\nlw_slk = 0.12\ntxt_offset = 1\n"
  },
  {
    "path": "scripts/Packages/TO_SOT_THT/tools.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\nimport time\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"..\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\n\n\n# round for grid g\ndef roundG(x, g):\n    if (x>0):\n        return math.ceil(x/g)*g\n    else:\n        return math.floor(x/g)*g\n\n# round for courtyard grid\ndef roundCrt(x):\n    return roundG(x, 0.01)\n\n# float-variant of range()\ndef frange(x, y, jump):\n  while x < y:\n    yield x\n    x += jump\n\n# inclusice float-variant of range()\ndef frangei(x, y, jump):\n  while x <= y:\n    yield x\n    x += jump\n\n# returns a list with a single rectangle around x,y with width and height w and h\ndef addKeepoutRect(x, y, w, h):\n  return [[x - w / 2, x + w / 2, y - h / 2, y + h / 2]]\n\n\n# returns a series of rectangle that lie around the circular pad around (x,y) with radius w=h\n# if w!=h, addKeepoutRect() is called\ndef addKeepoutRound(x,y, w,h):\n    if w!=h:\n        return addKeepoutRect(x,y,w,h)\n    else:\n        res=[]\n        Nrects=4\n        r=max(h,w)/2\n        yysum=0\n        for ya in frange(0,r,r/Nrects):\n            a=math.fabs(math.asin(ya/r)/math.pi*180)\n            yy=math.fabs(r*math.sin(a/180.0*math.pi))\n            xx=math.fabs(r*math.cos(a/180.0*math.pi))\n            if (xx>0):\n                res.append([x - xx-0.015, x + xx+0.015, y-yy-r/Nrects-0.015, y-yy+.015])\n                res.append([x - xx-0.015, x + xx+0.015, y+yy-0.015, y+yy+r/Nrects+0.015])\n            yysum=yysum+yy\n        return res\n\n\n\ndef applyKeepouts(lines_in, y, xi, yi, keepouts):\n    #print(\"  applyKeepouts(\\n  lines_in=\", lines_in, \"  \\n  y=\", y, \"   \\n  xi=\", xi, \"   yi=\", yi, \"   \\n  keepouts=\", keepouts, \")\")\n    lines=lines_in\n    changes = True\n    while (changes):\n        changes = False\n        for ko in keepouts:\n            ko = [min(ko[0], ko[1]), max(ko[0], ko[1]), min(ko[2], ko[3]), max(ko[2], ko[3])]\n            if (ko[yi+0] <= y) and (y <= ko[yi+1]):\n                #print(\"    INY: koy=\", [ko[yi + 0], ko[yi + 1]], \"  y=\", y, \"):             kox=\", [ko[xi + 0], ko[xi + 1]])\n                for li in reversed(range(0, len(lines))):\n                    l = lines[li]\n                    if (l[0] >= ko[xi+0]) and (l[0] <= ko[xi+1]) and (l[1] >= ko[xi+0]) and (l[1] <= ko[xi+1]):  # Line completely inside -> remove\n                        lines.pop(li)\n                        #print(\"      H1: ko=\", [ko[xi+0],ko[xi+1]], \"  li=\", li, \"   l=\", l, \")\")\n                        changes = True\n                    elif (l[0] >= ko[xi+0]) and (l[0] <= ko[xi+1]) and (l[1] > ko[xi+1]):  # Line starts inside, but ends outside -> remove and add shortened\n                        lines.pop(li)\n                        lines.append([ko[xi+1], l[1]])\n                        #print(\"      H2: ko=\", [ko[xi+0],ko[xi+1]], \"  li=\", li, \"   l=\", l, \"): \", [ko[xi+1], l[1]])\n                        changes = True\n                    elif (l[0] < ko[xi+0]) and (l[1] <= ko[xi+1]) and (l[1] >= ko[xi+0]):  # Line starts outside, but ends inside -> remove and add shortened\n                        lines.pop(li)\n                        lines.append([l[0], ko[xi+0]])\n                        #print(\"      H3: ko=\", [ko[xi+0],ko[xi+1]], \"  li=\", li, \"   l=\", l, \"): \", [l[0], ko[xi+0]])\n                        changes = True\n                    elif (l[0] < ko[xi+0]) and (l[1] > ko[xi+1]):  # Line starts outside, and ends outside -> remove and add 2 shortened\n                        lines.pop(li)\n                        lines.append([l[0], ko[xi+0]])\n                        lines.append([ko[xi+1], l[1]])\n                        #print(\"      H4: ko=\", [ko[xi+0],ko[xi+1]], \"  li=\", li, \"   l=\", l, \"): \", [l[0], ko[xi+0]], [ko[xi+1], l[1]])\n                        changes = True\n                    #else:\n                        #print(\"      USE: ko=\", [ko[xi+0],ko[xi+1]], \"  li=\", li, \"   l=\", l, \"): \")\n        if changes:\n            break\n\n    return lines\n\n\n\n#split a vertical line so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\ndef addHLineWithKeepout(kicad_mod, x0, x1, y,layer, width, keepouts=[], roun=0.001):\n    #print(\"addHLineWithKeepout\",y)\n    linesout = applyKeepouts([[min(x0,x1), max(x0,x1)]], y, 0,2,keepouts)\n    for l in linesout:\n        kicad_mod.append(Line(start=[roundG(l[0], roun), roundG(y, roun)], end=[roundG(l[1], roun), roundG(y, roun)], layer=layer, width=width))\n\n# split a vertical line into dashes, so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\ndef addHDLineWithKeepout(kicad_mod, x0, dx, x1, y, layer, width, keepouts=[], roun=0.001):\n    #print(\"addHDLineWithKeepout\",y)\n    x=min(x0,x1)\n    lines=[]\n    on=True\n    while (x+dx)<=max(x0,x1):\n        if (on):\n            lines.append([x,x+dx])\n        x=x+dx\n        on=not on\n    if (x<max(x0,x1)) and on:\n        lines.append([x, max(x0,x1)])\n    if len(lines)<=0:\n        return\n\n    linesout = applyKeepouts(lines, y, 0, 2, keepouts)\n\n    for l in linesout:\n        kicad_mod.append(Line(start=[roundG(l[0], roun), roundG(y, roun)], end=[roundG(l[1], roun), roundG(y, roun)],layer=layer, width=width))\n\n\n\n#split a vertical line so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\ndef addVLineWithKeepout(kicad_mod, x, y0, y1,layer, width, keepouts=[], roun=0.001):\n    #print(\"addVLineWithKeepout\",x)\n    linesout = applyKeepouts([[min(y0,y1), max(y0,y1)]], x, 2, 0, keepouts)\n    for l in linesout:\n        kicad_mod.append(Line(start=[roundG(x, roun), roundG(l[0], roun)], end=[roundG(x, roun), roundG(l[1], roun)], layer=layer, width=width))\n\n# split a vertical line so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\ndef addVDLineWithKeepout(kicad_mod, x, y0, dy, y1, layer, width, keepouts=[], roun=0.001):\n    #print(\"addVDLineWithKeepout\",x)\n    y=min(y0,y1)\n    lines=[]\n\n    on=True\n    while (y+dy)<=max(y0,y1):\n        if (on):\n            lines.append([y,y+dy])\n        y=y+dy\n        on=not on\n    if (y<max(y0,y1)) and on:\n        lines.append([y, max(y0,y1)])\n\n    linesout = applyKeepouts(lines, x, 2, 0, keepouts)\n    for l in linesout:\n        kicad_mod.append(Line(start=[roundG(x, roun), roundG(l[0], roun)], end=[roundG(x, roun), roundG(l[1], roun)], layer=layer, width=width))\n\n\n# add a rectangle that has two angled corners at the top\ndef addRectAngledTop(kicad_mod, x1, x2, angled_delta, layer, width, roun=0.001):\n    xmi=min(x1[0], x2[0])\n    xma = max(x1[0], x2[0])\n    xa=xma-angled_delta[0]\n    xl = xmi + angled_delta[0]\n    ymi=max(x1[1], x2[1])\n    yma = min(x1[1], x2[1])\n    ya = yma + angled_delta[1]\n    kicad_mod.append(\n        PolygoneLine(polygone=[[roundG(xmi, roun),roundG(ymi, roun)], [roundG(xmi, roun),roundG(ya, roun)],\n                               [roundG(xl, roun), roundG(yma, roun)],\n                               [roundG(xa, roun), roundG(yma, roun)],\n                               [roundG(xma, roun),roundG(ya, roun)],\n                               [roundG(xma, roun),roundG(ymi, roun)],\n                               [roundG(xmi, roun),roundG(ymi, roun)]], layer=layer, width=width))\n\n\n\n\n# add a rectangle that has two angled corners at the top\ndef addRectAngledTopNoBottom(kicad_mod, x1, x2, angled_delta, layer, width, roun=0.001):\n    xmi=min(x1[0], x2[0])\n    xma = max(x1[0], x2[0])\n    xa=xma-angled_delta[0]\n    xl = xmi + angled_delta[0]\n    ymi=max(x1[1], x2[1])\n    yma = min(x1[1], x2[1])\n    ya = yma + angled_delta[1]\n    kicad_mod.append(\n        PolygoneLine(polygone=[[roundG(xmi, roun),roundG(ymi, roun)], [roundG(xmi, roun),roundG(ya, roun)],\n                               [roundG(xl, roun), roundG(yma, roun)],\n                               [roundG(xa, roun), roundG(yma, roun)],\n                               [roundG(xma, roun),roundG(ya, roun)],\n                               [roundG(xma, roun),roundG(ymi, roun)]], layer=layer, width=width))\n\n\n# add a rectangle that has two angled corners at the bottom\ndef addRectAngledBottom(kicad_mod, x1, x2, angled_delta, layer, width, roun=0.001):\n    xmi=min(x1[0], x2[0])\n    xma = max(x1[0], x2[0])\n    xa=xma-angled_delta[0]\n    xl = xmi + angled_delta[0]\n    ymi=min(x1[1], x2[1])\n    yma = max(x1[1], x2[1])\n    ya = yma - angled_delta[1]\n    kicad_mod.append(\n        PolygoneLine(polygone=[[roundG(xmi, roun),roundG(ymi, roun)], [roundG(xmi, roun),roundG(ya, roun)],\n                               [roundG(xl, roun), roundG(yma, roun)],\n                               [roundG(xa, roun), roundG(yma, roun)],\n                               [roundG(xma, roun),roundG(ya, roun)],\n                               [roundG(xma, roun),roundG(ymi, roun)],\n                               [roundG(xmi, roun),roundG(ymi, roun)]], layer=layer, width=width))\n\n# add a circle which is filled with 45° lines\ndef addCircleLF(kicad_mod, center, radius, layer, width, linedist=0.3, roun=0.001):\n    trans=Translation(center[0], center[1])\n    kicad_mod.append(trans)\n    rend=roundG(radius, linedist)+linedist\n    M11=math.cos(45/180*math.pi)\n    M12 = -math.sin(45 / 180 * math.pi)\n    M21 = math.sin(45 / 180 * math.pi)\n    M22=math.cos(45/180*math.pi)\n    for y in frangei(-rend,rend, linedist):\n        if y*y <= radius*radius:\n            x1 = -math.sqrt(radius*radius-y*y)\n            x2 = -x1\n            if x1!=x2:\n                #print([roundG(x1, roun),roundG(y, roun)], [roundG(x2, roun),roundG(y, roun)])\n                trans.append(Line(start=[roundG(M11*x1+M12*y, roun),roundG(M21*x1+M22*y, roun)], end=[roundG(M11*x2+M12*y, roun),roundG(M21*x2+M22*y, roun)], layer=layer, width=width))\n\n\n    kicad_mod.append(Circle(center=[roundG(center[0], roun), roundG(center[1], roun)], radius=roundG(radius, roun), layer=layer,  width=width))\n"
  },
  {
    "path": "scripts/Packages/ipc_definitions.yaml",
    "content": "ipc_generic_rules:\n  min_ep_to_pad_clearance: 0.2\n\n# IPC IPC-7351 http://pcbget.ru/Files/Standarts/IPC_7351.pdf\n# Page 23\n# Updated with IPC-7351 B values (sadly no openly accessible document available)\n\n# Gull-Wing (L-Lead) pitch > 0.625\n#           | Minimum | Median    | Maximum |\n#           | (Least) | (Nominal) | (Most)  |\n#           | Density | Density   | Density | round\n# Lead Part | Level C | Level B   | Level A |  to\n# ----------+---------+-----------+---------+-\n# Toe       | 0.15    | 0.35      | 0.55    | 0.2\n# Heel      | 0.25    | 0.35      | 0.45    | 0.2\n# Side      | 0.01    | 0.03      | 0.05    | 0.05\n# Courtyard | 0.1     | 0.25      | 0.5     |\n\nipc_spec_gw_large_pitch:\n    least:\n        toe: 0.15\n        heel: 0.25\n        side: 0.01\n        courtyard: 0.1\n    nominal:\n        toe: 0.35\n        heel: 0.35\n        side: 0.03\n        courtyard: 0.25\n    most:\n        toe: 0.55\n        heel: 0.45\n        side: 0.05\n        courtyard: 0.5\n    round_base:\n        toe: 0.05\n        heel: 0.05\n        side: 0.05\n\n# Gull-Wing (L-Lead) pitch <= 0.625\n#           | Minimum | Median    | Maximum |\n#           | (Least) | (Nominal) | (Most)  |\n#           | Density | Density   | Density | round\n# Lead Part | Level C | Level B   | Level A |  to\n# ----------+---------+-----------+---------+-\n# Toe       | 0.15    | 0.35      | 0.55    | 0.05\n# Heel      | 0.25    | 0.35      | 0.45    | 0.05\n# Side      | -0.04   | -0.02     | 0.01    | 0.05\n# Courtyard | 0.1     | 0.25      | 0.5     |\n\nipc_spec_gw_small_pitch:\n    least:\n        toe: 0.15\n        heel: 0.25\n        side: -0.04\n        courtyard: 0.1\n    nominal:\n        toe: 0.35\n        heel: 0.35\n        side: -0.02\n        courtyard: 0.25\n    most:\n        toe: 0.55\n        heel: 0.45\n        side: 0.01\n        courtyard: 0.5\n    round_base:\n        toe: 0.05\n        heel: 0.05\n        side: 0.05\n\n# J Lead\n#           | Minimum | Median    | Maximum |\n#           | (Least) | (Nominal) | (Most)  |\n#           | Density | Density   | Density | round\n# Lead Part | Level C | Level B   | Level A |  to\n# ----------+---------+-----------+---------+-\n# Toe       | -0.1    | 0.0       | 0.1     | 0.05\n# Heel      | 0.15    | 0.35      | 0.55    | 0.05\n# Side      | 0.01    | 0.03      | 0.05    | 0.05\n# Courtyard | 0.1     | 0.25      | 0.5     |\n\nipc_spec_j_lead:\n    least:\n        toe: -0.1\n        heel: 0.15\n        side: 0.01\n        courtyard: 0.1\n    nominal:\n        toe: 0.0\n        heel: 0.35\n        side: 0.03\n        courtyard: 0.25\n    most:\n        toe: 0.1\n        heel: 0.25\n        side: 0.05\n        courtyard: 0.5\n    round_base:\n        toe: 0.05\n        heel: 0.05\n        side: 0.05\n\n# Flat No Lead (DFN/QFN) with toe fillet\n#           | Minimum | Median    | Maximum |\n#           | (Least) | (Nominal) | (Most)  |\n#           | Density | Density   | Density | round\n# Lead Part | Level C | Level B   | Level A |  to\n# ----------+---------+-----------+---------+-\n# Toe       | 0.2     | 0.3       | 0.4     | 0.05\n# Heel      | 0.0     | 0.0       | 0.0     | 0.05\n# Side      | -0.04   | -0.04     | -0.04   | 0.05\n# Courtyard | 0.1     | 0.25      | 0.5     |\n\nipc_spec_flat_no_lead:\n    least:\n        toe: 0.2\n        heel: 0.0\n        side: -0.04\n        courtyard: 0.1\n    nominal:\n        toe: 0.3\n        heel: 0.0\n        side: -0.04\n        courtyard: 0.25\n    most:\n        toe: 0.4\n        heel: 0.0\n        side: -0.04\n        courtyard: 0.5\n    round_base:\n        toe: 0.05\n        heel: 0.05\n        side: 0.05\n\n# Flat No Lead pull back\n#\n#           | Minimum | Median    | Maximum |\n#           | (Least) | (Nominal) | (Most)  |\n#           | Density | Density   | Density | round\n# Lead Part | Level C | Level B   | Level A |  to\n# ----------+---------+-----------+---------+-\n# Toe       | -0.05    | 0.0      | 0.05    | 0.05\n# Heel      | -0.05    | 0.0      | 0.05    | 0.05\n# Side      | -0.05   | -0.0      | 0.05    | 0.05\n# Courtyard | 0.1     | 0.25      | 0.5     |\n\nipc_spec_flat_no_lead_pull_back:\n    least:\n        toe: -0.05\n        heel: -0.05\n        side: -0.05\n        courtyard: 0.1\n    nominal:\n        toe: 0.0\n        heel: 0.0\n        side: 0.0\n        courtyard: 0.25\n    most:\n        toe: 0.05\n        heel: 0.05\n        side: 0.05\n        courtyard: 0.5\n    round_base:\n        toe: 0.05\n        heel: 0.05\n        side: 0.05\n"
  },
  {
    "path": "scripts/Packages/package_config_KLCv3.yaml",
    "content": "fp_name_format_string: '{man:s}_{mpn:s}_{pkg:s}-{pincount:d}_{size_x:.1f}x{size_y:.1f}mm_P{pitch:.2f}mm{suffix:s}'\nfp_name_format_string_pincount_text: '{man:s}_{mpn:s}_{pkg:s}-{pincount:s}_{size_x:.1f}x{size_y:.1f}mm_P{pitch:.2f}mm{suffix:s}'\n\nkeyword_fp_string: '{man:s} {package:s} {category:s}'\n\nlib_name_format_string: 'Package_{category:s}'\n\nfp_name_format_string_no_trailing_zero: '{man:s}_{mpn:s}_{pkg:s}-{pincount:d}_{size_x:g}x{size_y:g}mm_P{pitch:g}mm{suffix:s}{suffix2:s}'\nfp_name_format_string_no_trailing_zero_pincount_text: '{man:s}_{mpn:s}_{pkg:s}-{pincount:s}_{size_x:g}x{size_y:g}mm_P{pitch:g}mm{suffix:s}{suffix2:s}'\n\nfp_name_lga_format_string_no_trailing_zero: '{man:s}_{mpn:s}_{pkg:s}-{pincount:d}_{size_x:g}x{size_y:g}mm_P{pitch:g}mm{layout:s}{suffix:s}{suffix2:s}'\n\nlga_layout_grid: '_LayoutGrid{nx:d}x{ny:d}'\nlga_layout_border: '_LayoutBorder{nx:d}x{ny:d}y'\n\nfp_name_EP_format_string_no_trailing_zero: '{man:s}_{mpn:s}_{pkg:s}-{pincount:d}-1EP_{size_x:g}x{size_y:g}mm_P{pitch:g}mm{suffix:s}_EP{ep_size_x:g}x{ep_size_y:g}mm{suffix2:s}{vias:s}'\nfp_name_EP_format_string_no_trailing_zero_pincount_text: '{man:s}_{mpn:s}_{pkg:s}-{pincount:s}-1EP_{size_x:g}x{size_y:g}mm_P{pitch:g}mm{suffix:s}_EP{ep_size_x:g}x{ep_size_y:g}mm{suffix2:s}{vias:s}'\n\nfp_name_EP_custom_mask_format_string_no_trailing_zero: '{man:s}_{mpn:s}_{pkg:s}-{pincount:d}-1EP_{size_x:g}x{size_y:g}mm_P{pitch:g}mm{suffix:s}_EP{ep_size_x:g}x{ep_size_y:g}mm_Mask{mask_size_x:g}x{mask_size_y:g}mm{suffix2:s}{vias:s}'\nfp_name_EP_custom_mask_format_string_no_trailing_zero_pincount_text: '{man:s}_{mpn:s}_{pkg:s}-{pincount:s}-1EP_{size_x:g}x{size_y:g}mm_P{pitch:g}mm{suffix:s}_EP{ep_size_x:g}x{ep_size_y:g}mm_Mask{mask_size_x:g}x{mask_size_y:g}mm{suffix2:s}{vias:s}'\n\nthermal_via_suffix: \"_ThermalVias\"\n"
  },
  {
    "path": "scripts/Packages/utils/ep_handling_utils.py",
    "content": "#!/usr/bin/env python3\n\nfrom KicadModTree.nodes.base.Pad import Pad\n\ndef getEpRoundRadiusParams(device_params, configuration, pad_radius):\n    pad_shape_details = {}\n    pad_shape_details['shape'] = Pad.SHAPE_ROUNDRECT\n\n    pad_shape_details['paste_radius_ratio'] = configuration['paste_radius_ratio']\n    pad_shape_details['paste_maximum_radius'] = configuration['paste_maximum_radius']\n\n    if 'EP_round_radius' in device_params:\n        if type(device_params['EP_round_radius']) in [float, int]:\n            pad_shape_details['round_radius_exact'] = device_params['EP_round_radius']\n        elif device_params['EP_round_radius'] == \"pad\":\n            pad_shape_details['round_radius_exact'] = pad_radius\n        else:\n            raise TypeError(\n                    \"round radius must be a number or 'pad', is {}\"\n                    .format(type(device_params['EP_round_radius']))\n                    )\n    elif 'EP_round_radius_ratio' in device_params:\n        pad_shape_details['radius_ratio'] = device_params['EP_round_radius_ratio']\n    elif 'EP_round_radius_ratio' in configuration:\n        pad_shape_details['radius_ratio'] = configuration['EP_round_radius_ratio']\n    else:\n        pad_shape_details['radius_ratio'] = 0\n\n    if 'radius_ratio' in pad_shape_details and pad_shape_details['radius_ratio'] > 0:\n        if 'EP_maximum_radius' in device_params:\n            pad_shape_details['maximum_radius'] = device_params['EP_maximum_radius']\n        elif 'EP_maximum_radius' in configuration:\n            pad_shape_details['maximum_radius'] = configuration['EP_maximum_radius']\n        else:\n            pad_shape_details['maximum_radius'] = 0.25\n\n    return pad_shape_details\n"
  },
  {
    "path": "scripts/PadGenerator/RingPad.py",
    "content": "import sys\nimport os\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\"))\n\nimport argparse\nfrom KicadModTree import *\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='Commandline tool for generating ring pads.')\n    parser.add_argument('-n', '--name', metavar='fp_name', type=str,\n                        help='Name of the generated footprint. default: output', default='output')\n    parser.add_argument('--at', type=float, nargs=2, help='position of the pad, default: at origin', default=[0,0], metavar=('x', 'y'))\n    parser.add_argument('-v', '--verbose', action='count', help='set debug level')\n    parser.add_argument('-i', '--inner_diameter', type=float, help='inside diameter', required=True)\n    parser.add_argument('-o', '--outer_diameter', type=float, help='outside diameter', required=True)\n    parser.add_argument('-p', '--number', type=str, help='the pin number, default: 1', default='1')\n    parser.add_argument('--anchor_count', type=int, help='number of anchor (trace connection points), default: 4', default=4)\n    parser.add_argument('--paste_count', type=int, help='number of paste areas, default: 4', default=4)\n    parser.add_argument('--paste_round_radius_radio', type=float, help='round radius ratio for the paste pads', default=0.25)\n    parser.add_argument('--paste_clearance', type=float, help='clearance between paste areas', nargs='?')\n    parser.add_argument('--mask_margin', type=float, help='soldermask margin, default:0', default=0)\n    parser.add_argument('--paste_margin', type=float, help='solderpaste margin, default:0 (means controlled by footprint or board setup)', default=0)\n    args = parser.parse_args()\n\nkicad_mod = Footprint(args.name)\n\nkicad_mod.append(\n    RingPad(\n        number=args.number, at=args.at,\n        size=args.outer_diameter, inner_diameter=args.inner_diameter,\n        num_anchor=args.anchor_count, num_paste_zones=args.paste_count,\n        solder_paste_margin=args.paste_margin, solder_mask_margin=args.mask_margin,\n        paste_round_radius_radio=args.paste_round_radius_radio,\n        paste_to_paste_clearance=args.paste_clearance))\n\n\nfile_handler = KicadFileHandler(kicad_mod)\nfile_handler.writeFile(args.name + '.kicad_mod')\n"
  },
  {
    "path": "scripts/Potentiometers/make_Potentiometer_SMD.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom drawing_tools import *\nfrom footprint_scripts_potentiometers import *\n\n\nif __name__ == '__main__':\n    script3d_tsl=\"trimmer_screwleft.py\"\n    with open(script3d_tsl, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_tst=\"trimmer_screwtop.py\"\n    with open(script3d_tst, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_tsl_smd=\"trimmer_screwleft_smd.py\"\n    with open(script3d_tsl_smd, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_tst_smd=\"trimmer_screwtop_smd.py\"\n    with open(script3d_tst_smd, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_pv=\"pots_ver.py\"\n    with open(script3d_pv, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_trv=\"trim_round_ver.py\"\n    with open(script3d_trv, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_trh=\"trim_round_hor.py\"\n    with open(script3d_trh, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_trh_bel=\"trim_round_hor_below.py\"\n    with open(script3d_trh_bel, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_trh_smd=\"trim_round_smd_hor.py\"\n    with open(script3d_trh_smd, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_trh_smd_bel=\"trim_round_smd_hor_below.py\"\n    with open(script3d_trh_smd_bel, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_ph_bel=\"pots_hor_below.py\"\n    with open(script3d_ph_bel, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_ph=\"pots_hor.py\"\n    with open(script3d_ph, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n\n    # this footprint is not generated on-center due to design limitations of footprint_scripts_potentiometers.py\n    class_name=\"Bourns PRS11S\"; add_description=\"http://www.bourns.com/docs/Product-Datasheets/PRS11S.pdf\"\n    pins = 5; rmx=16.5; rmy=2.5; ddrill=1; wbody=13; hbody=11.7; height3d = 7.2; wscrew=4.3; dscrew=6.8\n    wshaft=20-wbody-wscrew; dshaft=6; pinxoffset=1.75; pinyoffset=(hbody-2*rmy)/2.0; dbody=0; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=6.5; c_offsety=hbody/2.0; mh_rmy=11.3\n    makePotentiometerVertical(SMD_pads=True, SMD_padsize=[4,2], mh_ddrill=1.5, mh_count=2, mh_rmx=0, mh_rmy=mh_rmy, mh_xoffset=8.25, mh_yoffset=(mh_rmy-2*rmy)/2.0, mh_nopads=True, shaft_hole=False, class_name=class_name, wbody=wbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n    \n    class_name=\"ACP CA6-VSMD\"; add_description=\"http://www.acptechnologies.com/wp-content/uploads/2017/06/01-ACP-CA6.pdf\"\n    pins = 3; rmx=8.65; rmy=4.3/2.0; ddrill=0.9; wbody=6.5; hbody=6.5; dbody=0; height3d = 4.5+hbody/2.0; screwzpos = 4.5; wscrew=-wbody; dscrew=2\n    wshaft=0; dshaft=1.8; pinxoffset=1.075; pinyoffset=(hbody-2*rmy)/2.0; dbody=0; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=3.525; c_offsety=hbody/2.0; c_ddrill=2.5\n    makePotentiometerVertical(SMD_pads=True, SMD_padsize=[2.5,2], style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=wbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=pinxoffset,pinyoffset=vpinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_smd,height3d=height3d)\n    makePotentiometerVertical(SMD_pads=True, SMD_padsize=[2.5,2], style=\"trimmer\", shaft_hole=True, class_name=class_name, wbody=wbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=pinxoffset,pinyoffset=vpinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_smd_bel,height3d=height3d)\n    \n    class_name=\"ACP CA9-VSMD\"; add_description=\"http://www.acptechnologies.com/wp-content/uploads/2017/05/02-ACP-CA9-CE9.pdf\"\n    pins = 3; rmx=9.25; rmy=2.5; ddrill=1.3; hbody=9.8; wbody=10; dbody=0; screwzpos = 7; wscrew=-wbody; dscrew=3\n    wshaft=0; dshaft=2.1; pinxoffset=-0.375; pinyoffset=(hbody-2*rmy)/2.0; dbody=0; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=5.125; c_offsety=hbody/2.0; c_ddrill=4; height3d=5.5\n    makePotentiometerVertical(SMD_pads=True, SMD_padsize=[2.5,2.5], style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=wbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=pinxoffset,pinyoffset=vpinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_smd,height3d=height3d)\n    makePotentiometerVertical(SMD_pads=True, SMD_padsize=[2.5,2.5], style=\"trimmer\", shaft_hole=True, class_name=class_name, wbody=wbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=pinxoffset,pinyoffset=vpinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_smd_bel,height3d=height3d)\n    \n    class_name=\"ACP CA14-VSMD\"; add_description=\"http://www.acptechnologies.com/wp-content/uploads/2017/10/03-ACP-CA14-CE14.pdf\"\n    pins = 3; rmx=13; rmy=5; dbody=0; pinxoffset=-0.7; wbody=14; hbody=14; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=7; c_offsety=hbody/2.0; c_ddrill=7; height3d=5.8\n    makePotentiometerVertical(SMD_pads=True, SMD_padsize=[3,3], style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=wbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=pinxoffset,pinyoffset=vpinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_smd,height3d=height3d)\n    makePotentiometerVertical(SMD_pads=True, SMD_padsize=[3,3], style=\"trimmer\", shaft_hole=True, class_name=class_name, wbody=wbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=pinxoffset,pinyoffset=vpinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_smd_bel,height3d=height3d)\n\n    class_name=\"Bourns 3214W\"; add_description = \"https://www.bourns.com/docs/Product-Datasheets/3214.pdf\"\n    wbody=4.8; hbody=3.5; pinxoffset=(wbody-2.5)/2.0+2.5; pinyoffset=0.3; height3d = 5.1; rmx2=-1.25; rmy2=2.9; rmx3=-2.5; rmy3=0; ddrill=0.8; dscrew=1.5; wscrew = dscrew; screwxoffset = 1.2; screwyoffset = hbody-1.1\n    style = \"screwtop\"; SMD_pads = True; SMD_padsize = [1.3,1.6,2,1.6,1.3,1.6]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst_smd, height3d=height3d)\n    class_name=\"Bourns 3214X\"\n    wbody=4.8; hbody=3.5; pinxoffset=(wbody-2.5)/2.0+2.5; pinyoffset=-(5.1-3.5)/2.0; height3d = 5.3; rmx2=-1.15; rmy2=5.1; rmx3=-2.3; rmy3=0; ddrill=0.8; dscrew=1.5; wscrew = dscrew; screwxoffset = 1.2; screwyoffset = hbody-1.1\n    style = \"screwtop\"; SMD_pads = True; SMD_padsize = [1.3,1.9,2,1.9,1.3,1.9]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst_smd, height3d=height3d)\n    class_name=\"Bourns 3214G\"\n    wbody=4.6; hbody=4.8; pinxoffset=(wbody-5.2)/2.0+5.2; pinyoffset=(hbody-2.3)/2.0; height3d = 3.71; rmx2=-5.2; rmy2=1.15; rmx3=0; rmy3=2.3; ddrill=0.8; dscrew=1.78; wscrew = 0; screwxoffset = 0; screwyoffset = 1.27\n    style = \"screwleft\"; SMD_pads = True; SMD_padsize = [1.3,1.3,1.3,2,1.3,1.3]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl_smd, height3d=height3d)\n    class_name=\"Bourns 3214J\"\n    wbody=4.6; hbody=4.8; pinxoffset=(wbody-4)/2.0+4; pinyoffset=(hbody-2.3)/2.0; height3d = 3.71; rmx2=-4; rmy2=1.15; rmx3=0; rmy3=2.3; ddrill=0.8; dscrew=1.78; wscrew = 0; screwxoffset = 0; screwyoffset = 1.27\n    style = \"screwleft\"; SMD_pads = True; SMD_padsize = [2,1.3,2,2,2,1.3]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl_smd, height3d=height3d)\n\n    class_name=\"Bourns 3314J\"; add_description = \"http://www.bourns.com/docs/Product-Datasheets/3314.pdf\"\n    pins = 3; wbody=4.5; hbody=4.5; rmx2=-1.15; rmy2=4.0; rmx3=-2.3; rmy3=0; pinxoffset=(wbody+rmx3)/2.0-rmx3; pinyoffset=(hbody-rmy2)/2.0; height3d = 2.55; ddrill=0.8; dscrew=2.0; wscrew = 0; screwxoffset = wbody/2.0; screwyoffset = hbody/2.0\n    style = \"screwtop\"; SMD_pads = True; SMD_padsize = [1.3,2.0,2.0,2.0,1.3,2.0]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst_smd, height3d=height3d)\n    class_name=\"Bourns 3314G\"\n    pinyoffset=-1.25; rmy2 = 5.5; pinxoffset=(wbody+rmx3)/2.0-rmx3; pinyoffset=(hbody-rmy2)/2.0; SMD_padsize = [1.3,1.3,2.0,1.3,1.3,1.3]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst_smd, height3d=height3d)\n    class_name=\"Bourns 3314R-1\"\n    wbody=5.0; pinxoffset=(wbody+rmx3)/2.0-rmx3; screwxoffset = wbody/2.0; ddrill = 3.2\n    makeSpindleTrimmer(shaft_hole=True, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl_smd, height3d=height3d)\n    class_name=\"Bourns 3314R-GM5\"\n    rmx2=-1.155; rmy2 = 6.25; rmx3=-2.31; pinxoffset=(wbody+rmx3)/2.0-rmx3; pinyoffset=(hbody-rmy2)/2.0\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl_smd, height3d=height3d)\n    class_name=\"Bourns 3314S\"\n    wbody = 5.01; rmx2=-1.15; rmy2 = 4.05; rmx3=-2.3; pinxoffset=(wbody+rmx3)/2.0-rmx3; pinyoffset=(hbody-rmy2)/2.0;  height3d = 5.61; screwxoffset = wbody/2.0; style = \"screwleft\"; SMD_padsize = [1.2,1.75,1.6,1.75,1.2,1.75]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl_smd, height3d=height3d)\n\n    class_name=\"Bourns 3224W\"; add_description = \"https://www.bourns.com/docs/Product-Datasheets/3224.pdf\"\n    wbody=4.8; hbody=3.5; pinxoffset=(wbody-2.5)/2.0+2.5; pinyoffset=0.3; height3d = 5.1; rmx2=-1.25; rmy2=2.9; rmx3=-2.5; rmy3=0; ddrill=0.8; dscrew=1.5; wscrew = dscrew; screwxoffset = 1.2; screwyoffset = hbody-1.1\n    style = \"screwtop\"; SMD_pads = True; SMD_padsize = [1.3,1.6,2,1.6,1.3,1.6]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst_smd, height3d=height3d)\n    class_name=\"Bourns 3224X\"\n    wbody=4.8; hbody=3.5; pinxoffset=(wbody-2.5)/2.0+2.5; pinyoffset=-(5.1-3.5)/2.0; height3d = 5.3; rmx2=-1.15; rmy2=5.1; rmx3=-2.3; rmy3=0; ddrill=0.8; dscrew=1.5; wscrew = dscrew; screwxoffset = 1.2; screwyoffset = hbody-1.1\n    style = \"screwtop\"; SMD_pads = True; SMD_padsize = [1.3,1.9,2,1.9,1.3,1.9]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst_smd, height3d=height3d)\n    class_name=\"Bourns 3224G\"\n    wbody=4.6; hbody=4.8; pinxoffset=(wbody-5.2)/2.0+5.2; pinyoffset=(hbody-2.3)/2.0; height3d = 3.71; rmx2=-5.2; rmy2=1.15; rmx3=0; rmy3=2.3; ddrill=0.8; dscrew=1.78; wscrew = 0; screwxoffset = 0; screwyoffset = 1.27\n    style = \"screwleft\"; SMD_pads = True; SMD_padsize = [1.3,1.3,1.3,2,1.3,1.3]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl_smd, height3d=height3d)\n    class_name=\"Bourns 3224J\"\n    wbody=4.6; hbody=4.8; pinxoffset=(wbody-4)/2.0+4; pinyoffset=(hbody-2.3)/2.0; height3d = 3.71; rmx2=-4; rmy2=1.15; rmx3=0; rmy3=2.3; ddrill=0.8; dscrew=1.78; wscrew = 0; screwxoffset = 0; screwyoffset = 1.27\n    style = \"screwleft\"; SMD_pads = True; SMD_padsize = [2,1.3,2,2,2,1.3]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl_smd, height3d=height3d)\n\n    class_name=\"Bourns 3269W\"; add_description = \"https://www.bourns.com/docs/Product-Datasheets/3269.pdf\"\n    wbody=6.35; hbody=4.32; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=-0.25; height3d = 7.44; rmx2=-2.54; rmy2=4.83; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew=1.78; wscrew = dscrew; screwxoffset = wbody-1.002; screwyoffset = hbody-1.52\n    style = \"screwtop\"; SMD_pads = True; SMD_padsize = [1.19,2.79]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst_smd, height3d=height3d)\n    class_name=\"Bourns 3269X\"\n    wbody=6.35; hbody=4.32; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=-0.25; height3d = 7.44; rmx2=-2.54; rmy2=4.83; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew=1.78; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody-1.52\n    style = \"screwleft\"; SMD_pads = True; SMD_padsize = [1.19,2.79]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl_smd, height3d=height3d)\n    class_name=\"Bourns 3269P\"\n    wbody=6.35; hbody=6.35; pinxoffset=-(wbody-6.4)/2.0+6.4; pinyoffset=(hbody-5.08)/2.0; height3d = 5.21; rmx2=-6.4; rmy2=2.54; rmx3=0; rmy3=5.08; ddrill=0.8; dscrew=1.78; wscrew = 1.52; screwxoffset = 0; screwyoffset = 1.27\n    style = \"screwleft\"; SMD_pads = True; SMD_padsize = [3.3,1.19]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl_smd, height3d=height3d)\n\n    class_name=\"Vishay TS53YJ\"; add_description = \"https://www.vishay.com/docs/51008/ts53.pdf\"\n    wbody=5; hbody=5; pinxoffset=0.5+4; pinyoffset=(5-2.3)/2.0; height3d = 2.7; rmx2=-4; rmy2=1.15; rmx3=0; rmy3=2.3; ddrill=0.8; dscrew=2.3; wscrew = dscrew; screwxoffset = wbody/2.0; screwyoffset = hbody/2.0\n    SMD_pads = True; SMD_padsize = [2,1.3,2,2,2,1.3]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, screwstyle=\"cross\", ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=\"screwtop\", SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst_smd, height3d=height3d)\n    class_name=\"Vishay TS53YL\"\n    wbody=5; hbody=5; pinxoffset=-0.25+5.5; pinyoffset=(5-2.3)/2.0; height3d = 2.7; rmx2=-5.5; rmy2=1.15; rmx3=0; rmy3=2.3; ddrill=0.8; dscrew=2.3; wscrew = dscrew; screwxoffset = wbody/2.0; screwyoffset = hbody/2.0\n    SMD_pads = True; SMD_padsize = [1.3,1.3,2,1.3,1.3,1.3]\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, screwstyle=\"cross\", ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=\"screwtop\", SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst_smd, height3d=height3d)\n"
  },
  {
    "path": "scripts/Potentiometers/make_Potentiometer_THT.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom drawing_tools import *\nfrom footprint_scripts_potentiometers import *\n\n\nif __name__ == '__main__':\n    script3d_tsl=\"trimmer_screwleft.py\"\n    with open(script3d_tsl, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_tst=\"trimmer_screwtop.py\"\n    with open(script3d_tst, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_tsl_smd=\"trimmer_screwleft_smd.py\"\n    with open(script3d_tsl_smd, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_tst_smd=\"trimmer_screwtop_smd.py\"\n    with open(script3d_tst_smd, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_pv=\"pots_ver.py\"\n    with open(script3d_pv, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_trv=\"trim_round_ver.py\"\n    with open(script3d_trv, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_trh=\"trim_round_hor.py\"\n    with open(script3d_trh, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_trh_bel=\"trim_round_hor_below.py\"\n    with open(script3d_trh_bel, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_trh_smd=\"trim_round_smd_hor.py\"\n    with open(script3d_trh_smd, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_trh_smd_bel=\"trim_round_smd_hor_below.py\"\n    with open(script3d_trh_smd_bel, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_ph_bel=\"pots_hor_below.py\"\n    with open(script3d_ph_bel, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3d_ph=\"pots_hor.py\"\n    with open(script3d_ph, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n\n    R_POW = 0\n\n    class_name=\"Omeg PC16BU\"; add_description=\"http://www.omeg.co.uk/pc6bubrc.htm\"\n    pins = 3; rmx=5.0; rmy=5.; ddrill=1.3; wbody=9.3; hbody=16.9; height3d = 21; screwzpos = 12.5; wscrew=6; dscrew=7\n    wshaft=50-wscrew; dshaft=4; pinxoffset=6.3; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    voffsetx=1.75; dbody=16.9; vwbody=5; vpinyoffset=(hbody-2*rmy)/2.0; c_offsety=dbody/2.0; c_offsetx=10.8\n    #makePotentiometerVertical(shaft_hole=True, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n    makePotentiometerVertical(shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph,height3d=height3d)\n    \n    class_name=\"Vishay 248GJ-249GJ Single\"; add_description=\"http://www.vishay.com/docs/57054/248249.pdf\"\n    pins = 3; rmx=7.62; rmy=2.54; ddrill=1; wbody=7.6; hbody=12.5; height3d = 13.1; screwzpos = 12.7/2.0+0.6; wscrew=9.5; dscrew=(3/8.0)*25.4\n    wshaft=22.22-wscrew; dshaft=(1/4.0)*25.4; pinxoffset=5.08; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    voffsetx=0.75; dbody=0; vwbody=12.7; vpinyoffset=(hbody-2*rmy)/2.0; c_offsety=hbody/2.0; c_offsetx=vwbody/2.0\n    #makePotentiometerVertical(shaft_hole=True, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n    makePotentiometerVertical(shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph,height3d=height3d)\n    class_name=\"Vishay 248BH-249BH Single\"; add_description=\"http://www.vishay.com/docs/57054/248249.pdf\"\n    wscrew=9.5; dscrew=0.25*25.4; wshaft=19.05-wscrew; dshaft=3.18; pinxoffset=5.08; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n\n    class_name=\"Vishay 148-149 Single\"; add_description=\"http://www.vishay.com/docs/57040/148149.pdf\"\n    pins = 3; rmx=7.62; rmy=2.54; ddrill=1; wbody=8.83; hbody=12.5; height3d = 13.1; screwzpos = 12.5/2.0+0.6; wscrew=6.35; dscrew=0.25*25.4\n    wshaft=12.8-wscrew; dshaft=3.17; pinxoffset=5.08; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    voffsetx=0.75; dbody=0; vwbody=12.5; vpinyoffset=(hbody-2*rmy)/2.0; c_offsety=hbody/2.0; c_offsetx=vwbody/2.0\n    #makePotentiometerVertical(shaft_hole=True, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n    makePotentiometerVertical(shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph,height3d=height3d)\n    class_name=\"Vishay 148E-149E Single\"\n    wbody = 6.35 + 3.85 + 1.52 + 0.5\n    makePotentiometerHorizontal(mh_ddrill=1.3, mh_count=4, mh_rmx=3.85+6.35, mh_rmy=10.16, mh_xoffset=3.85, mh_yoffset=(10.16-2*rmy)/2.0, class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Vishay 148-149 Dual\"\n    pins = 6; wbody=16.45; wscrew=7\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Vishay 148E-149E Dual\"\n    wbody = 6.35+7.62+3.85+1.52+0.5\n    makePotentiometerHorizontal(mh_ddrill=1.3, mh_count=4, mh_rmx=3.85+7.62+6.35, mh_rmy=10.16, mh_xoffset=3.85, mh_yoffset=(10.16-2*rmy)/2.0, class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n\n    class_name=\"Piher PC-16 Single\"; add_description=\"http://www.piher-nacesa.com/pdf/20-PC16v03.pdf\"\n    pins = 3; rmx=7.5; rmy=5.0; ddrill=1.3; wbody=8; hbody=16; height3d = 20.5; screwzpos = 12.5; wscrew=9; dscrew=10\n    wshaft=25-wscrew; dshaft=6; pinxoffset=6.5; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    voffsetx = 0.5; dbody = 0; vwbody = 18; vpinyoffset = (hbody-2*rmy)/2.0; c_offsetx = 10; c_offsety = hbody/2.0\n    #makePotentiometerVertical(shaft_hole=True, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n    makePotentiometerVertical(shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph,height3d=height3d)\n    #class_name=\"Piher PC-16SV Single\"\n    #voffsetx=0.5; dbody=0; vwbody=18; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=10; c_offsety=hbody/2.0\n    #makePotentiometerVertical(mh_ddrill=1.3, mh_count=2, mh_rmx=0, mh_rmy=10.0, mh_xoffset=15, mh_yoffset=(10-2*rmy)/2.0, shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n    class_name=\"Piher PC-16 Dual\"\n    pins = 6; wbody=16\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Piher PC-16 Triple\"\n    pins = 9; wbody=24\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n\n    class_name=\"Piher T-16H Single\"; add_description=\"http://www.piher-nacesa.com/pdf/22-T16v03.pdf\"\n    pins = 3; rmx=7.5; rmy=5.0; ddrill=1.3; wbody=7.5; hbody=16; height3d = 21; screwzpos = 12.5; wscrew=5; dscrew=7\n    wshaft=15-wscrew; dshaft=4; pinxoffset=1.5; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Piher T-16L Single\"\n    voffsetx=-0.5; dbody=16; vwbody=3; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=10.5; c_offsety=hbody/2.0\n    makePotentiometerVertical(shaft_hole=True, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n    class_name=\"Piher T-16H Double\"\n    pins = 6; wbody=15\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n \n    class_name=\"Alps RK163 Single\"; add_description=\"http://www.alps.com/prod/info/E/HTML/Potentiometer/RotaryPotentiometers/RK16/RK16_list.html\"\n    pins = 3; rmx=5.0; rmy=5.0; ddrill=1.3; wbody=10.5; hbody=17.9; height3d = 21; screwzpos = 12.5; wscrew=5; dscrew=7\n    wshaft=15-wscrew; dshaft=6; pinxoffset=3.8; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Alps RK163 Dual\"\n    pins = 6; wbody=12.1; wscrew=7\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    \n    class_name=\"Alps RK097 Single\"; add_description=\"http://www.alps.com/prod/info/E/HTML/Potentiometer/RotaryPotentiometers/RK097/RK097_list.html\"\n    pins = 3; rmx=2.5; rmy=2.5; ddrill=1; wbody=7.05; hbody=9.5; height3d = 6.5+0.25+4.85; screwzpos = 6.5+0.25; wscrew=5; dscrew=7\n    wshaft=15-wscrew; dshaft=6; pinxoffset=5; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Alps RK097 Dual\"\n    pins = 6; wbody=9.55\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n\n    class_name=\"Bourns PTV09A-2 Single\"; add_description=\"http://www.bourns.com/docs/Product-Datasheets/ptv09.pdf\"\n    pins = 3; rmx=2.5; rmy=2.5; ddrill=1; wbody=5; hbody=9.7; height3d = 10+5.5; screwzpos = 10; wscrew=0.8; dscrew=6.8\n    wshaft=15-wbody-wscrew; dshaft=6; pinxoffset=3.5; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(mh_ddrill=2.3, mh_count=2, mh_rmx=0, mh_rmy=10, mh_xoffset=-3.3, mh_yoffset=(10-2*rmy)/2.0, class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Bourns PTV09A-1 Single\"\n    voffsetx=1; dbody=0; vwbody=12; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=6.5; c_offsety=hbody/2.0\n    makePotentiometerVertical(mh_ddrill=2, mh_count=2, mh_rmx=0, mh_rmy=8.8, mh_xoffset=7, mh_yoffset=(8.8-2*rmy)/2.0, shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)    \n\n    class_name=\"Alps RK09K Single\"; add_description=\"http://www.alps.com/prod/info/E/HTML/Potentiometer/RotaryPotentiometers/RK09K/RK09K_list.html\"\n    pins = 3; rmx=2.5; rmy=2.5; ddrill=1; wbody=6.8; hbody=9.8; height3d = 6.5+5.5; screwzpos = 6.5; wscrew=0.8; dscrew=6.5\n    wshaft=15-6.8-wscrew; dshaft=6; pinxoffset=3.4; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(mh_ddrill=2.3, mh_count=2, mh_rmx=0, mh_rmy=10, mh_xoffset=-3.3, mh_yoffset=(10-2*rmy)/2.0, class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Alps RK09K Single\"\n    voffsetx=1; dbody=0; vwbody=12; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=6.5; c_offsety=hbody/2.0\n    makePotentiometerVertical(mh_ddrill=2, mh_count=2, mh_rmx=0, mh_rmy=8.8, mh_xoffset=7, mh_yoffset=(8.8-2*rmy)/2.0, shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n    \n    class_name=\"Alps RK09L Single\"; add_description=\"http://www.alps.com/prod/info/E/HTML/Potentiometer/RotaryPotentiometers/RK09L/RK09L_list.html\"\n    pins = 3; rmx=2.5; rmy=2.5; ddrill=1; wbody=7.45; hbody=12.1; height3d = 6.5+0.25+4.85; screwzpos = 6.5+0.25; wscrew=5; dscrew=9\n    wshaft=15-wscrew; dshaft=6; pinxoffset=5; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(mh_ddrill=2.1, mh_count=2, mh_rmx=0, mh_rmy=9.5, mh_xoffset=-4.1, mh_yoffset=(9.5-2*rmy)/2.0, class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Alps RK09L Single\"\n    voffsetx=1; dbody=0; vwbody=11.35; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=6.5; c_offsety=hbody/2.0\n    makePotentiometerVertical(mh_ddrill=2, mh_count=2, mh_rmx=0, mh_rmy=9.5, mh_xoffset=7.5, mh_yoffset=(9.5-2*rmy)/2.0, shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n    class_name=\"Alps RK09L Double\"\n    pins = 6; wbody=9.14\n    makePotentiometerHorizontal(mh_ddrill=2.1, mh_count=2, mh_rmx=0, mh_rmy=9.5, mh_xoffset=-5.8, mh_yoffset=(9.5-2*rmy)/2.0, class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Alps RK09L Double\"\n    voffsetx=1; dbody=0; vwbody=11.35; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=6.5; c_offsety=hbody/2.0\n    makePotentiometerVertical(mh_ddrill=2, mh_count=2, mh_rmx=0, mh_rmy=9.5, mh_xoffset=7.5, mh_yoffset=(9.5-2*rmy)/2.0, shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=dscrew+0.5,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n\n    class_name=\"Alps RK09Y11 Single\"; add_description=\"http://www.alps.com/prod/info/E/HTML/Potentiometer/RotaryPotentiometers/RK09Y11/RK09Y11_list.html\"\n    pins = 3; rmx=5.0; rmy=2.5; ddrill=1.0; wbody=5.4; hbody=9.5; height3d = 6.25+0.25+4.85; screwzpos = 6.25+0.25; wscrew=5; dscrew=7\n    wshaft=12-wscrew; dshaft=5; pinxoffset=3.45; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_pv,height3d=height3d, screwzpos=screwzpos)\n\n    class_name=\"Bourns 3339S\"; add_description='http://www.bourns.com/docs/Product-Datasheets/3339.pdf'\n    pins = 3; rmx=-2.54; rmy=2.54; ddrill=0.8; wbody=5.97; hbody=8.13; dbody=0; height3d = 9.53; screwzpos = 5.54; wscrew=8-5.97; dscrew=7.62\n    wshaft=0; dshaft=4; pinxoffset=+4.57-wscrew; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    rmx=2.54; pinxoffset=+4.57-wscrew+2.54\n    class_name=\"Bourns 3339W\"\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Bourns 3339P\"\n    pins = 3; rmx=-2.54; rmy=2.54; ddrill=0.7; wbody=0; hbody=7.62; dbody=7.62; height3d = 6.35; wscrew=-wbody; dscrew=5\n    wshaft=0; dshaft=0; pinxoffset=0; pinyoffset=(hbody-2*rmy)/2.0\n    voffsetx=-rmx; vwbody=0; pinyoffset=(hbody-2*rmy)/2.0; c_offsetx=rmx; c_offsety=hbody/2.0; c_ddrill=2\n    makePotentiometerVertical(screwstyle='slit', style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n    class_name=\"Bourns 3339H\"\n    rmx = 2.54 / math.sqrt(2); rmy = 2.54 / math.sqrt(2); voffsetx = rmx*2; vwbody = 0\n    pinyoffset = (hbody - 2 * rmy)/2.0; c_offsetx=-rmx;  c_offsety=hbody/2.0; c_ddrill=2\n    makePotentiometerVertical(screwstyle='slit', style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n\n    class_name=\"Vishay T7-YA Single\"; add_description=\"http://www.vishay.com/docs/51015/t7.pdf\"\n    pins = 3; rmx=2.54; rmy=2.54; ddrill=0.8; wbody=0; hbody=7; dbody=7; height3d = 5.85; wscrew=-wbody; dscrew=4.1\n    wshaft=0; dshaft=0; pinxoffset=0; pinyoffset=(hbody-2*rmy)/2.0\n    voffsetx=-rmx; vwbody=0; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=2.5; c_offsety=hbody/2.0; c_ddrill=2\n    makePotentiometerVertical(screwstyle='slit', style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n    \n    class_name=\"Bourns 3386X\"; add_description=\"https://www.bourns.com/pdfs/3386.pdf\"\n    pins = 3; rmx=2.54; rmy=2.54; ddrill=0.8; wbody=-4.83; hbody=9.53; dbody=0; height3d = 9.53; screwzpos = 5.33; wscrew=0; dscrew=3.15\n    wshaft=0; dshaft=0; pinxoffset=-(4.83-2.54)/2.0; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name = \"Bourns 3386C\"\n    rmx=0; pinxoffset=-4.83/2.0\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Bourns 3386P\"\n    rmx=2.54; dbody=0; voffsetx=-4.78; vwbody=9.53; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=9.53-5.64; c_offsety=hbody/2.0; c_ddrill=2; height3d = 4.83\n    makePotentiometerVertical(screwstyle=\"slit\", style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n    class_name=\"Bourns 3386F\"\n    rmx=5.08; voffsetx=-9.53+5.08+2.34\n    makePotentiometerVertical(screwstyle=\"slit\", style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n\n    class_name=\"Vishay T73XX\"; add_description=\"http://www.vishay.com/docs/51016/t73.pdf\"\n    pins = 3; rmx=2.54; rmy=2.54; ddrill=0.8; wbody=-4.7; hbody=6.6; dbody=0; height3d = 7; screwzpos = 3.8; wscrew=0; dscrew=3\n    wshaft=0; dshaft=0; pinxoffset=-1.02; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Vishay T73XW\"\n    rmx=0; pinxoffset=-2.35\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Vishay T73YP\"\n    rmx=2.54; dbody=0; voffsetx=-3.56; vwbody=7; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=3.8; c_offsety=hbody/2.0; c_ddrill=2\n    makePotentiometerVertical(screwstyle=\"cross\", style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_ph_bel,height3d=height3d)\n\n    class_name=\"Piher PT-6-H\"; add_description=\"http://www.piher-nacesa.com/pdf/11-PT6v03.pdf\"\n    pins = 3; rmx=2.5; rmy=2.5; ddrill=0.9; wbody=-3.5; hbody=6.3; dbody=6.3; height3d = 4.5+dbody/2.0; screwzpos = 4.5; wscrew=-wbody; dscrew=2\n    wshaft=0; dshaft=1.8; pinxoffset=0; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Piher PT-6-V\"\n    rmx=5; dbody=6.3; voffsetx=0; vwbody=0; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=2.5; c_offsety=hbody/2.0; c_ddrill=2; height3d=4\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh,height3d=height3d)\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=True, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_bel,height3d=height3d)\n\n    class_name=\"Piher PT-10-H01\"; add_description=\"http://www.piher-nacesa.com/pdf/12-PT10v03.pdf\"\n    pins = 3; rmx=2.5; rmy=2.5; ddrill=1.3; wbody=-4.8; hbody=10.3; height3d = 12.1; screwzpos = 7; dbody=10.3; wscrew=-wbody; dscrew=3.5\n    wshaft=0; dshaft=3; pinxoffset=0; pinyoffset=(hbody-2*rmy)/2.0\n    #name_additions=[\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2*rmy)]\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Piher PT-10-H05\"\n    rmx=5; height3d = 12.1; screwzpos = 7;  pinyoffset=(hbody-2*rmy)/2.0\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Piher PT-101-H3.8\"\n    rmx=3.8; height3d = 17.1; screwzpos = 9.6;  pinyoffset=(hbody-2*rmy)/2.0\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    #makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Piher PT-10-V10\"\n    hbody=10; rmx=10; dbody=10.3; voffsetx=0; vwbody=0; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=5; c_offsety=hbody/2.0; c_ddrill=4; height3d=5.3\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh,height3d=height3d)\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=True, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_bel,height3d=height3d)\n    class_name=\"Piher PT-10-V05\"\n    voffsetx = -5.3/2.0; hbody=10; rmx=5; dbody=10.3; vwbody=0; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=10.3/2.0; c_offsety=dbody/2.0; c_ddrill=3\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_bel,height3d=height3d)\n    #name_additions = []\n    \n    class_name=\"Piher PT-15-H05\"; add_description=\"http://www.piher-nacesa.com/pdf/14-PT15v03.pdf\"\n    pins = 3; rmx=5.0; rmy=5; ddrill=1.3; wbody=-5; hbody=15; height3d = 17.5; screwzpos = 10; dbody=15; wscrew=-wbody; dscrew=6\n    wshaft=0; dshaft=4.4; pinxoffset=0; pinyoffset=(hbody-2*rmy)/2.0\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Piher PT-15-H01\"\n    rmy=5; rmx=2.5; height3d = 17.5; screwzpos = 10;  pinyoffset=(hbody-2*rmy)/2.0\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Piher PT-15-H06\"\n    rmy=4.4; rmx=4; height3d = 17.1; screwzpos = 9.6;  pinyoffset=(hbody-2*rmy)/2.0\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Piher PT-15-H25\"\n    rmy=5; rmx=5; height3d = 20; screwzpos = 12.5;  pinyoffset=(hbody-2*rmy)/2.0\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"Piher PT-15-V02\"\n    hbody=10; rmx=12.5; dbody=15; voffsetx=0; vwbody=0; vpinyoffset=(dbody-2*rmy)/2.0; c_offsetx=7.5; c_offsety=dbody/2.0; c_ddrill=7; height3d=5.5\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh,height3d=height3d)\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=True, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_bel,height3d=height3d)\n    class_name=\"Piher PT-15-V15\"\n    voffsetx =0; hbody=15; rmx=15; dbody=15; vwbody=0; vpinyoffset=(dbody-2*rmy)/2.0; c_offsetx=7.5; c_offsety=dbody/2.0; c_ddrill=7\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh,height3d=height3d)\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=True, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_bel,height3d=height3d)\n    #name_additions=[]\n    \n    class_name=\"ACP CA6-H2,5\"; add_description=\"http://www.acptechnologies.com/wp-content/uploads/2017/06/01-ACP-CA6.pdf\"\n    pins = 3; rmx=2.5; rmy=2.5; ddrill=0.9; wbody=-3.5; hbody=6.3; dbody=0; height3d = 4.5+hbody/2.0; screwzpos = 4.5; wscrew=-wbody; dscrew=2\n    wshaft=0; dshaft=1.8; pinxoffset=0; pinyoffset=(hbody-2*rmy)/2.0\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n\n    class_name=\"ACP CA9-H2,5\"; add_description=\"http://www.acptechnologies.com/wp-content/uploads/2017/05/02-ACP-CA9-CE9.pdf\"\n    pins = 3; rmx=2.5; rmy=2.5; ddrill=1.3; wbody=-4.8; hbody=9.8; dbody=0; height3d = 12; screwzpos = 7; wscrew=-wbody; dscrew=3\n    wshaft=0; dshaft=2.1; pinxoffset=0; pinyoffset=(hbody-2*rmy)/2.0\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"ACP CA9-H3,8\"\n    rmx=3.8; height3d = 12\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"ACP CA9-H5\"\n    rmx=5; height3d = 12\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"ACP CA9-V10\"\n    rmx=10; dbody=0; voffsetx=0; vwbody=10; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=vwbody/2.0; c_offsety=hbody/2.0; c_ddrill=4; height3d=7.2\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=vpinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh,height3d=height3d)\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=True, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=vpinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_bel,height3d=height3d)\n    #name_additions=[]\n    \n    class_name=\"ACP CA14-H2,5\"; add_description=\"http://www.acptechnologies.com/wp-content/uploads/2017/10/03-ACP-CA14-CE14.pdf\"\n    pins = 3; rmx=2.5; rmy=5; ddrill=1.3; wbody=-5.0; hbody=14; dbody=0; height3d = 17; screwzpos = 10; wscrew=-wbody; dscrew=6\n    wshaft=0; dshaft=5; pinxoffset=0; pinyoffset=(hbody-2*rmy)/2.0\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"ACP CA14-H4\"\n    rmx=4\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"ACP CA14-H5\"\n    rmx=5\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerHorizontal(style=\"trimmer\", class_name=class_name, wbody=wbody, hbody=hbody, wscrew=wscrew, dscrew=dscrew, wshaft=wshaft, dshaft=dshaft, pinxoffset=pinxoffset,pinyoffset=pinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, R_POW=R_POW, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trv,height3d=height3d, screwzpos=screwzpos)\n    class_name=\"ACP CA14V-15\"\n    rmx=15; dbody=0; voffsetx=0.5; vwbody=14; vpinyoffset=(hbody-2*rmy)/2.0; c_offsetx=vwbody/2.0; c_offsety=hbody/2.0; c_ddrill=7; height3d=7.2\n    #name_additions = [\"Px{0:1.1f}mm_Py{1:1.1f}mm\".format(rmx, 2 * rmy)]\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=False, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=vpinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh,height3d=height3d)\n    makePotentiometerVertical(style=\"trimmer\", shaft_hole=True, class_name=class_name, wbody=vwbody, hbody=hbody, d_body=dbody, dshaft=dshaft, dscrew=dscrew, c_ddrill=c_ddrill,c_offsetx=c_offsetx, c_offsety=c_offsety, pinxoffset=voffsetx,pinyoffset=vpinyoffset, pins=pins, rmx=rmx, rmy=rmy, ddrill=ddrill, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_trh_bel,height3d=height3d)\n    #name_additions=[]\n    \n    class_name=\"Bourns 3005\"; add_description = \"http://www.bourns.com/docs/Product-Datasheets/3005.pdf\";\n    wbody=19.3; hbody=4.06; pinxoffset=16; pinyoffset=(hbody-2.54)/2.0+2.54; height3d = 7.87; rmx2=-7.62; rmy2=-2.54; rmx3=-12.7; rmy3=0; ddrill=1; dscrew=3; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody/2.0\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n    \n    class_name=\"Vishay 43\"; add_description = \"http://www.vishay.com/docs/57026/43.pdf\";\n    wbody=19.0; hbody=4.8; pinxoffset=16; pinyoffset=(hbody-2.54)/2.0+2.54; height3d = 6.35; rmx2=-7.62; rmy2=-2.54; rmx3=-12.7; rmy3=0; ddrill=1; dscrew=2.36; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody/2.0\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n\n    class_name=\"Bourns 3006P\"; add_description = \"https://www.bourns.com/docs/Product-Datasheets/3006.pdf\";\n    wbody=19.05; hbody=4.83; pinxoffset=16; pinyoffset=(hbody-2.54)/2.0+2.54; height3d = 6.35; rmx2=-7.62; rmy2=-2.54; rmx3=-12.7; rmy3=0; ddrill=1; dscrew=2.36; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody/2.0\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n    class_name=\"Bourns 3006W\"\n    wbody=19.05; hbody=4.83; pinxoffset=16; pinyoffset=4.83+0.15; height3d = 6.35; rmx2=-7.62; rmy2=-5.06; rmx3=-12.7; rmy3=0; ddrill=1; dscrew=2.36; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody/2.0\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n    class_name=\"Bourns 3006Y\"\n    wbody=19.05; hbody=4.83; pinxoffset=18.42; pinyoffset=(hbody-2.54)/2.0+2.54; height3d = 6.35; rmx2=-(17.78-7.62); rmy2=-2.54; rmx3=-17.78; rmy3=0; ddrill=1; dscrew=2.36; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody/2.0\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n\n    class_name=\"Bourns 3009P\"; add_description = \"http://www.bourns.com/docs/Product-Datasheets/3009.pdf\"\n    wbody=19.05; hbody=4.83; pinxoffset=16; pinyoffset=(hbody-2.54)/2.0+2.54; height3d = 8.98; rmx2=-7.62; rmy2=-2.54; rmx3=-12.7; rmy3=0; ddrill=1; dscrew=2.36; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody/2.0\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n    class_name=\"Bourns 3009Y\"\n    wbody=19.05; hbody=4.83; pinxoffset=18.42; pinyoffset=(hbody-2.54)/2.0+2.54; height3d = 8.98; rmx2=-(17.78-7.62); rmy2=-2.54; rmx3=-17.78; rmy3=0; ddrill=1; dscrew=2.36; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody/2.0\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n\n    class_name=\"Bourns 3296W\"; add_description = \"https://www.bourns.com/pdfs/3296.pdf\";\n    wbody=9.53; hbody=4.83; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=2.41; height3d = 10.03; rmx2=-2.54; rmy2=0; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew=2.19; wscrew = dscrew; screwxoffset = wbody-1.27; screwyoffset = hbody-1.27\n    style = \"screwtop\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst, height3d=height3d)\n    class_name=\"Bourns 3296X\"\n    wbody=9.53; hbody=4.83; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=2.41; height3d = 10.03; rmx2=-2.54; rmy2=0; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew = 2.19; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody-1.27\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n    class_name=\"Bourns 3296Y\"\n    wbody=9.53; hbody=4.83; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=1.14; height3d = 10.03; rmx2=-2.54; rmy2=2.54; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew=2.19; wscrew = dscrew; screwxoffset = wbody-1.27; screwyoffset = hbody-1.27\n    style = \"screwtop\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst, height3d=height3d)\n    class_name=\"Bourns 3296Z\"\n    wbody=9.53; hbody=4.83; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=hbody-1.14-2.54; height3d = 10.03; rmx2=-2.54; rmy2=2.54; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew=2.19; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody-1.27\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n    class_name=\"Bourns 3296P\"\n    wbody=10.03; hbody=9.53; pinxoffset=wbody/2.0; pinyoffset=(hbody-5.08)/2.0; height3d = 4.83; rmx2=-2.54; rmy2=2.54; rmx3=0; rmy3=5.08; ddrill=0.8; dscrew=2.19; wscrew = 1.52; screwxoffset = 0; screwyoffset = 1.27\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n\n    class_name=\"Bourns 3299W\"; add_description = \"https://www.bourns.com/pdfs/3299.pdf\";\n    wbody=9.53; hbody=6.10; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=1.91; height3d = 10.03; rmx2=-2.54; rmy2=0; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew=2.19; wscrew = dscrew; screwxoffset = wbody-1.27; screwyoffset = hbody-1.27\n    style = \"screwtop\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst, height3d=height3d)\n    class_name=\"Bourns 3299X\"\n    wbody=9.53; hbody=6.10; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=1.91; height3d = 10.03; rmx2=-2.54; rmy2=0; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew = 2.19; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody-1.27\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n    class_name=\"Bourns 3299Y\"\n    wbody=9.53; hbody=6.10; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=1.91; height3d = 10.03; rmx2=-2.54; rmy2=2.54; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew=2.19; wscrew = dscrew; screwxoffset = wbody-1.27; screwyoffset = hbody-1.27\n    style = \"screwtop\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst, height3d=height3d)\n    class_name=\"Bourns 3299Z\"\n    wbody=9.53; hbody=6.10; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=1.91; height3d = 10.03; rmx2=-2.54; rmy2=2.54; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew=2.19; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody-1.27\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n    class_name=\"Bourns 3299P\"\n    wbody=10.03; hbody=9.53; pinxoffset=wbody/2.0; pinyoffset=(hbody-5.08)/2.0; height3d = 6.10; rmx2=-2.54; rmy2=2.54; rmx3=0; rmy3=5.08; ddrill=0.8; dscrew=2.19; wscrew = 1.52; screwxoffset = 0; screwyoffset = 1.27\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n\n    class_name=\"Bourns 3266Y\"; add_description = \"https://www.bourns.com/docs/Product-Datasheets/3266.pdf\";\n    wbody=6.71; hbody=4.5; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=2.16; height3d = 6.71; rmx2=-2.54; rmy2=0; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew=1.78; wscrew = dscrew; screwxoffset = wbody-1.22; screwyoffset = hbody-1.27\n    style = \"screwtop\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst, height3d=height3d)\n    class_name=\"Bourns 3266Z\"\n    wbody=6.71; hbody=4.5; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=2.16; height3d = 6.71; rmx2=-2.54; rmy2=0; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew = 1.78; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody-1.27\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n    class_name=\"Bourns 3266W\"\n    wbody=6.71; hbody=4.5; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=1.02; height3d = 6.71; rmx2=-2.54; rmy2=2.54; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew=1.78; wscrew = dscrew; screwxoffset = wbody-1.27; screwyoffset = hbody-1.27\n    style = \"screwtop\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tst, height3d=height3d)\n    class_name=\"Bourns 3266X\"\n    wbody=6.71; hbody=4.5; pinxoffset=(wbody-5.08)/2.0+5.08; pinyoffset=1.02; height3d = 6.71; rmx2=-2.54; rmy2=2.54; rmx3=-5.08; rmy3=0; ddrill=0.8; dscrew=1.78; wscrew = 1.52; screwxoffset = 0; screwyoffset = hbody-1.27\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)\n    class_name=\"Bourns 3266P\"\n    wbody=6.71; hbody=6.71; pinxoffset=wbody/2.0; pinyoffset=(hbody-5.08)/2.0; height3d = 4.5; rmx2=-2.54; rmy2=2.54; rmx3=0; rmy3=5.08; ddrill=0.8; dscrew=1.78; wscrew = 1.52; screwxoffset = 0; screwyoffset = 1.27\n    style = \"screwleft\"; SMD_pads = False; SMD_padsize = []\n    makeSpindleTrimmer(shaft_hole=False, class_name=class_name, ddrill=ddrill, wbody=wbody, hbody=hbody, pinxoffset=pinxoffset, pinyoffset=pinyoffset, rmx2=rmx2, rmy2=rmy2, rmx3=rmx3, rmy3=rmy3, dscrew=dscrew, wscrew=wscrew, screwxoffset=screwxoffset, screwyoffset=screwyoffset, style=style, SMD_pads=SMD_pads, SMD_padsize=SMD_padsize, specialtags=[], add_description=add_description, name_additions=[], script3d=script3d_tsl, height3d=height3d)    \n"
  },
  {
    "path": "scripts/Potentiometers/slide_Potentiometer.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\n\nimport os\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))\nsys.path.append(os.path.join(sys.path[0], \"..\", \"tools\"))\n\nfrom KicadModTree import *\nfrom drawing_tools import *\n\ndef slide_pot(args):\n    footprint_name = args[\"name\"]\n    dimA = args[\"dimA\"]\n    dimB = args[\"dimB\"]\n    dimC = args[\"dimC\"]\n    dimD = args[\"dimD\"]\n    dimE = args[\"dimE\"]\n    travel = args[\"travel\"]\n\n    f = Footprint(footprint_name)\n    f.setDescription(\"Bourns single-gang slide potentiometer, \" + str(travel) + \"mm travel, https://www.bourns.com/docs/Product-Datasheets/pta.pdf\")\n    f.setTags(\"Bourns single-gang slide potentiometer \" + str(travel) + \"mm\")\n    f.append(Model(filename=\"${KISYS3DMOD}/Potentiometer_THT.3dshapes/\" + footprint_name + \".wrl\", at=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], rotate=[0.0, 0.0, 0.0]))\n\n    dPin = [1.2, 1.2]\n    dMP = [1.7, 1.7]\n\n    pPin = [1.75, 1.75]\n    pMP = [2.7, 2.7]\n\n    s = [1.0, 1.0]\n    t = 0.15\n\n    wCrtYd = 0.05\n    wFab = 0.1\n    wSilkS = 0.12\n\n    silk = wSilkS\n    silkGap = 2 * wSilkS\n    silk_ko = 0.3\n    crtYd = 0.5\n\n    xCenter = dimE / 2\n    yCenter = 3.5 / 2\n\n    xPin1 = 0.0\n    yPin1 = 0.0\n    xPin2 = 0.0\n    yPin2 = 3.5\n    xPin3 = dimE\n    yPin3 = 0.0\n\n    mountingPins = []\n\n    for row in [[-1, dimC], [1, dimD]]:\n        y = yCenter + 8.4 / 2 * row[0]\n        half = row[1] / 2\n        mountingPins.append([xCenter - half, y])\n        mountingPins.append([xCenter + half, y])\n\n    halfWidth = dimA / 2\n    halfHeight = 9.0 / 2\n\n    xLeftFab = xCenter - halfWidth\n    xRightFab = xCenter + halfWidth\n    yTopFab = yCenter - halfHeight\n    yBottomFab = yCenter + halfHeight\n\n    xLeftSilk = xLeftFab - silk\n    xRightSilk = xRightFab + silk\n    yTopSilk = yTopFab - silk\n    yBottomSilk = yBottomFab + silk\n\n    xLeftCrtYd = xLeftFab - crtYd\n    xRightCrtYd = xRightFab + crtYd\n    yTopCrtYd = yTopFab - crtYd\n    yBottomCrtYd = yBottomFab + crtYd\n\n    yRef = yTopFab - 1.25\n    yValue = yBottomFab + 1.25\n    yFabRef = yCenter\n\n    hTravel = travel / 2\n    xLeftTravel = xCenter - hTravel\n    xRightTravel = xCenter + hTravel\n\n    keepouts = []\n\n    # Pins\n    for pin in [[\"1\", [xPin1, yPin1], Pad.SHAPE_RECT],\n                [\"2\", [xPin2, yPin2], Pad.SHAPE_CIRCLE],\n                [\"3\", [xPin3, yPin3], Pad.SHAPE_CIRCLE]]:\n        f.append(Pad(number=pin[0], type=Pad.TYPE_THT, shape=pin[2], at=pin[1],\n                     size=pPin, layers=Pad.LAYERS_THT, drill=dPin))\n        x = pin[1][0]\n        y = pin[1][1]\n        d = pPin[0] + 2 * silk_ko\n        if pin[0] == \"1\":\n            keepouts = keepouts + addKeepoutRect(x, y, d, d)\n        else:\n            keepouts = keepouts + addKeepoutRound(x, y, d, d)\n\n    for mp in mountingPins:\n        f.append(Pad(number=\"MP\", type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\n                     at=mp, size=pMP, layers=Pad.LAYERS_THT, drill=dMP))\n        d = pMP[0] + 2 * silk_ko\n        keepouts = keepouts + addKeepoutRound(mp[0], mp[1], d, d)\n\n    # Text\n    f.append(Text(type=\"reference\", text=\"REF**\", at=[xCenter, yRef], layer=\"F.SilkS\", size=s, thickness=t))\n    f.append(Text(type=\"value\", text=footprint_name, at=[xCenter, yValue], layer=\"F.Fab\", size=s, thickness=t))\n    f.append(Text(type=\"user\", text=\"%R\", at=[xCenter, yFabRef], layer=\"F.Fab\", size=s, thickness=t))\n\n    # Fab\n    f.append(PolygoneLine(polygone=[[xLeftFab + 1, yTopFab],\n                                    [xRightFab, yTopFab],\n                                    [xRightFab, yBottomFab],\n                                    [xLeftFab, yBottomFab],\n                                    [xLeftFab, yTopFab + 1],\n                                    [xLeftFab + 1, yTopFab]],\n                          layer=\"F.Fab\",\n                          width=wFab))\n    for dir in [-1, 1]:\n        xScrew = xCenter + dir * (dimB / 2)\n        f.append(Circle(center=[xScrew, yCenter], radius=1.0,\n                        layer=\"F.Fab\", width=wFab))\n\n    # Silk outline\n    addRectWithKeepout(f, xLeftSilk, yTopSilk,\n                       xRightSilk - xLeftSilk, yBottomSilk - yTopSilk,\n                       \"F.SilkS\", wSilkS, keepouts)\n\n    # Silk pin 1 indicator\n    xp1 = -(pPin[0] / 2 + silk_ko)\n    yp1 = 0.0\n    f.append(PolygoneLine(polygone=[[xp1, yp1],\n                                    [xp1 - 0.5, yp1 - 0.5],\n                                    [xp1 - 0.5, yp1 + 0.5],\n                                    [xp1, yp1]],\n                          layer=\"F.SilkS\", width=wSilkS))\n\n    # Silk travel indicator\n    f.append(Line(start=[xLeftTravel, yCenter],\n                  end=[xRightTravel, yCenter],\n                  layer=\"F.SilkS\", width=wSilkS))\n    for dir in [-1, 1]:\n        xTravel = xCenter + dir * hTravel\n        xArrow = xCenter + dir * (hTravel - 0.75)\n        f.append(Line(start=[xTravel, yCenter - 1.5],\n                      end=[xTravel, yCenter + 1.5],\n                      layer=\"F.SilkS\", width=wSilkS))\n        f.append(PolygoneLine(polygone=[[xArrow, yCenter - 0.75],\n                                        [xTravel, yCenter],\n                                        [xArrow, yCenter + 0.75]],\n                              layer=\"F.SilkS\", width=wSilkS))\n\n    # CrtYd\n    f.append(RectLine(start=[xLeftCrtYd, yTopCrtYd],\n                      end=[xRightCrtYd, yBottomCrtYd],\n                      layer=\"F.CrtYd\",\n                      width=wCrtYd))\n\n    file_handler = KicadFileHandler(f)\n    file_handler.writeFile(footprint_name + \".kicad_mod\")\n\n\nif __name__ == '__main__':\n    parser = ModArgparser(slide_pot)\n    # the root node of .yml files is parsed as name\n    parser.add_parameter(\"name\", type=str, required=True)\n    parser.add_parameter(\"dimA\", type=float, required=True)\n    parser.add_parameter(\"dimB\", type=float, required=True)\n    parser.add_parameter(\"dimC\", type=float, required=True)\n    parser.add_parameter(\"dimD\", type=float, required=True)\n    parser.add_parameter(\"dimE\", type=float, required=True)\n    parser.add_parameter(\"travel\", type=float, required=True)\n\n    # now run our script which handles the whole part of parsing the files\n    parser.run()\n"
  },
  {
    "path": "scripts/Potentiometers/slide_Potentiometer.yaml",
    "content": "Potentiometer_Bourns_PTA1543_Single_Slide:\n  dimA: 30\n  dimB: 26\n  dimC: 17.8\n  dimD: 20.2\n  dimE: 28.5\n  travel: 15\nPotentiometer_Bourns_PTA2043_Single_Slide:\n  dimA: 35\n  dimB: 31\n  dimC: 22.8\n  dimD: 25.2\n  dimE: 33\n  travel: 20\nPotentiometer_Bourns_PTA3043_Single_Slide:\n  dimA: 45\n  dimB: 41\n  dimC: 32.8\n  dimD: 35.2\n  dimE: 43.5\n  travel: 30\nPotentiometer_Bourns_PTA4543_Single_Slide:\n  dimA: 60\n  dimB: 56\n  dimC: 47.8\n  dimD: 50.2\n  dimE: 58.5\n  travel: 45\nPotentiometer_Bourns_PTA6043_Single_Slide:\n  dimA: 75\n  dimB: 71\n  dimC: 62.8\n  dimD: 65.2\n  dimE: 73.5\n  travel: 60\n"
  },
  {
    "path": "scripts/Recom_DCDC/Recom_SIP.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom drawing_tools import *\nfrom footprint_scripts_sip import *\n\nrm=2.54\n\ndef recom_78_3pin():\n    pins=3\n    \n    ddrill_large=1.2\n    pad_large=[1.7, 2.5]\n\n    ddrill_small=1.0\n    pad_small=[1.5, 2.3]    \n\n    package_size=[11.5,8.5,17.5]\n    left_offset=3.21\n    top_offset=2\n    makeSIPVertical(pins=pins, rm=rm, ddrill=ddrill_large, pad=pad_large, package_size=package_size, left_offset=left_offset, top_offset=top_offset, \n            footprint_name='Converter_DCDC_RECOM_R-78B-2.0_THT', \n            description=\"DCDC-Converter, RECOM, RECOM_R-78B-2.0, SIP-{0}, pitch {1:3.2f}mm, package size {2}x{3}x{4}mm^3, https://www.recom-power.com/pdf/Innoline/R-78Bxx-2.0.pdf\".format(pins,rm,package_size[0],package_size[1],package_size[2]), \n            tags=\"dc-dc recom buck sip-{0} pitch {1:3.2f}mm\".format(pins,rm), \n            lib_name='Converter_DCDC')\n\n    package_size=[11.6,8.5,10.4]\n    left_offset=package_size[0]-3.21-5.08\n    top_offset=package_size[1]-2\n    makeSIPVertical(pins=pins, rm=rm, ddrill=ddrill_small, pad=pad_small, package_size=package_size, left_offset=left_offset, top_offset=top_offset, \n            footprint_name='Converter_DCDC_RECOM_R-78E-0.5_THT', \n            description=\"DCDC-Converter, RECOM, RECOM_R-78E-0.5, SIP-{0}, pitch {1:3.2f}mm, package size {2}x{3}x{4}mm^3, https://www.recom-power.com/pdf/Innoline/R-78Exx-0.5.pdf\".format(pins,rm,package_size[0],package_size[1],package_size[2]), \n            tags=\"dc-dc recom buck sip-{0} pitch {1:3.2f}mm\".format(pins,rm), \n            lib_name='Converter_DCDC')\n\n    package_size=[11.5,8.5,17.5]\n    left_offset=3.21\n    top_offset=2\n    pin_bottom_offset=1.5\n    makeSIPVertical(pins=pins, rm=rm, ddrill=ddrill_small, pad=pad_small, package_size=package_size, left_offset=left_offset, top_offset=top_offset, \n            footprint_name='Converter_DCDC_RECOM_R-78HB-0.5_THT', \n            description=\"DCDC-Converter, RECOM, RECOM_R-78HB-0.5, SIP-{0}, pitch {1:3.2f}mm, package size {2}x{3}x{4}mm^3, https://www.recom-power.com/pdf/Innoline/R-78HBxx-0.5_L.pdf\".format(pins,rm,package_size[0],package_size[1],package_size[2]), \n            tags=\"dc-dc recom buck sip-{0} pitch {1:3.2f}mm\".format(pins,rm), \n            lib_name='Converter_DCDC')\n    makeSIPHorizontal(pins=pins, rm=rm, ddrill=ddrill_small, pad=pad_small, package_size=package_size, left_offset=left_offset, pin_bottom_offset=pin_bottom_offset, \n            footprint_name='Converter_DCDC_RECOM_R-78HB-0.5L_THT', \n            description=\"DCDC-Converter, RECOM, RECOM_R-78HB-0.5L, SIP-{0}, Horizontally Mounted, pitch {1:3.2f}mm, package size {2}x{3}x{4}mm^3, https://www.recom-power.com/pdf/Innoline/R-78HBxx-0.5_L.pdf\".format(pins,rm,package_size[0],package_size[1],package_size[2]), \n            tags=\"dc-dc recom buck sip-{0} pitch {1:3.2f}mm\".format(pins,rm), \n            lib_name='Converter_DCDC')\n\ndef recom_78_4pin(): \n    pins=4\n\n    ddrill=1.0\n    pad=[1.5, 2.3]\n\n    package_size=[11.6,8.5,10.4]\n\n    left_offset=2\n    top_offset=package_size[1]-2\n    makeSIPVertical(pins=pins, rm=rm, ddrill=ddrill, pad=pad, package_size=package_size, left_offset=left_offset, top_offset=top_offset, \n            footprint_name='Converter_DCDC_RECOM_R-78S-0.1_THT', \n            description=\"DCDC-Converter, RECOM, RECOM_R-78S-0.1, SIP-{0}, pitch {1:3.2f}mm, package size {2}x{3}x{4}mm^3, https://www.recom-power.com/pdf/Innoline/R-78Sxx-0.1.pdf\".format(pins,rm,package_size[0],package_size[1],package_size[2]), \n            tags=\"dc-dc recom buck sip-{0} pitch {1:3.2f}mm\".format(pins,rm), \n            lib_name='Converter_DCDC')\n\ndef recom_r5():\n    pins=12\n\n    ddrill=1.0\n    pad=[1.5, 2.3]\n    \n    package_size=[32.2,9.1,15]\n    left_offset=2.1\n    top_offset=0.8\n    pin_bottom_offset=2\n    makeSIPVertical(pins=pins, rm=rm, ddrill=ddrill, pad=pad, package_size=package_size, left_offset=left_offset, top_offset=top_offset, \n            footprint_name='Converter_DCDC_RECOM_R5xxxPA_THT', \n            description=\"DCDC-Converter, RECOM, RECOM_R5xxxPA, SIP-{0}, pitch {1:3.2f}mm, package size {2}x{3}x{4}mm^3, https://www.recom-power.com/pdf/Innoline/R-5xxxPA_DA.pdf\".format(pins,rm,package_size[0],package_size[1],package_size[2]), \n            tags=\"dc-dc recom buck sip-{0} pitch {1:3.2f}mm\".format(pins,rm), \n            lib_name='Converter_DCDC')\n    makeSIPHorizontal(pins=pins, rm=rm, ddrill=ddrill, pad=pad, package_size=package_size, left_offset=left_offset, pin_bottom_offset=pin_bottom_offset, \n            footprint_name='Converter_DCDC_RECOM_R5xxxDA_THT', \n            description=\"DCDC-Converter, RECOM, RECOM_R5xxxDA, SIP-{0}, Horizontally Mounted, pitch {1:3.2f}mm, package size {2}x{3}x{4}mm^3, https://www.recom-power.com/pdf/Innoline/R-5xxxPA_DA.pdf\".format(pins,rm,package_size[0],package_size[1],package_size[2]), \n            tags=\"dc-dc recom buck sip-{0} pitch {1:3.2f}mm\".format(pins,rm), \n            lib_name='Converter_DCDC')\n\nif __name__ == '__main__':\n    recom_78_3pin()\n    recom_78_4pin()\n    recom_r5()\n"
  },
  {
    "path": "scripts/ResistorArrays_SIP_THT/make_Resistor_array_SIP.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom drawing_tools import *\nfrom footprint_scripts_sip import *\n\n\nif __name__ == '__main__':\n    for R in range(3, 14):\n        pins=R+1\n        makeResistorSIP(pins, \"Resistor_Array_SIP%d\" % (pins), \"{0}-pin Resistor SIP pack\".format(pins, R))\n    #for R in range(3,6):\n    #    pins=2*R\n    #    makeResistorSIP(pins, \"Resistor_ArrayParallel_SIP%d\" % (R), \"{0}-pin Resistor SIP pack, {1} parallel resistors\".format(pins, R))\n    #for R in range(3,6):\n    #    pins=R+2\n    #    makeResistorSIP(pins, \"Resistor_ArrayDivider_SIP%d\" % (R), \"{0}-pin Resistor SIP pack, {1} voltage dividers = {2} resistors\".format(pins, R, 2*R))\n"
  },
  {
    "path": "scripts/Resistor_THT/make_Resistors_THT.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom drawing_tools import *\nfrom footprint_scripts_resistorlike import *\n\n\n\n\n\n\n\n\n\nif __name__ == '__main__':\n    lib_name=\"${KISYS3DMOD}/Resistor_THT\"\n\n    # standard resistors: http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf\n    type = \"cyl\"\n    script3d=\"res_axial_cyl_hor.py\"\n    with open(script3d, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3dv=\"res_axial_cyl_ver.py\"\n    with open(script3dv, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n\n    d2=0\n    seriesname = \"Axial_DIN0204\"; w=3.6; d=1.6; ddrill=0.7; R_POW=1.0/6.0; add_description=\"http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf\"; name_additions=[]\n    for rm in [5.08, 7.62]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [1.9,2.54, 5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n    seriesname = \"Axial_DIN0207\"; w = 6.3; d = 2.5; ddrill = 0.8; R_POW = 0.25; add_description=\"http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf\"; name_additions=[]\n    for rm in [7.62, 10.16, 15.24]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [2.54, 5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n    seriesname=\"Axial_DIN0309\"; w = 9; d = 3.2; ddrill = 0.8; R_POW = 0.5; add_description=\"http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf\"; name_additions=[]\n    for rm in [12.7, 15.24, 20.32, 25.4]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [2.54, 5.08]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n    seriesname = \"Axial_DIN0411\"; w = 9.9; d = 3.6; ddrill = 1.2; R_POW = 1; add_description=\"\"; name_additions=[]\n    for rm in [12.7,15.24, 20.32, 25.4]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n    seriesname = \"Axial_DIN0414\"; w = 11.9; d = 4.5; ddrill = 1.2; R_POW = 2; add_description=\"http://www.vishay.com/docs/20128/wkxwrx.pdf\"; name_additions=[]\n    for rm in [15.24, 20.32, 25.4]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n    seriesname = \"Axial_DIN0516\"; w = 15.5; d = 5; ddrill = 1.2; R_POW = 2; add_description=\"http://cdn-reichelt.de/documents/datenblatt/B400/1_4W%23YAG.pdf\"; name_additions=[]\n    for rm in [20.32, 25.4, 30.48]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [5.08, 7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n    seriesname = \"Axial_DIN0614\"; w = 14.3; d = 5.7; ddrill = 1.4; R_POW = 1.5; add_description=\"\"\n    for rm in [15.24, 20.32, 25.4]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n\n    seriesname = \"Axial_DIN0617\"; w = 17; d = 6; ddrill = 1.2; R_POW = 2; add_description=\"http://www.vishay.com/docs/20128/wkxwrx.pdf\"; name_additions=[]\n    for rm in [20.32, 25.4, 30.48]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [5.08, 7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n\n    seriesname = \"Axial_DIN0918\"; w = 18; d = 9; ddrill = 1.2; R_POW = 4; add_description=\"\"\n    for rm in [22.86, 25.4, 30.48]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n    seriesname = \"Axial_DIN0922\"; w = 20; d = 9; ddrill = 1.2; R_POW = 5; add_description=\"http://www.vishay.com/docs/20128/wkxwrx.pdf\"; name_additions=[]\n    for rm in [25.4, 30.48]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n\t\t\n\n\n    # POWER Resistors (rectangular)\n    script3d = \"res_axial_box_hor.py\"\n    with open(script3d, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    script3dv = \"res_axial_box_ver.py\"\n    with open(script3dv, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    type = \"box\"\n    seriesname = \"Axial_Power\"; w=20; d=6.4; d2=6.4; ddrill=1.2; R_POW=4; add_description=\"http://cdn-reichelt.de/documents/datenblatt/B400/5WAXIAL_9WAXIAL_11WAXIAL_17WAXIAL%23YAG.pdf\"; name_additions=[]\n    for rm in [22.4, 25.4, 30.48]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [5.08,7.62]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n    seriesname = \"Axial_Power\"; w=25; d=6.4; d2=6.4; ddrill=1.2; R_POW=5; name_additions=[]\n    for rm in [27.94,30.48]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n\n    seriesname = \"Axial_Power\"; w=38; d=6.4; d2=6.4; ddrill=1.2; R_POW=7; name_additions=[]\n    for rm in [40.64,45.72]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n\n    seriesname = \"Axial_Power\"; w=25; d=9; d2=9; ddrill=1.2; R_POW=7; name_additions=[]\n    for rm in [27.94,30.48]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [7.62,10.16]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n    seriesname = \"Axial_Power\"; w=38; d=9; d2=9; ddrill=1.2; R_POW=9; name_additions=[]\n    for rm in [40.64,45.72]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n\n    seriesname = \"Axial_Power\"; w=50; d=9; d2=9; ddrill=1.2; R_POW=11; name_additions=[]\n    for rm in [55.88,60.96]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n\n    seriesname = \"Axial_Power\"; w=75; d=9; d2=9; ddrill=1.2; R_POW=17; name_additions=[]\n    for rm in [81.28,86.36]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n\n    seriesname = \"Axial_Power\"; w=48; d=12.5; d2=12.5; ddrill=1.2; R_POW=15; name_additions=[]\n    for rm in [55.88,60.96]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [7.62,10.16]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n    seriesname = \"Axial_Power\"; w=60; d=14; d2=14; ddrill=1.2; R_POW=25; name_additions=[]\n    for rm in [66.04,71.12]:\n        makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3d, lib_name=lib_name)\n    for rm in [10.16]:\n        makeResistorAxialVertical(seriesname=seriesname, rm=rm, rmdisp=rm, l=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type, d2=d2, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n    # shunt resistor with additional pins\n    script3dv = \"res_axial_shunt_ver.py\"\n    with open(script3dv, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    type = \"box\"\n    seriesname = \"Axial_Shunt\";  ddrill=1.5; add_description=\"http://www.vishay.com/docs/30217/cpsl.pdf\"; name_additions=[]\n    rm = 25.4; shuntPinsRM=14.3; w=22.2; d=8; d2=d; R_POW=3\n    makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2, hasShuntPins=True, shuntPinsRM=shuntPinsRM,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n    rm = 25.4; shuntPinsRM=14.3; w=22.2; d=9.5; d2=d; R_POW=5\n    makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2, hasShuntPins=True, shuntPinsRM=shuntPinsRM,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n    rm = 38.1; shuntPinsRM=25.4; w=35.3; d=9.5; d2=d; R_POW=7\n    makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2, hasShuntPins=True, shuntPinsRM=shuntPinsRM,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n    rm = 50.8; shuntPinsRM=34.93; w=47.6; d=9.5; d2=d; R_POW=10\n    makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2, hasShuntPins=True, shuntPinsRM=shuntPinsRM,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n    rm = 50.8; shuntPinsRM=34.93; w=47.6; d=12.7; d2=d; R_POW=15\n    makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2, hasShuntPins=True, shuntPinsRM=shuntPinsRM,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[],script3d=script3dv, lib_name=lib_name)\n\n    # wire bridge/bare metal resistor elements\n    type = \"bridge\"\n    seriesname = \"Bare_Metal_Element\"; d=4.8; d2=2; ddrill=1.5; add_description=\"https://www.bourns.com/pdfs/PWR4412-2S.pdf\"; name_additions=[]\n    rm = 11.4; w=rm+1; R_POW=1\n    makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[], lib_name=lib_name)\n    rm = 15.3; w=rm+1; R_POW=3\n    makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[], lib_name=lib_name)\n    rm = 20.3; w=rm+1; R_POW=5\n    makeResistorAxialHorizontal(seriesname=seriesname, rm=rm, rmdisp=rm, w=w, d=d, ddrill=ddrill, R_POW=R_POW, type=type,d2=d2,  x_3d=[0,0,0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", add_description=add_description, name_additions=name_additions, specialtags=[], lib_name=lib_name)\n    \n    # radial resistors, 45deg wires\n    script3dv = \"res_radial_power_ver.py\"\n    with open(script3dv, \"w\") as myfile:\n        myfile.write(\"#\\n# SCRIPT to generate 3D models\\n#\\n\\n\")\n    rm2=0; w2=0\n    type = \"simple45\"; seriesname = \"Radial_Power\"; add_description = \"http://www.vitrohm.com/content/files/vitrohm_series_kv_-_201601.pdf\"; name_additions=[]\n    w = 7; h = 8; ddrill = 1.2; rm=2.4; rm2=2.3; R_POW=7\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=[], add_description=add_description,script3d=script3dv,height3d=38, lib_name=lib_name)\n    w = 9; h = 10; ddrill = 1.2; rm=2.7; rm2=2.3; R_POW=17\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=[], add_description=add_description,script3d=script3dv,height3d=75, lib_name=lib_name)\n\n    # radial resistors, simple box\n    rm2=0; w2=0\n    type = \"simple\"; seriesname = \"Box\"; add_description = \"http://www.vishay.com/docs/60051/cns020.pdf\"; name_additions=[]\n    w = 8.38; h = 2.54; ddrill = 0.8; rm=5.08; rm2=0; R_POW=0.5\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=[], add_description=add_description,script3d=script3dv,height3d=6.62, lib_name=lib_name)\n\n    add_description = \"http://www.produktinfo.conrad.com/datenblaetter/425000-449999/443860-da-01-de-METALLBAND_WIDERSTAND_0_1_OHM_5W_5Pr.pdf\"; name_additions=[]\n    w = 13.0; h = 4.0; ddrill = 1.0; rm=9.0; rm2=0; R_POW=2\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=[], add_description=add_description,script3d=script3dv,height3d=8, lib_name=lib_name)\n    w = 14.0; h = 5.0; ddrill = 1.0; rm=9.0; rm2=0; R_POW=5\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=[], add_description=add_description,script3d=script3dv,height3d=18, lib_name=lib_name)\n    w = 26.0; h = 5.0; ddrill = 1.4; rm=20; rm2=0; R_POW=10\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=False, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=[], add_description=add_description,script3d=script3dv,height3d=18, lib_name=lib_name)\n\n    # radial resistors, simple\n    rm2=0; w2=0\n    type = \"simple\"; seriesname = \"Radial_Power\"; add_description = \"http://www.vishay.com/docs/30218/cpcx.pdf\"; name_additions=[]\n    w = 11.0; w2=w-2.0; h = 7.0; ddrill = 1.2; rm=5.0; rm2=0; R_POW=2\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=True, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=[], add_description=add_description,script3d=script3dv,height3d=20.5, lib_name=lib_name)\n    w = 12.0; w2=w-2.0; h = 8.0; ddrill = 1.2; rm=5.0; rm2=0; R_POW=3\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=True, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=[], add_description=add_description,script3d=script3dv,height3d=24.99, lib_name=lib_name)\n    w = 13.0; w2=w-2.0; h = 9.0; ddrill = 1.2; rm=5.0; rm2=0; R_POW=7\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=True, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=[], add_description=add_description,script3d=script3dv,height3d=39, lib_name=lib_name)\n    w = 16.1; w2=w-3; h = 9; ddrill = 1.4; rm=7.37; rm2=0; R_POW=10\n    makeResistorRadial(seriesname=seriesname, rm=rm, w=w, h=h, ddrill=ddrill, R_POW=R_POW, rm2=rm2, vlines=True, w2=w2, type=type, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", name_additions=name_additions, specialtags=[], add_description=add_description,script3d=script3dv,height3d=34.85, lib_name=lib_name)\n"
  },
  {
    "path": "scripts/Resistors_SMD/README.md",
    "content": "## HowTo generate the footprints\n\n```bash\nmkdir Resistors_SMD.pretty\ncd Resistors_SMD.pretty\n../../general/smd_chip.py ../smd_chip_resistors_smd.csv\n```"
  },
  {
    "path": "scripts/Resistors_SMD/generator found under SMD_chip_package_rlc-etc",
    "content": ""
  },
  {
    "path": "scripts/Resistors_SMD/smd_chip_resistors_smd.csv",
    "content": "name,description,tags,model_dir,courtyard,part_x,part_y,pad_x,pad_y,pad_spacing\nR_01005,Resistor SMD 01005,resistor 01005,Resistors_SMD,0.15,0.4,0.2,,,\nR_0201,Resistor SMD 0201,resistor 0201,Resistors_SMD,0.15,0.6,0.3,0.3,0.4,0.25\nR_0402,Resistor SMD 0402,resistor 0402,Resistors_SMD,0.15,1,0.5,0.4,0.6,0.5\nR_0504,Resistor SMD 0504,resistor 0504,Resistors_SMD,0.15,1.27,1.02,,,\nR_0603,Resistor SMD 0603,resistor 0603,Resistors_SMD,0.25,1.6,0.8,0.5,0.9,1\nR_0805,Resistor SMD 0805,resistor 0805,Resistors_SMD,0.25,2,1.25,0.7,1.3,1.2\nR_0907,Resistor SMD 0907,resistor 0907,Resistors_SMD,0.25,2.29,1.78,,,\nR_1008,Resistor SMD 1008,resistor 1008,Resistors_SMD,0.25,2.5,2,,,\nR_1206,Resistor SMD 1206,resistor 1206,Resistors_SMD,0.25,3.2,1.6,0.9,1.7,2\nR_1210,Resistor SMD 1210,resistor 1210,Resistors_SMD,0.25,3.2,2.5,0.9,2.5,2\nR_1218,Resistor SMD 1218,resistor 1218,Resistors_SMD,0.25,3.2,4.6,1,4.9,2\nR_1411,Resistor SMD 1411,resistor 1411,Resistors_SMD,0.25,3.5,2.8,,,\nR_1515,Resistor SMD 1515,resistor 1515,Resistors_SMD,0.25,3.81,3.81,,,\nR_1608,Resistor SMD 1608,resistor 1608,Resistors_SMD,0.25,4,2,,,\nR_1806,Resistor SMD 1806,resistor 1806,Resistors_SMD,0.25,4.5,1.6,,,\nR_1812,Resistor SMD 1812,resistor 1812,Resistors_SMD,0.25,4.5,3.2,1.6,3.5,3.3\nR_1825,Resistor SMD 1825,resistor 1825,Resistors_SMD,0.25,4.5,6.4,,,\nR_2010,Resistor SMD 2010,resistor 2010,Resistors_SMD,0.25,5,2.5,1,2.5,4\nR_2220,Resistor SMD 2220,resistor 2220,Resistors_SMD,0.25,5.7,5,,,\nR_2312,Resistor SMD 2312,resistor 2312,Resistors_SMD,0.25,6,3.2,,,\nR_2512,Resistor SMD 2512,resistor 2512,Resistors_SMD,0.25,6.3,3.2,,,\nR_2515,Resistor SMD 2515,resistor 2515,Resistors_SMD,0.25,6.3,3.81,,,\nR_2716,Resistor SMD 2716,resistor 2716,Resistors_SMD,0.25,7,4,,,\nR_2824,Resistor SMD 2824,resistor 2824,Resistors_SMD,0.25,7.2,6.1,,,\nR_2917,Resistor SMD 2917,resistor 2917,Resistors_SMD,0.25,7.3,4.3,,,\nR_2920,Resistor SMD 2920,resistor 2920,Resistors_SMD,0.25,7.4,5,,,\nR_3111,Resistor SMD 3111,resistor 3111,Resistors_SMD,0.25,8,2.8,,,\nR_3931,Resistor SMD 3931,resistor 3931,Resistors_SMD,0.25,10,8,,,\nR_4018,Resistor SMD 4018,resistor 4018,Resistors_SMD,0.25,10.2,4.6,,,\nR_4020,Resistor SMD 4020,Resistor 4020,Resistors_SMD,0.25,10.2,5,,,\nR_4040,Resistor SMD 4040,resistor 4040,Resistors_SMD,0.25,10.2,10.2,,,\nR_4320,Resistor SMD 4320,resistor 4320,Resistors_SMD,0.25,11,5,,,\nR_4335,Resistor SMD 4335,resistor 4335,Resistors_SMD,0.25,11,9,,,\nR_4349,Resistor SMD 4349,resistor 4349,Resistors_SMD,0.25,11,12.5,,,\nR_4424,Resistor SMD 4424,resistor 4424,Resistors_SMD,0.25,11.11,6.1,,,\nR_4527,Resistor SMD 4527,resistor 4527,Resistors_SMD,0.25,11.5,7,,,\nR_4540,Resistor SMD 4540,resistor 4540,Resistors_SMD,0.25,11.4,10.2,,,\nR_4723,Resistor SMD 4723,resistor 4723,Resistors_SMD,0.25,12,6.1,,,\nR_4825,Resistor SMD 4825,resistor 4825,Resistors_SMD,0.25,12.2,6.35,,,\nR_5550,Resistor SMD 5550,resistor 5550,Resistors_SMD,0.25,14,12.7,,,\nR_5727,Resistor SMD 5727,resistor 5727,Resistors_SMD,0.25,14.4,7,,,\nR_6145,Resistor SMD 6145,resistor 6145,Resistors_SMD,0.25,15.5,11.5,,,\nR_6561,Resistor SMD 6561,resistor 6561,Resistors_SMD,0.25,16.5,15.5,,,\nR_7565,Resistor SMD 7565,resistor 7565,Resistors_SMD,0.25,19.1,16.5,,,\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/SMD_chip_devices.yaml",
    "content": "resistor:\n    fp_lib_name: 'Resistor_SMD'\n    size_definitions: ['size_default_chip_devices.yaml', 'size_wide_body_chip_resistor.yaml', 'size_resistor.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'R'\n    description: 'Resistor SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'resistor'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n\nresistor_smaller_0603:\n    fp_lib_name: 'Resistor_SMD'\n    size_definitions: ['size_default_chip_devices_smaller_0603.yaml']\n    ipc_reference: \"ipc_spec_smaller_0603\"\n    prefix: 'R'\n    description: 'Resistor SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'resistor'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n\nresistor_smaller_0402:\n    fp_lib_name: 'Resistor_SMD'\n    size_definitions: ['size_default_chip_devices_smaller_0402.yaml']\n    ipc_reference: \"ipc_spec_smaller_0603\"\n    prefix: 'R'\n    description: 'Resistor SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'resistor'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n    paste_pad:\n        all_sides_rel: 0.9 #-10%\n        heel_abs: -0.05 # additional heel reduction\n\nresistor_handsolder:\n    #ToDo: only generate > 0402\n    fp_lib_name: 'Resistor_SMD'\n    size_definitions: ['size_default_chip_devices.yaml', 'size_wide_body_chip_resistor.yaml', 'size_resistor.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'R'\n    description: 'Resistor SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal with elongated pad for handsoldering. {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'resistor handsolder'\n    ipc_density: 'nominal'\n    pad_length_addition: 0.35\n    suffix: \"_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder\"\n    include_suffix_in_3dpath: 'False'\n######################################################################################\n\ncapacitor:\n    fp_lib_name: 'Capacitor_SMD'\n    size_definitions: ['size_default_chip_devices.yaml', 'size_capacitor_chip_devices.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'C'\n    description: 'Capacitor SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'capacitor'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n\ncapacitor_smaller_0603:\n    fp_lib_name: 'Capacitor_SMD'\n    size_definitions: ['size_default_chip_devices_smaller_0603.yaml']\n    ipc_reference: \"ipc_spec_smaller_0603\"\n    prefix: 'C'\n    description: 'Capacitor SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'capacitor'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n\ncapacitor_smaller_0402:\n    fp_lib_name: 'Capacitor_SMD'\n    size_definitions: ['size_default_chip_devices_smaller_0402.yaml']\n    ipc_reference: \"ipc_spec_smaller_0603\"\n    prefix: 'C'\n    description: 'Capacitor SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'capacitor'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n    paste_pad:\n        all_sides_rel: 0.9 #-10%\n        heel_abs: -0.05 # additional heel reduction\n\ncapacitor_handsolder:\n    #ToDo: only generate > 0402\n    fp_lib_name: 'Capacitor_SMD'\n    size_definitions: ['size_default_chip_devices.yaml', 'size_capacitor_chip_devices.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'C'\n    description: 'Capacitor SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal with elongated pad for handsoldering. {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'capacitor handsolder'\n    ipc_density: 'nominal'\n    pad_length_addition: 0.35\n    suffix: \"_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder\"\n    include_suffix_in_3dpath: 'False'\n\ncapacitor_tantal:\n    fp_lib_name: 'Capacitor_Tantalum_SMD'\n    size_definitions: ['size_tantal.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'CP'\n    description: 'Tantalum Capacitor SMD {code_letter:s} ({code_metric:s} Metric), IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'capacitor tantalum'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n    polarization_mark: 'True'\n\ncapacitor_tantal_handsolder:\n    fp_lib_name: 'Capacitor_Tantalum_SMD'\n    size_definitions: ['size_tantal.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'CP'\n    description: 'Tantalum Capacitor SMD {code_letter:s} ({code_metric:s} Metric), IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'capacitor tantalum'\n    ipc_density: 'nominal'\n    pad_length_addition: 0.35\n    suffix: \"_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder\"\n    include_suffix_in_3dpath: 'False'\n    polarization_mark: 'True'\n######################################################################################\n\ninductor:\n    fp_lib_name: 'Inductor_SMD'\n    size_definitions: ['size_default_chip_devices.yaml', 'size_inductor.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'L'\n    description: 'Inductor SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'inductor'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n\ninductor_smaller_0603:\n    fp_lib_name: 'Inductor_SMD'\n    size_definitions: ['size_default_chip_devices_smaller_0603.yaml']\n    ipc_reference: \"ipc_spec_smaller_0603\"\n    prefix: 'L'\n    description: 'Inductor SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'inductor'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n\ninductor_smaller_0402:\n    fp_lib_name: 'Inductor_SMD'\n    size_definitions: ['size_default_chip_devices_smaller_0402.yaml']\n    ipc_reference: \"ipc_spec_smaller_0603\"\n    prefix: 'L'\n    description: 'Inductor SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'inductor'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n    paste_pad:\n        all_sides_rel: 0.9 #-10%\n        heel_abs: -0.05 # additional heel reduction\n\ninductor_handsolder:\n    #ToDo: only generate > 0402\n    fp_lib_name: 'Inductor_SMD'\n    size_definitions: ['size_default_chip_devices.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'L'\n    description: 'Capacitor SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal with elongated pad for handsoldering. {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'inductor handsolder'\n    ipc_density: 'nominal'\n    pad_length_addition: 0.35\n    suffix: \"_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder\"\n    include_suffix_in_3dpath: 'False'\n######################################################################################\n\ndiode:\n    fp_lib_name: 'Diode_SMD'\n    size_definitions: ['size_default_chip_devices.yaml', 'size_diode.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'D'\n    description: 'Diode SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'diode'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    polarization_mark: 'True'\n    suffix: \"\"\n\ndiode_smaller_0603:\n    fp_lib_name: 'Diode_SMD'\n    size_definitions: ['size_default_chip_devices_smaller_0603.yaml']\n    ipc_reference: \"ipc_spec_smaller_0603\"\n    prefix: 'D'\n    description: 'Diode SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'diode'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    polarization_mark: 'True'\n    suffix: \"\"\n\ndiode_smaller_0402:\n    fp_lib_name: 'Diode_SMD'\n    size_definitions: ['size_default_chip_devices_smaller_0402.yaml']\n    ipc_reference: \"ipc_spec_smaller_0603\"\n    prefix: 'D'\n    description: 'Diode SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'diode'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    polarization_mark: 'True'\n    suffix: \"\"\n    paste_pad:\n        all_sides_rel: 0.9 #-10%\n        heel_abs: -0.05 # additional heel reduction\n\ndiode_handsolder:\n    fp_lib_name: 'Diode_SMD'\n    size_definitions: ['size_default_chip_devices.yaml', 'size_diode.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'D'\n    description: 'Diode SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'diode handsolder'\n    ipc_density: 'nominal'\n    pad_length_addition: 0.35\n    polarization_mark: 'True'\n    suffix: \"_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder\"\n    include_suffix_in_3dpath: 'False'\n\ndiode_castellated:\n    fp_lib_name: 'Diode_SMD'\n    size_definitions: ['size_default_chip_devices.yaml', 'size_diode.yaml']\n    ipc_reference: \"ipc_spec_castellated\"\n    prefix: 'D'\n    description: 'Diode SMD {code_imperial:s} ({code_metric:s} Metric), castellated end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'diode castellated'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    polarization_mark: 'True'\n    suffix: \"_Castellated\"\n######################################################################################\n\nled:\n    fp_lib_name: 'LED_SMD'\n    size_definitions: ['size_default_chip_devices.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'LED'\n    description: 'LED SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'diode'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    polarization_mark: 'True'\n    suffix: \"\"\n\nled_smaller_0603:\n    fp_lib_name: 'LED_SMD'\n    size_definitions: ['size_default_chip_devices_smaller_0603.yaml']\n    ipc_reference: \"ipc_spec_smaller_0603\"\n    prefix: 'LED'\n    description: 'LED SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'LED'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    polarization_mark: 'True'\n    suffix: \"\"\n\n\nled_smaller_0402:\n    fp_lib_name: 'LED_SMD'\n    size_definitions: ['size_default_chip_devices_smaller_0402.yaml']\n    ipc_reference: \"ipc_spec_smaller_0603\"\n    prefix: 'LED'\n    description: 'LED SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'LED'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    polarization_mark: 'True'\n    suffix: \"\"\n    paste_pad:\n        all_sides_rel: 0.9 #-10%\n        heel_abs: -0.05 # additional heel reduction\n\nled_handsolder:\n    fp_lib_name: 'LED_SMD'\n    size_definitions: ['size_default_chip_devices.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'LED'\n    description: 'LED SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'LED handsolder'\n    ipc_density: 'nominal'\n    pad_length_addition: 0.35\n    polarization_mark: 'True'\n    suffix: \"_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder\"\n    include_suffix_in_3dpath: 'False'\n\nled_castellated:\n    fp_lib_name: 'LED_SMD'\n    size_definitions: ['size_default_chip_devices.yaml']\n    ipc_reference: \"ipc_spec_castellated\"\n    prefix: 'LED'\n    description: 'LED SMD {code_imperial:s} ({code_metric:s} Metric), castellated end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'LED castellated'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    polarization_mark: 'True'\n    suffix: \"_Castellated\"\n\n###############################################################################\nfuse:\n    fp_lib_name: 'Fuse'\n    size_definitions: ['size_default_chip_devices.yaml', 'size_fuse.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'Fuse'\n    description: 'Fuse SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'fuse'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n\nfuse_smaller_0603:\n    fp_lib_name: 'Fuse'\n    size_definitions: ['size_default_chip_devices_smaller_0603.yaml']\n    ipc_reference: \"ipc_spec_smaller_0603\"\n    prefix: 'Fuse'\n    description: 'Fuse SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'fuse'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n\nfuse_smaller_0402:\n    fp_lib_name: 'Fuse'\n    size_definitions: ['size_default_chip_devices_smaller_0402.yaml']\n    ipc_reference: \"ipc_spec_smaller_0603\"\n    prefix: 'Fuse'\n    description: 'Fuse SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal, {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'fuse'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"\"\n    paste_pad:\n        all_sides_rel: 0.9 #-10%\n        heel_abs: -0.05 # additional heel reduction\n\nfuse_handsolder:\n    fp_lib_name: 'Fuse'\n    size_definitions: ['size_default_chip_devices.yaml', 'size_fuse.yaml']\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    prefix: 'Fuse'\n    description: 'Fuse SMD {code_imperial:s} ({code_metric:s} Metric), square (rectangular) end terminal, IPC_7351 nominal with elongated pad for handsoldering. {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'fuse handsolder'\n    ipc_density: 'nominal'\n    pad_length_addition: 0.35\n    suffix: \"_Pad{pad_x:.2f}x{pad_y:.2f}mm_HandSolder\"\n    include_suffix_in_3dpath: 'False'\n\nfuse_castellated:\n    fp_lib_name: 'Fuse'\n    size_definitions: ['size_default_chip_devices.yaml', 'size_fuse.yaml']\n    ipc_reference: \"ipc_spec_castellated\"\n    prefix: 'Fuse'\n    description: 'Fuse SMD {code_imperial:s} ({code_metric:s} Metric), castellated end terminal, IPC_7351. {size_info:s}, generated with kicad-footprint-generator'\n    keywords: 'fuse castellated'\n    ipc_density: 'nominal'\n    pad_length_addition: 0\n    suffix: \"_Castellated\"\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/SMD_chip_package_rlc-etc.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nimport argparse\nimport yaml\nimport math\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load parent path of KicadModTree\n\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\nsys.path.append(os.path.join(sys.path[0], \"..\", \"tools\"))  # load parent path of tools\nfrom footprint_text_fields import addTextFields\nfrom ipc_pad_size_calculators import *\nfrom drawing_tools import nearestSilkPointOnOrthogonalLineSmallClerance\n\nsize_definition_path = \"size_definitions/\"\ndef roundToBase(value, base):\n    return round(value/base) * base\n\ndef merge_dicts(*dict_args):\n    \"\"\"\n    Given any number of dicts, shallow copy and merge into a new dict,\n    precedence goes to key value pairs in latter dicts.\n    \"\"\"\n    result = {}\n    for dictionary in dict_args:\n        result.update(dictionary)\n    return result\n\nclass TwoTerminalSMDchip():\n    def __init__(self, command_file, configuration):\n        self.configuration = configuration\n        with open(command_file, 'r') as command_stream:\n            try:\n                self.footprint_group_definitions = yaml.safe_load(command_stream)\n            except yaml.YAMLError as exc:\n                print(exc)\n        ipc_doc = configuration['ipc_definition']\n        with open(ipc_doc, 'r') as ipc_stream:\n            try:\n                self.ipc_defintions = yaml.safe_load(ipc_stream)\n            except yaml.YAMLError as exc:\n                print(exc)\n\n    def calcPadDetails(self, device_dimensions, ipc_data, ipc_round_base, footprint_group_data):\n        # Zmax = Lmin + 2JT + √(CL^2 + F^2 + P^2)\n        # Gmin = Smax − 2JH − √(CS^2 + F^2 + P^2)\n        # Xmax = Wmin + 2JS + √(CW^2 + F^2 + P^2)\n\n        # Some manufacturers do not list the terminal spacing (S) in their datasheet but list the terminal lenght (T)\n        # Then one can calculate\n        # Stol(RMS) = √(Ltol^2 + 2*^2)\n        # Smin = Lmin - 2*Tmax\n        # Smax(RMS) = Smin + Stol(RMS)\n\n        manf_tol = {\n            'F': self.configuration.get('manufacturing_tolerance', 0.1),\n            'P': self.configuration.get('placement_tolerance', 0.05)\n        }\n\n        if 'terminal_width' in device_dimensions:\n            lead_width = device_dimensions['terminal_width']\n        else:\n            lead_width = device_dimensions['body_width']\n\n        Gmin, Zmax, Xmax = ipc_body_edge_inside(ipc_data, ipc_round_base, manf_tol,\n                device_dimensions['body_length'], lead_width,\n                lead_len=device_dimensions.get('terminal_length'),\n                lead_inside=device_dimensions.get('terminator_spacing'))\n\n        Zmax += footprint_group_data.get('pad_length_addition', 0)\n        Pad = {'at':[-(Zmax+Gmin)/4,0], 'size':[(Zmax-Gmin)/2,Xmax]}\n        Paste = None\n\n        if 'paste_pad' in footprint_group_data:\n            rel_reduction_factor = footprint_group_data['paste_pad'].get('all_sides_rel', 0.9)\n            x_abs_reduction = (1 - rel_reduction_factor)*Pad['size'][0]\n            Zmax -= 2*x_abs_reduction\n            Gmin += 2*x_abs_reduction - 2 * footprint_group_data['paste_pad'].get('heel_abs',0)\n            Xmax *= rel_reduction_factor\n            Paste = {'at':[-(Zmax+Gmin)/4,0], 'size':[(Zmax-Gmin)/2,Xmax]}\n\n        return Pad, Paste\n\n    @staticmethod\n    def deviceDimensions(device_size_data):\n        dimensions = {\n            'body_length': TolerancedSize.fromYaml(device_size_data, base_name='body_length'),\n            'body_width': TolerancedSize.fromYaml(device_size_data, base_name='body_width')\n        }\n        if 'terminator_spacing_max' in device_size_data and 'terminator_spacing_min' in device_size_data or 'terminator_spacing' in device_size_data:\n            dimensions['terminator_spacing'] = TolerancedSize.fromYaml(device_size_data, base_name='terminator_spacing')\n        elif 'terminal_length_max' in device_size_data and 'terminal_length_min' in device_size_data or 'terminal_length' in device_size_data:\n            dimensions['terminal_length'] = TolerancedSize.fromYaml(device_size_data, base_name='terminal_length')\n        else:\n            raise KeyError(\"Either terminator spacing or terminal lenght must be included in the size definition.\")\n\n        if 'terminal_width_min' in device_size_data and 'terminal_width_max' in device_size_data or 'terminal_width' in device_size_data:\n            dimensions['terminal_width'] = TolerancedSize.fromYaml(device_size_data, base_name='terminal_width')\n\n        return dimensions\n\n    def generateFootprints(self):\n        for group_name in self.footprint_group_definitions:\n            #print(device_group)\n            footprint_group_data = self.footprint_group_definitions[group_name]\n\n            device_size_docs = footprint_group_data['size_definitions']\n            package_size_defintions={}\n            for device_size_doc in device_size_docs:\n                with open(size_definition_path+device_size_doc, 'r') as size_stream:\n                    try:\n                        package_size_defintions.update(yaml.safe_load(size_stream))\n                    except yaml.YAMLError as exc:\n                        print(exc)\n\n            for size_name in package_size_defintions:\n                device_size_data = package_size_defintions[size_name]\n                try:\n                    self.generateFootprint(device_size_data,\n                            footprint_group_data)\n                except Exception as exc:\n                    print(\"Failed to generate {size_name} (group: {group_name}):\".format(\n                                size_name=size_name, group_name=group_name))\n                    print(exc)\n\n    def generateFootprint(self, device_size_data, footprint_group_data):\n        fab_line_width = self.configuration.get('fab_line_width', 0.1)\n        silk_line_width = self.configuration.get('silk_line_width', 0.12)\n\n        device_dimensions = TwoTerminalSMDchip.deviceDimensions(device_size_data)\n\n        ipc_reference = footprint_group_data['ipc_reference']\n        ipc_density = footprint_group_data['ipc_density']\n        ipc_data_set = self.ipc_defintions[ipc_reference][ipc_density]\n        ipc_round_base = self.ipc_defintions[ipc_reference]['round_base']\n\n        pad_details, paste_details = self.calcPadDetails(device_dimensions, ipc_data_set, ipc_round_base, footprint_group_data)\n        #print(calc_pad_details())\n        #print(\"generate {name}.kicad_mod\".format(name=footprint))\n\n        suffix = footprint_group_data.get('suffix', '').format(pad_x=pad_details['size'][0],\n            pad_y=pad_details['size'][1])\n        prefix = footprint_group_data['prefix']\n\n        model3d_path_prefix = self.configuration.get('3d_model_prefix','${KISYS3DMOD}')\n        suffix_3d = suffix if footprint_group_data.get('include_suffix_in_3dpath', 'True') == 'True' else \"\"\n\n        code_metric = device_size_data.get('code_metric')\n        code_letter = device_size_data.get('code_letter')\n        code_imperial = device_size_data.get('code_imperial')\n\n        if 'code_letter' in device_size_data:\n            name_format = self.configuration['fp_name_tantal_format_string']\n        else:\n            if 'code_metric' in device_size_data:\n                name_format = self.configuration['fp_name_format_string']\n            else:\n                name_format = self.configuration['fp_name_non_metric_format_string']\n\n        fp_name = name_format.format(prefix=prefix,\n            code_imperial=code_imperial, code_metric=code_metric,\n            code_letter=code_letter, suffix=suffix)\n        fp_name_2 = name_format.format(prefix=prefix,\n            code_imperial=code_imperial, code_letter=code_letter,\n            code_metric=code_metric, suffix=suffix_3d)\n        model_name = '{model3d_path_prefix:s}{lib_name:s}.3dshapes/{fp_name:s}.wrl'.format(\n            model3d_path_prefix=model3d_path_prefix, lib_name=footprint_group_data['fp_lib_name'], fp_name=fp_name_2)\n        #print(fp_name)\n        #print(pad_details)\n\n        kicad_mod = Footprint(fp_name)\n\n        # init kicad footprint\n        kicad_mod.setDescription(footprint_group_data['description'].format(code_imperial=code_imperial,\n            code_metric=code_metric, code_letter=code_letter,\n            size_info=device_size_data.get('size_info')))\n        kicad_mod.setTags(footprint_group_data['keywords'])\n        kicad_mod.setAttribute('smd')\n\n        pad_shape_details = {}\n        pad_shape_details['shape'] = Pad.SHAPE_ROUNDRECT\n        pad_shape_details['radius_ratio'] = configuration.get('round_rect_radius_ratio', 0)\n        if 'round_rect_max_radius' in configuration:\n            pad_shape_details['maximum_radius'] = configuration['round_rect_max_radius']\n\n\n        if paste_details is not None:\n            layers_main = ['F.Cu', 'F.Mask']\n\n            kicad_mod.append(Pad(number= '', type=Pad.TYPE_SMT,\n                layers=['F.Paste'], **merge_dicts(paste_details, pad_shape_details)))\n            paste_details['at'][0] *= (-1)\n            kicad_mod.append(Pad(number= '', type=Pad.TYPE_SMT,\n                layers=['F.Paste'], **merge_dicts(paste_details, pad_shape_details)))\n        else:\n            layers_main = Pad.LAYERS_SMT\n\n        P1 = Pad(number= 1, type=Pad.TYPE_SMT,\n            layers=layers_main, **merge_dicts(pad_details, pad_shape_details))\n        pad_radius = P1.getRoundRadius()\n\n        kicad_mod.append(P1)\n        pad_details['at'][0] *= (-1)\n        kicad_mod.append(Pad(number= 2, type=Pad.TYPE_SMT,\n            layers=layers_main, **merge_dicts(pad_details, pad_shape_details)))\n\n        fab_outline = self.configuration.get('fab_outline', 'typical')\n        if fab_outline == 'max':\n            outline_size = [device_dimensions['body_length'].maximum, device_dimensions['body_width'].maximum]\n        elif fab_outline == 'min':\n            outline_size = [device_dimensions['body_length'].minimum, device_dimensions['body_width'].minimum]\n        else:\n            outline_size = [device_dimensions['body_length'].nominal, device_dimensions['body_width'].nominal]\n\n        if footprint_group_data.get('polarization_mark', 'False') == 'True':\n            polararity_marker_size = self.configuration.get('fab_polarity_factor', 0.25)\n            polararity_marker_size *= (outline_size[1] if outline_size[1] < outline_size[0] else outline_size[0])\n\n            polarity_marker_thick_line = False\n\n            polarity_max_size = self.configuration.get('fab_polarity_max_size', 1)\n            if polararity_marker_size > polarity_max_size:\n                polararity_marker_size = polarity_max_size\n            polarity_min_size = self.configuration.get('fab_polarity_min_size', 0.25)\n            if polararity_marker_size < polarity_min_size:\n                if polararity_marker_size < polarity_min_size*0.6:\n                    polarity_marker_thick_line = True\n                polararity_marker_size = polarity_min_size\n\n            silk_x_left = -abs(pad_details['at'][0]) - pad_details['size'][0]/2 - \\\n                self.configuration['silk_pad_clearance'] - silk_line_width/2\n\n            silk_y_bottom = max(\n                self.configuration['silk_pad_clearance'] + silk_line_width/2 + pad_details['size'][1]/2,\n                outline_size[1]/2 + self.configuration['silk_fab_offset']\n                )\n\n            if polarity_marker_thick_line:\n                kicad_mod.append(RectLine(start=[-outline_size[0]/2, outline_size[1]/2],\n                    end=[outline_size[0]/2, -outline_size[1]/2],\n                    layer='F.Fab', width=fab_line_width))\n                x = -outline_size[0]/2 + fab_line_width\n                kicad_mod.append(Line(start=[x, outline_size[1]/2],\n                    end=[x, -outline_size[1]/2],\n                    layer='F.Fab', width=fab_line_width))\n                x += fab_line_width\n                if x < -fab_line_width/2:\n                    kicad_mod.append(Line(start=[x, outline_size[1]/2],\n                        end=[x, -outline_size[1]/2],\n                        layer='F.Fab', width=fab_line_width))\n\n                kicad_mod.append(Circle(center=[silk_x_left-0.05, 0],\n                    radius=0.05, layer=\"F.SilkS\", width=0.1))\n            else:\n                poly_fab= [\n                    {'x':outline_size[0]/2,'y':-outline_size[1]/2},\n                    {'x':polararity_marker_size - outline_size[0]/2,'y':-outline_size[1]/2},\n                    {'x':-outline_size[0]/2,'y':polararity_marker_size-outline_size[1]/2},\n                    {'x':-outline_size[0]/2,'y':outline_size[1]/2},\n                    {'x':outline_size[0]/2,'y':outline_size[1]/2},\n                    {'x':outline_size[0]/2,'y':-outline_size[1]/2}\n                ]\n                kicad_mod.append(PolygoneLine(polygone=poly_fab, layer='F.Fab', width=fab_line_width))\n\n                poly_silk = [\n                    {'x':outline_size[0]/2,'y':-silk_y_bottom},\n                    {'x':silk_x_left,'y':-silk_y_bottom},\n                    {'x':silk_x_left,'y':silk_y_bottom},\n                    {'x':outline_size[0]/2,'y':silk_y_bottom}\n                ]\n                kicad_mod.append(PolygoneLine(polygone=poly_silk, layer='F.SilkS', width=silk_line_width))\n        else:\n            kicad_mod.append(RectLine(start=[-outline_size[0]/2, outline_size[1]/2],\n                end=[outline_size[0]/2, -outline_size[1]/2],\n                layer='F.Fab', width=fab_line_width))\n\n            silk_outline_y = outline_size[1]/2 + self.configuration['silk_fab_offset']\n            default_clearance = self.configuration.get('silk_pad_clearance', 0.2)\n            silk_point_top_right = nearestSilkPointOnOrthogonalLineSmallClerance(\n                pad_size=pad_details['size'], pad_position=pad_details['at'], pad_radius=pad_radius,\n                fixed_point=Vector2D(0, silk_outline_y),\n                moving_point=Vector2D(outline_size[0]/2, silk_outline_y),\n                silk_pad_offset_default=(silk_line_width/2+default_clearance),\n                silk_pad_offset_reduced=(silk_line_width/2\\\n                    +self.configuration.get('silk_clearance_small_parts', default_clearance)),\n                min_lenght=configuration.get('silk_line_lenght_min', 0)/2)\n\n            if silk_point_top_right:\n                kicad_mod.append(Line(\n                    start=[-silk_point_top_right.x, -silk_point_top_right.y],\n                    end=[silk_point_top_right.x, -silk_point_top_right.y],\n                    layer='F.SilkS', width=silk_line_width))\n                kicad_mod.append(Line(\n                    start=[-silk_point_top_right.x, silk_point_top_right.y],\n                    end=silk_point_top_right,\n                    layer='F.SilkS', width=silk_line_width))\n\n        CrtYd_rect = [None,None]\n        CrtYd_rect[0] = roundToBase(2 * abs(pad_details['at'][0]) + \\\n            pad_details['size'][0] + 2 * ipc_data_set['courtyard'], 0.02)\n        if pad_details['size'][1] > outline_size[1]:\n            CrtYd_rect[1] = pad_details['size'][1] + 2 * ipc_data_set['courtyard']\n        else:\n            CrtYd_rect[1] = outline_size[1] + 2 * ipc_data_set['courtyard']\n\n        CrtYd_rect[1] = roundToBase(CrtYd_rect[1], 0.02)\n\n        kicad_mod.append(RectLine(start=[-CrtYd_rect[0]/2, CrtYd_rect[1]/2],\n            end=[CrtYd_rect[0]/2, -CrtYd_rect[1]/2],\n            layer='F.CrtYd', width=self.configuration['courtyard_line_width']))\n\n        ######################### Text Fields ###############################\n\n        addTextFields(kicad_mod=kicad_mod, configuration=configuration,\n            body_edges={'left':-outline_size[0]/2,'right':outline_size[0]/2,\n                        'top':-outline_size[1]/2,'bottom':outline_size[1]/2},\n            courtyard={'top':-CrtYd_rect[1]/2, 'bottom':CrtYd_rect[1]/2}, fp_name=fp_name, text_y_inside_position='center')\n\n        kicad_mod.append(Model(filename=model_name))\n        output_dir = '{lib_name:s}.pretty/'.format(lib_name=footprint_group_data['fp_lib_name'])\n        if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n            os.makedirs(output_dir)\n        filename =  '{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=fp_name)\n\n        file_handler = KicadFileHandler(kicad_mod)\n        file_handler.writeFile(filename)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='use confing .yaml files to create footprints.')\n    parser.add_argument('files', metavar='file', type=str, nargs='+',\n                        help='list of files holding information about what devices should be created.')\n    parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../tools/global_config_files/config_KLCv3.0.yaml')\n    parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='config_KLCv3.0.yaml')\n    parser.add_argument('--ipc_definition', type=str, nargs='?', help='the ipc definition file', default='ipc7351B_smd_two_terminal_chip.yaml')\n    parser.add_argument('--force_rectangle_pads', action='store_true', help='Force the generation of rectangle pads instead of rounded rectangle (KiCad 4.x compatibility.)')\n    args = parser.parse_args()\n\n    with open(args.global_config, 'r') as config_stream:\n        try:\n            configuration = yaml.safe_load(config_stream)\n        except yaml.YAMLError as exc:\n            print(exc)\n\n    with open(args.series_config, 'r') as config_stream:\n        try:\n            configuration.update(yaml.safe_load(config_stream))\n        except yaml.YAMLError as exc:\n            print(exc)\n    args = parser.parse_args()\n    configuration['ipc_definition'] = args.ipc_definition\n    if args.force_rectangle_pads:\n        configuration['round_rect_max_radius'] = None\n        configuration['round_rect_radius_ratio'] = 0\n\n    for filepath in args.files:\n        two_terminal_smd =TwoTerminalSMDchip(filepath, configuration)\n        two_terminal_smd.generateFootprints()\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/config_KLCv3.0.yaml",
    "content": "# This holds the configuration information\n# using this config file will create KLCv3.0 compatible footprints.\n\nplacement_tolerance: 0.05\nmanufacturing_tolerance: 0.1\n\nfp_name_format_string: '{prefix:s}_{code_imperial:s}_{code_metric:s}Metric{suffix:s}'\nfp_name_non_metric_format_string: '{prefix:s}_{code_imperial:s}{suffix:s}'\n\nfp_name_tantal_format_string: '{prefix:s}_EIA-{code_metric:s}_{code_letter:s}{suffix:s}'\n\n3d_model_prefix: '${KISYS3DMOD}/'\n\n\nfab_outline: 'typical' # typical | max | min\nfab_polarity_min_size: 0.3\nfab_polarity_max_size: 1\nfab_polarity_factor: 0.25\n\nsilk_clearance_small_parts: 0.1\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/ipc7351B_smd_two_terminal_chip.yaml",
    "content": "# Dimensions taken from ipc7351b\n\n# < 0603 (1608 Metric)\n#           | Minimum | Median    | Maximum |\n#           | (Least) | (Nominal) | (Most)  |\n#           | Density | Density   | Density | round\n# Lead Part | Level C | Level B   | Level A |  to\n# ----------+---------+-----------+---------+-\n# Toe (JT)  |  0.1    |  0.2      |  0.3    | 0.02\n# Heel (JH) |  0.0    |  0.0      |  0.0    | 0.02\n# Side (JS) |  -0.05  |  0.0      |  0.05   | 0.02\n# Courtyard |  0.1    |  0.15     |  0.2    |\n\nipc_spec_smaller_0603:\n    least:\n        toe: 0.1\n        heel: 0\n        side: -0.05\n        courtyard: 0.1\n    nominal:\n        toe: 0.2\n        heel: 0\n        side: 0.0\n        courtyard: 0.15\n    most:\n        toe: 0.3\n        heel: 0\n        side: 0.05\n        courtyard: 0.2\n    round_base:\n        toe: 0.02\n        heel: 0.02\n        side: 0.02\n\n\n# >= 0603 (1608 Metric)\n#           | Minimum | Median    | Maximum\n#           | (Least) | (Nominal) | (Most)\n#           | Density | Density   | Density\n# Lead Part | Level C | Level B   | Level A\n# ----------+---------+-----------+--------\n# Toe (JT)  |  0.15   |  0.35     |  0.55\n# Heel (JH) |  0.0    |  0.0      |  0.0\n# Side (JS) |  -0.05  |  0.00     |  0.05\n# Courtyard |  0.1    |  0.25     |  0.5\n\nipc_spec_larger_or_equal_0603:\n    least:\n        toe: 0.15\n        heel: 0.0\n        side: -0.05\n        courtyard: 0.1\n    nominal:\n        toe: 0.35\n        heel: 0.0\n        side: 0.00\n        courtyard: 0.25\n    most:\n        toe: 0.55\n        heel: 0.0\n        side: 0.05\n        courtyard: 0.5\n    round_base:\n        toe: 0.05\n        heel: 0.05\n        side: 0.05\n\n\n# tantalum cap\n#           | Minimum | Median    | Maximum\n#           | (Least) | (Nominal) | (Most)\n#           | Density | Density   | Density\n# Lead Part | Level C | Level B   | Level A\n# ----------+---------+-----------+--------\n# Toe (JT)  |  0.07   |  0.15     |  0.25\n# Heel (JH) |  0.20   |  0.50     |  0.80\n# Side (JS) | -0.10   | -0.05     |  0.01\n# Courtyard |  0.1    |  0.25     |  0.5\n\nipc_spec_tantalumn:\n    least:\n        toe: 0.07\n        heel: 0.2\n        side: -0.1\n        courtyard: 0.1\n    nominal:\n        toe: 0.15\n        heel: 0.5\n        side: -0.05\n        courtyard: 0.25\n    most:\n        toe: 0.25\n        heel: 0.8\n        side: 0.01\n        courtyard: 0.5\n    round_base:\n        toe: 0.05\n        heel: 0.05\n        side: 0.05\n\n# castellated\n# The document is a bit strange with the castellated definitions.\n# They seem to exchange the toe and heel fillet.\n# For square terminated parts the toe fillet is towards the outside = Z measurement\n# But for castellated they tell us that the heel fillet is responsible for the Z measurement.\n# As the script interprets toe to point outwards (=Z dim) we change these two compared to the\n# ipc document.\n\n#           | Minimum | Median    | Maximum\n#           | (Least) | (Nominal) | (Most)\n#           | Density | Density   | Density\n# Lead Part | Level C | Level B   | Level A\n# ----------+---------+-----------+--------\n# Toe (JT)  |  0.45   |  0.55     |  0.65\n# Heel (JH) |  0.05   |  0.15     |  0.25\n# Side (JS) | -0.15   | -0.05     |  0.05\n# Courtyard |  0.1    |  0.25     |  0.5\n\nipc_spec_castellated:\n    least:\n        toe: 0.45\n        heel: 0.05\n        side: -0.15\n        courtyard: 0.1\n    nominal:\n        toe: 0.55\n        heel: 0.15\n        side: -0.05\n        courtyard: 0.25\n    most:\n        toe: 0.65\n        heel: 0.25\n        side: 0.05\n        courtyard: 0.5\n    round_base:\n        toe: 0.05\n        heel: 0.05\n        side: 0.05\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/ipc_smd_two_terminal_chip.yaml",
    "content": "# IPC IPC-7351 http://pcbget.ru/Files/Standarts/IPC_7351.pdf\n# Page 23\n\n# < 0603 (1608 Metric)\n#           | Minimum | Median    | Maximum |\n#           | (Least) | (Nominal) | (Most)  |\n#           | Density | Density   | Density | round\n# Lead Part | Level C | Level B   | Level A |  to\n# ----------+---------+-----------+---------+-\n# Toe (JT)  |  0.0    |  0.1      |  0.2    | 0.05\n# Heel (JH) | -0.05   | -0.05     | -0.05   | 0.05\n# Side (JS) |  0.00   | 0.00      |  0.05   | 0.05\n# Courtyard |  0.1    | 0.15      |  0.2    |\n\nipc_spec_smaller_0603:\n    least:\n        toe: 0.0\n        heel: -0.05\n        side: 0.0\n        courtyard: 0.1\n    nominal:\n        toe: 0.1\n        heel: -0.05\n        side: 0.0\n        courtyard: 0.15\n    most:\n        toe: 0.2\n        heel: -0.05\n        side: 0.05\n        courtyard: 0.2\n    round_base:\n        toe: 0.05\n        heel: 0.05\n        side: 0.05\n\n# >= 0603 (1608 Metric)\n#           | Minimum | Median    | Maximum\n#           | (Least) | (Nominal) | (Most)\n#           | Density | Density   | Density\n# Lead Part | Level C | Level B   | Level A\n# ----------+---------+-----------+--------\n# Toe (JT)  |  0.15   |  0.35     |  0.55\n# Heel (JH) | -0.05   | -0.05     | -0.05\n# Side (JS) |  -0.05  |  0.00     |  0.05\n# Courtyard |  0.1    |  0.25     |  0.5\n\nipc_spec_larger_or_equal_0603:\n    least:\n        toe: 0.15\n        heel: -0.05\n        side: -0.05\n        courtyard: 0.1\n    nominal:\n        toe: 0.35\n        heel: -0.05\n        side: 0.00\n        courtyard: 0.25\n    most:\n        toe: 0.55\n        heel: -0.05\n        side: 0.05\n        courtyard: 0.5\n    round_base:\n        toe: 0.02\n        heel: 0.02\n        side: 0.1\n\n\n# tantalum cap\n#           | Minimum | Median    | Maximum\n#           | (Least) | (Nominal) | (Most)\n#           | Density | Density   | Density\n# Lead Part | Level C | Level B   | Level A\n# ----------+---------+-----------+--------\n# Toe (JT)  |  0.07   |  0.15     |  0.25\n# Heel (JH) |  0.20   |  0.50     |  0.80\n# Side (JS) | -0.10   | -0.05     |  0.01\n# Courtyard |  0.1    |  0.25     |  0.5\n\nipc_spec_tantalumn:\n    least:\n        toe: 0.07\n        heel: 0.2\n        side: -0.1\n        courtyard: 0.1\n    nominal:\n        toe: 0.15\n        heel: 0.5\n        side: -0.05\n        courtyard: 0.25\n    most:\n        toe: 0.25\n        heel: 0.8\n        side: 0.01\n        courtyard: 0.5\n    round_base:\n        toe: 0.02\n        heel: 0.02\n        side: 0.1\n\n# castellated\n# The document is a bit strange with the castellated definitions.\n# They seem to exchange the toe and heel fillet.\n# For square terminated parts the toe fillet is towards the outside = Z measurement\n# But for castellated they tell us that the heel fillet is responsible for the Z measurement.\n# As the script interprets toe to point outwards (=Z dim) we change these two compared to the\n# ipc document.\n\n#           | Minimum | Median    | Maximum\n#           | (Least) | (Nominal) | (Most)\n#           | Density | Density   | Density\n# Lead Part | Level C | Level B   | Level A\n# ----------+---------+-----------+--------\n# Toe (JT)  |  0.45   |  0.55     |  0.65\n# Heel (JH) |  0.05   |  0.15     |  0.25\n# Side (JS) | -0.15   | -0.05     |  0.05\n# Courtyard |  0.1    |  0.25     |  0.5\n\nipc_spec_castellated:\n    least:\n        toe: 0.45\n        heel: 0.05\n        side: -0.15\n        courtyard: 0.1\n    nominal:\n        toe: 0.55\n        heel: 0.15\n        side: -0.05\n        courtyard: 0.25\n    most:\n        toe: 0.65\n        heel: 0.25\n        side: 0.05\n        courtyard: 0.5\n    round_base:\n        toe: 0.02\n        heel: 0.02\n        side: 0.01\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/size_definitions/size_capacitor_chip_devices.yaml",
    "content": "\nSMD_1825:\n    code_imperial: \"1825\"\n    code_metric: \"4564\"\n    body_length:\n        nominal: 4.6\n        tolerance: 0.5\n    body_width:\n        nominal: 6.3\n        tolerance: 0.4\n    terminal_length:\n        nominal: 0.75\n        tolerance: 0.35\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    size_info: '(Body size from: http://datasheets.avx.com/AVX-HV_MLCC.pdf)'\n\nSMD_2220:\n    code_imperial: \"2220\"\n    code_metric: \"5650\"\n    body_length:\n        nominal: 5.7\n        tolerance: 0.5\n    body_width:\n        nominal: 5.0\n        tolerance: 0.4\n    terminal_length:\n        nominal: 0.85\n        tolerance: 0.35\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    size_info: '(Body size from: http://datasheets.avx.com/AVX-HV_MLCC.pdf)'\n\nSMD_2225:\n    code_imperial: \"2225\"\n    code_metric: \"5664\"\n    body_length:\n        nominal: 5.72\n        tolerance: 0.25\n    body_width:\n        nominal: 6.35\n        tolerance: 0.25\n    terminal_length:\n        nominal: 0.85\n        tolerance: 0.35\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    size_info: '(Body size from: http://datasheets.avx.com/AVX-HV_MLCC.pdf)'\n\nSMD_3640:\n    code_imperial: \"3640\"\n    code_metric: \"9110\"\n    body_length:\n        nominal: 9.14\n        tolerance: 0.25\n    body_width:\n        nominal: 10.2\n        tolerance: 0.25\n    terminal_length:\n        minimum: 0.76\n        maximum: 1.52\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    size_info: '(Body size from: http://datasheets.avx.com/AVX-HV_MLCC.pdf)'\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/size_definitions/size_default_chip_devices.yaml",
    "content": "SMD_0603:\n    code_imperial: \"0603\"\n    code_metric: \"1608\"\n    body_length: 1.6\n    body_length_min: 1.5\n    body_length_max: 1.7\n    body_width: 0.8\n    body_width_min: 0.7\n    body_width_max: 0.95\n    terminator_spacing_min: 0.7\n    terminator_spacing_max: 1.11\n    size_info: '(Body size source: http://www.tortai-tech.com/upload/download/2011102023233369053.pdf)'\n\nSMD_0805:\n    code_imperial: \"0805\"\n    code_metric: \"2012\"\n    body_length: 2.0\n    body_length_min: 1.86\n    body_length_max: 2.15\n    body_width: 1.2\n    body_width_min: 1.12\n    body_width_max: 1.38\n    terminator_spacing_min: 0.89\n    terminator_spacing_max: 1.55\n    size_info: '(Body size source: https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing)'\n\n# SMD_1008:\n# I did not find any part that uses this package.\n#     code_imperial: \"1008\"\n#     code_metric: \"2520\"\n#     body_length: 2.5\n#     body_length_min:\n#     body_width: 2.0\n#     body_width_min:\n#     terminator_spacing_max:\n\nSMD_1206:\n    code_imperial: \"1206\"\n    code_metric: \"3216\"\n    body_length: 3.2\n    body_length_min: 3.05\n    body_length_max: 3.35\n    body_width: 1.6\n    body_width_min: 1.45\n    body_width_max: 1.75\n    terminator_spacing_min: 1.55\n    terminator_spacing_max: 2.32\n    size_info: '(Body size source: http://www.tortai-tech.com/upload/download/2011102023233369053.pdf)'\n\nSMD_1210:\n    code_imperial: \"1210\"\n    code_metric: \"3225\"\n    body_length: 3.2\n    body_length_min: 3.05\n    body_length_max: 3.35\n    body_width: 2.5\n    body_width_min: 2.34\n    body_width_max: 2.64\n    terminator_spacing_min: 1.55\n    terminator_spacing_max: 2.32\n    size_info: '(Body size source: http://www.tortai-tech.com/upload/download/2011102023233369053.pdf)'\n\nSMD_1806:\n    code_imperial: \"1806\"\n    code_metric: \"4516\"\n    body_length:\n      nominal: 4.5\n      tolerance: 0.2\n    body_width:\n      nominal: 1.6\n      tolerance: 0.2\n    terminal_length:\n      nominal: 0.7\n      tolerance: 0.3\n    size_info: '(Body size source: https://www.modelithics.com/models/Vendor/MuRata/BLM41P.pdf)'\n\nSMD_1812:\n    code_imperial: \"1812\"\n    code_metric: \"4532\"\n    body_length:\n        nominal: 4.5\n        tolerance: 0.2\n    body_width:\n        nominal: 3.2\n        tolerance: 0.2\n    terminal_length:\n        nominal: 0.5\n        tolerance: 0.2\n    size_info: '(Body size source: https://www.nikhef.nl/pub/departments/mt/projects/detectorR_D/dtddice/ERJ2G.pdf)'\n\nSMD_2010:\n    code_imperial: \"2010\"\n    code_metric: \"5025\"\n    body_length: 5.0\n    body_length_min: 4.85\n    body_length_max: 5.15\n    body_width: 2.5\n    body_width_min: 2.35\n    body_width_max: 2.65\n    terminator_spacing_min: 3.15\n    terminator_spacing_max: 3.92\n    size_info: '(Body size source: http://www.tortai-tech.com/upload/download/2011102023233369053.pdf)'\n\nSMD_2512:\n    code_imperial: \"2512\"\n    code_metric: \"6332\"\n    body_length: 6.3\n    body_length_min: 6.15\n    body_length_max: 6.45\n    body_width: 3.2\n    body_width_min: 3.05\n    body_width_max: 3.35\n    terminator_spacing_min: 4.45\n    terminator_spacing_max: 5.22\n    size_info: '(Body size source: http://www.tortai-tech.com/upload/download/2011102023233369053.pdf)'\n\nSMD_2816:\n    code_imperial: \"2816\"\n    code_metric: \"7142\"\n    body_length:\n        nominal: 7.1\n        tolerance: 0.254\n    body_width:\n        nominal: 4.2\n        tolerance: 0.254\n    terminal_length_min: 1.316\n    terminal_length_max: 2.744\n    size_info: '(Body size from: https://www.vishay.com/docs/30100/wsl.pdf)'\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/size_definitions/size_default_chip_devices_smaller_0402.yaml",
    "content": "SMD_01005:\n    code_imperial: \"01005\"\n    code_metric: \"0402\"\n    body_length:\n      nominal: 0.4\n      tolerance: 0.02\n    body_width:\n      nominal: 0.2\n      tolerance: 0.02\n    terminal_length:\n      nominal: 0.1\n      tolerance: 0.03\n    size_info: '(Body size source: http://www.vishay.com/docs/20056/crcw01005e3.pdf)'\n\nSMD_0201:\n   code_imperial: \"0201\"\n   code_metric: \"0603\"\n   body_length:\n      nominal: 0.6\n      tolerance: 0.05\n   body_width:\n      nominal: 0.3\n      tolerance: 0.05\n   terminal_length:\n      nominal: 0.15\n      tolerance: 0.05\n   size_info: '(Body size source: https://www.vishay.com/docs/20052/crcw0201e3.pdf)'\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/size_definitions/size_default_chip_devices_smaller_0603.yaml",
    "content": "SMD_0402:\n    code_imperial: \"0402\"\n    code_metric: \"1005\"\n    body_length:\n      nominal: 1.0\n      minimum: 1.0\n      maximum: 1.1\n    body_width:\n      nominal: 0.5\n      minimum: 0.48\n      maximum: 0.6\n    terminator_spacing_min: 0.4\n    terminator_spacing_max: 0.7\n    size_info: '(Body size source: http://www.tortai-tech.com/upload/download/2011102023233369053.pdf)'\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/size_definitions/size_diode.yaml",
    "content": "SMD_2114:\n    code_imperial: \"2114\"\n    code_metric: \"3652\"\n    body_length:\n      nominal: 5.2\n      tolerance: 0.1\n    body_width:\n      nominal: 3.6\n      tolerance: 0.1\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n      nominal: 1.15\n      tolerance: 0.1\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    size_info: '(Body size from: http://datasheets.avx.com/schottky.pdf)'\n\nSMD_3220:\n    code_imperial: \"3220\"\n    code_metric: \"8050\"\n    body_length:\n      nominal: 8.0\n      tolerance: 0.1\n    body_width:\n      nominal: 5.0\n      tolerance: 0.1\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n      nominal: 1.95\n      tolerance: 0.1\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    size_info: '(Body size from: http://datasheets.avx.com/schottky.pdf)'\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/size_definitions/size_fuse.yaml",
    "content": "SMD_2920:\n    code_imperial: \"2920\"\n    code_metric: \"7451\"\n    body_length_min: 6.73\n    body_length_max: 7.98\n    body_width_min: 4.8\n    body_width_max: 5.44\n    terminal_length_min: 0.5\n    terminal_length_max: 1.2\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    size_info: '(Body size from: http://www.megastar.com/products/fusetronic/polyswitch/PDF/smd2920.pdf)'\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/size_definitions/size_inductor.yaml",
    "content": "SMD_1008:\n  code_imperial: \"1008\"\n  code_metric: \"2520\"\n  body_length:\n    nominal: 2.5\n    tolerance: 0.2\n  body_width:\n    nominal: 2.0\n    tolerance: 0.2\n  terminal_length:\n    nominal: 0.6\n    tolerance: 0.25\n  ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n  size_info: '(Body size source: https://ecsxtal.com/store/pdf/ECS-MPI2520-SMD-POWER-INDUCTOR.pdf)'\n\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/size_definitions/size_resistor.yaml",
    "content": "SMD_4020:\n    code_imperial: \"4020\"\n    code_metric: \"10251\"\n    body_length:\n      nominal: 10.2\n      tolerance: [0.05, 0.2]\n    body_width:\n      nominal: 5.1\n      tolerance: [0.05, 0.2]\n    terminal_length:\n      nominal: 0.9\n      tolerance: 0.2\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    size_info: '(Body size source: http://datasheet.octopart.com/HVC0603T5004FET-Ohmite-datasheet-26699797.pdf)'\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/size_definitions/size_tantal.yaml",
    "content": "SMD_1608-08:\n    code_metric: '1608-08'\n    # size   | 1,6 x 0,8 x 0,8 mm\n    #code_letter: 'Kemet-—'\n    code_letter: 'AVX-J'\n    body_length: 1.6\n    body_length_tol: 0.2\n    body_width: 0.85\n    body_width_tol: 0.2\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length: 0.5\n    terminal_length_tol: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: https://www.vishay.com/docs/48064/_t58_vmn_pt0471_1601.pdf)'\n\nSMD_1608-10:\n    code_metric: '1608-10'\n    # size   | 1,6 x 0,85 x 1,05 mm\n    #code_letter: 'Kemet-—'\n    code_letter: 'AVX-L'\n    body_length: 1.6\n    body_length_tol: 0.2\n    body_width: 0.85\n    body_width_tol: 0.2\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length: 0.5\n    terminal_length_tol: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: https://www.vishay.com/docs/48064/_t58_vmn_pt0471_1601.pdf)'\n\nSMD_2012-12:\n    code_metric: '2012-12'\n    # size   | 2,05 x 1,35 x 1,2 mm\n    code_letter: 'Kemet-R'\n    #code_letter: 'AVX-R'\n    body_length:\n        nominal: 2.0\n        tolerance: 0.2\n    body_width:\n        nominal: 1.25\n        tolerance: 0.2\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 0.5\n        tolerance: 0.2\n    terminal_width:\n        nominal: 0.9\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: https://www.vishay.com/docs/40182/tmch.pdf)'\n\nSMD_2012-15:\n    code_metric: '2012-15'\n    # size   | 2,05 x 1,35 x 1,5 mm\n    #code_letter: 'Kemet-—'\n    code_letter: 'AVX-P'\n    body_length:\n        nominal: 2.0\n        tolerance: 0.2\n    body_width:\n        nominal: 1.25\n        tolerance: 0.2\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 0.5\n        tolerance: 0.2\n    terminal_width:\n        nominal: 0.9\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: https://www.vishay.com/docs/40182/tmch.pdf)'\n\nSMD_3216-10:\n    code_metric: '3216-10'\n    # size   | 3,2 x 1,6 x 1,0 mm\n    code_letter: 'Kemet-I'\n    #code_letter: 'AVX-K'\n    body_length:\n        nominal: 3.2\n        tolerance: 0.2\n    body_width:\n        nominal: 1.6\n        tolerance: 0.2\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 0.8\n        tolerance: [0.3, 0.2]\n    terminal_width:\n        nominal: 1.2\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_3216-12:\n    code_metric: '3216-12'\n    # size   | 3,2 x 1,6 x 1,2 mm\n    code_letter: 'Kemet-S'\n    #code_letter: 'AVX-S'\n    body_length:\n        nominal: 3.2\n        tolerance: 0.2\n    body_width:\n        nominal: 1.6\n        tolerance: 0.2\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 0.8\n        tolerance: [0.3, 0.2]\n    terminal_width:\n        nominal: 1.2\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_3216-18:\n    code_metric: '3216-18'\n    # size   | 3,2 x 1,6 x 1,8 mm\n    code_letter: 'Kemet-A'\n    #code_letter: 'AVX-A'\n    body_length:\n        nominal: 3.2\n        tolerance: 0.2\n    body_width:\n        nominal: 1.6\n        tolerance: 0.2\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 0.8\n        tolerance: [0.3, 0.2]\n    terminal_width:\n        nominal: 1.2\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_3528-12:\n    code_metric: '3528-12'\n    # size   | 3,5 x 2,8 x 1,2 mm\n    code_letter: 'Kemet-T'\n    #code_letter: 'AVX-T'\n    body_length:\n        nominal: 3.5\n        tolerance: 0.2\n    body_width:\n        nominal: 2.8\n        tolerance: 0.2\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 0.8\n        tolerance: [0.3, 0.1]\n    terminal_width:\n        nominal: 2.2\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_3528-15:\n    code_metric: '3528-15'\n    # size   | 3,5 x 2,8 x 1,5 mm\n    #code_letter: 'Kemet-—'\n    code_letter: 'AVX-H'\n    body_length:\n        nominal: 3.5\n        tolerance: 0.2\n    body_width:\n        nominal: 2.8\n        tolerance: 0.2\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 0.8\n        tolerance: [0.3, 0.1]\n    terminal_width:\n        nominal: 2.2\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_3528-21:\n    code_metric: '3528-21'\n    # size   | 3,5 x 2,8 x 2,1 mm\n    code_letter: 'Kemet-B'\n    #code_letter: 'AVX-B'\n    body_length:\n        nominal: 3.5\n        tolerance: 0.2\n    body_width:\n        nominal: 2.8\n        tolerance: 0.2\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 0.8\n        tolerance: [0.3, 0.1]\n    terminal_width:\n        nominal: 2.2\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_6032-15:\n    code_metric: '6032-15'\n    # size   | 6,0 x 3,2 x 1,5 mm\n    code_letter: 'Kemet-U'\n    #code_letter: 'AVX-W'\n    body_length:\n        nominal: 6.0\n        tolerance: 0.3\n    body_width:\n        nominal: 3.2\n        tolerance: 0.2\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.3\n    terminal_width:\n        nominal: 2.2\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_6032-20:\n    code_metric: '6032-20'\n    # size   | 6,0 x 3,2 x 2,0 mm\n    #code_letter: 'Kemet-—'\n    code_letter: 'AVX-F'\n    body_length:\n        nominal: 6.0\n        tolerance: 0.3\n    body_width:\n        nominal: 3.2\n        tolerance: 0.2\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.3\n    terminal_width:\n        nominal: 2.2\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_6032-28:\n    code_metric: '6032-28'\n    # size   | 6,0 x 3,2 x 2,8 mm\n    code_letter: 'Kemet-C'\n    #code_letter: 'AVX-C'\n    body_length:\n        nominal: 6.0\n        tolerance: 0.3\n    body_width:\n        nominal: 3.2\n        tolerance: 0.3\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.3\n    terminal_width:\n        nominal: 2.2\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_7132-20:\n    code_metric: '7132-20'\n    # size   | 7,1 x 3,2 x 2,0 mm\n    code_letter: 'AVX-U'\n    body_length:\n        nominal: 7.1\n        tolerance: 0.3\n    body_width:\n        nominal: 3.2\n        tolerance: 0.3\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.3\n    terminator_spacing:\n        nominal: 3.6\n        tolerance: 0.6\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://datasheets.avx.com/F72-F75.pdf)'\n\nSMD_7132-28:\n    code_metric: '7132-28'\n    # size   | 7,1 x 3,2 x 2,8 mm\n    code_letter: 'AVX-C'\n    body_length:\n        nominal: 7.1\n        tolerance: 0.3\n    body_width:\n        nominal: 3.2\n        tolerance: 0.3\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.3\n    terminator_spacing:\n        nominal: 3.6\n        tolerance: 0.6\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://datasheets.avx.com/F72-F75.pdf)'\n\nSMD_7260-15:\n    code_metric: '7260-15'\n    # size   | 7,2 x 6,0 x 1,5 mm\n    code_letter: 'AVX-R'\n    body_length:\n        nominal: 7.2\n        tolerance: 0.3\n    body_width:\n        nominal: 6.0\n        tolerance: 0.3\n    terminator_spacing:\n        nominal: 3.8\n        tolerance: 0.6\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.4\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://datasheets.avx.com/F72-F75.pdf)'\n\nSMD_7260-20:\n    code_metric: '7260-20'\n    # size   | 7,2 x 6,0 x 2,0 mm\n    code_letter: 'AVX-M'\n    body_length:\n        nominal: 7.2\n        tolerance: 0.3\n    body_width:\n        nominal: 6.0\n        tolerance: 0.3\n    terminator_spacing:\n        nominal: 3.8\n        tolerance: 0.6\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.4\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://datasheets.avx.com/F72-F75.pdf)'\n\nSMD_7260-28:\n    code_metric: '7260-28'\n    # size   | 7,2 x 6,0 x 2,8 mm\n    code_letter: 'AVX-M'\n    body_length:\n        nominal: 7.2\n        tolerance: 0.3\n    body_width:\n        nominal: 6.0\n        tolerance: 0.3\n    terminator_spacing:\n        nominal: 3.8\n        tolerance: 0.6\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.4\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://datasheets.avx.com/F72-F75.pdf)'\n\nSMD_7260-38:\n    code_metric: '7260-38'\n    # size   | 7,2 x 6,0 x 3,8 mm\n    code_letter: 'AVX-R'\n    body_length:\n        nominal: 7.2\n        tolerance: 0.3\n    body_width:\n        nominal: 6.0\n        tolerance: 0.3\n    terminator_spacing:\n        nominal: 3.8\n        tolerance: 0.6\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.4\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://datasheets.avx.com/F72-F75.pdf)'\n\nSMD_7343-15:\n    code_metric: '7343-15'\n    # size   | 7,3 x 4,3 x 1,5 mm\n    code_letter: 'Kemet-W'\n    #code_letter: 'AVX-X'\n    body_length:\n        nominal: 7.3\n        tolerance: 0.3\n    body_width:\n        nominal: 4.3\n        tolerance: 0.3\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.3\n    terminal_width_min: 2.3\n    terminal_width_max: 2.5\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_7343-20:\n    code_metric: '7343-20'\n    # size   | 7,3 x 4,3 x 2,0 mm\n    code_letter: 'Kemet-V'\n    #code_letter: 'AVX-Y'\n    body_length:\n        nominal: 7.3\n        tolerance: 0.3\n    body_width:\n        nominal: 4.3\n        tolerance: 0.3\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.3\n    terminal_width:\n        nominal: 2.4\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_7343-30:\n    code_metric: '7343-30'\n    # size   | 7,3 x 4,3 x 3,0 mm\n    #code_letter: 'Kemet-—'\n    code_letter: 'AVX-N'\n    body_length:\n        nominal: 7.3\n        tolerance: 0.3\n    body_width:\n        nominal: 4.3\n        tolerance: 0.3\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.3\n    terminal_width:\n        nominal: 2.4\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_7343-31:\n    code_metric: '7343-31'\n    # size   | 7,3 x 4,3 x 3,1 mm\n    code_letter: 'Kemet-D'\n    #code_letter: 'AVX-D'\n    body_length:\n        nominal: 7.3\n        tolerance: 0.3\n    body_width:\n        nominal: 4.3\n        tolerance: 0.3\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.3\n    terminal_width:\n        nominal: 2.4\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_7343-40:\n    code_metric: '7343-40'\n    # size   | 7,3 x 4,3 x 4,0 mm\n    code_letter: 'Kemet-Y'\n    #code_letter: 'AVX-—'\n    body_length:\n        nominal: 7.3\n        tolerance: 0.3\n    body_width:\n        nominal: 4.3\n        tolerance: 0.3\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.3\n    terminal_width:\n        nominal: 2.4\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_7343-43:\n    code_metric: '7343-43'\n    # size   | 7,3 x 4,3 x 4,3 mm\n    code_letter: 'Kemet-X'\n    #code_letter: 'AVX-E'\n    body_length:\n        nominal: 7.3\n        tolerance: 0.3\n    body_width:\n        nominal: 4.3\n        tolerance: 0.3\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.3\n    terminal_width:\n        nominal: 2.4\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_7360-38:\n    code_metric: '7360-38'\n    # size   | 7,3 x 6,0 x 3,8 mm\n    code_letter: 'Kemet-E'\n    #code_letter: 'AVX-—'\n    body_length:\n        nominal: 7.3\n        tolerance: 0.3\n    body_width:\n        nominal: 6.0\n        tolerance: 0.3\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 1.3\n        tolerance: 0.3\n    terminal_width:\n        nominal: 4.1\n        tolerance: 0.1\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://www.kemet.com/Lists/ProductCatalog/Attachments/253/KEM_TC101_STD.pdf)'\n\nSMD_7361-38:\n    code_metric: '7361-38'\n    # size   | 7,3 x 6,1 x 3,8 mm\n    #code_letter: 'Kemet-—'\n    code_letter: 'AVX-V'\n    body_length:\n        nominal: 7.3\n        tolerance: 0.2\n    body_width:\n        nominal: 6.1\n        tolerance: [0.1, 0.2]\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 1.3\n        tolerance: [0.2, 0.3]\n    terminal_width:\n        nominal: 3.1\n        tolerance: 0.2\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://datasheets.avx.com/NOS.pdf)'\n\nSMD_7361-438:\n    code_metric: '7361-438'\n    # size | 7,3 x 6,1 x 4,3 mm\n    #code_letter: 'Kemet-—'\n    code_letter: 'AVX-U'\n    body_length:\n        nominal: 7.3\n        tolerance: 0.2\n    body_width:\n        nominal: 6.1\n        tolerance: [0.1, 0.2]\n    #terminator_spacing_min:\n    #terminator_spacing_max:\n    terminal_length:\n        nominal: 1.3\n        tolerance: [0.2, 0.3]\n    terminal_width:\n        nominal: 3.1\n        tolerance: 0.2\n    ipc_reference: \"ipc_spec_tantalumn\"\n    size_info: '(Body size from: http://datasheets.avx.com/NOS.pdf)'\n"
  },
  {
    "path": "scripts/SMD_chip_package_rlc-etc/size_definitions/size_wide_body_chip_resistor.yaml",
    "content": "SMD_0612:\n    code_imperial: \"0612\"\n    code_metric: \"1632\"\n    body_length:\n      nominal: 1.6\n      tolerance: 0.2\n    body_width:\n      nominal: 3.2\n      tolerance: 0.2\n    terminal_length:\n      nominal: 0.4\n      tolerance: 0.15\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    size_info: '(Body size source: https://www.vishay.com/docs/20019/rcwe.pdf)'\n\nSMD_0815:\n    code_imperial: \"0815\"\n    code_metric: \"2038\"\n    body_length:\n        nominal: 2.15\n        tolerance: 0.2\n    body_width:\n        nominal: 3.75\n        tolerance: 0.25\n    terminal_length:\n        nominal: 0.7\n        tolerance: 0.25\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    size_info: '(Body size source: http://www.yageo.com/documents/recent/PYu-PRPFPH_521_RoHS_L_0.pdf)'\n\nSMD_1020:\n    code_imperial: \"1020\"\n    code_metric: \"2550\"\n    body_length:\n      nominal: 2.5\n      tolerance: 0.2\n    body_width:\n      nominal: 5.0\n      tolerance: 0.2\n    terminal_length:\n      nominal: 0.55\n      tolerance: 0.15\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    size_info: '(Body size source: https://www.vishay.com/docs/20019/rcwe.pdf)'\n\nSMD_1218:\n    code_imperial: \"1218\"\n    code_metric: \"3246\"\n    body_length:\n        nominal: 3.2\n        tolerance: [0.2, 0.1]\n    body_width:\n        nominal: 4.6\n        tolerance: 0.15\n    terminal_length:\n        nominal: 0.45\n        tolerance: 0.2\n    ipc_reference: \"ipc_spec_larger_or_equal_0603\"\n    size_info: '(Body size source: https://www.vishay.com/docs/20035/dcrcwe3.pdf)'\n"
  },
  {
    "path": "scripts/Shielding/laird_technologies_smd_shielding.kicad_mod.yaml",
    "content": "# page 9\nLaird_Technologies_BMI-S-101_13.66x12.70mm:\n    description: \"Laird Technologies BMI-S-101 Shielding Cabinet One Piece SMD 13.66x12.70mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 12.70\n    y_part_size: 13.66\n    x_pad_spacer: [1.9, 4.1, 6.75]\n    y_pad_spacer: [1.9, 4.1, 7.23]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\nLaird_Technologies_BMI-S-201-F_13.66x12.70mm:\n    description: \"Laird Technologies BMI-S-201-F Shielding Cabinet Two Piece SMD 13.66x12.70mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 12.70\n    y_part_size: 13.66\n    x_pad_spacer: [1.9, 4.1, 6.75]\n    y_pad_spacer: [1.9, 4.1, 7.23]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\n# page 10\nLaird_Technologies_BMI-S-102_16.50x16.50mm:\n    description: \"Laird Technologies BMI-S-102 Shielding Cabinet One Piece SMD 16.50x16.50mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 16.50\n    y_part_size: 16.50\n    x_pad_spacer: [1.9, 4.1, 8.65]\n    y_pad_spacer: [1.9, 4.1, 8.65]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\nLaird_Technologies_BMI-S-202-F_16.50x16.50mm:\n    description: \"Laird Technologies BMI-S-202-F Shielding Cabinet Two Piece SMD 16.50x16.50mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 16.50\n    y_part_size: 16.50\n    x_pad_spacer: [1.9, 4.1, 8.65]\n    y_pad_spacer: [1.9, 4.1, 8.65]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\n# page 11\nLaird_Technologies_BMI-S-103_26.21x26.21mm:\n    description: \"Laird Technologies BMI-S-103 Shielding Cabinet One Piece SMD 26.21x26.21mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 26.21\n    y_part_size: 26.21\n    x_pad_spacer: [1.735, 3.935, 7.735, 9.935, 13.505]\n    y_pad_spacer: [1.735, 3.935, 7.735, 9.935, 13.505]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\nLaird_Technologies_BMI-S-203-F_26.21x26.21mm:\n    description: \"Laird Technologies BMI-S-203-F Shielding Cabinet Two Piece SMD 26.21x26.21mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 26.21\n    y_part_size: 26.21\n    x_pad_spacer: [1.735, 3.935, 7.735, 9.935, 13.505]\n    y_pad_spacer: [1.735, 3.935, 7.735, 9.935, 13.505]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\n# page 12\nLaird_Technologies_BMI-S-104_32.00x32.00mm:\n    description: \"Laird Technologies BMI-S-104 Shielding Cabinet One Piece SMD 32.00x32.00mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 32.00\n    y_part_size: 32.00\n    x_pad_spacer: [1.1, 4.9, 7.1, 10.9, 13.1, 16.4]\n    y_pad_spacer: [1.1, 4.9, 7.1, 10.9, 13.1, 16.4]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\nLaird_Technologies_BMI-S-204-F_32.00x32.00mm:\n    description: \"Laird Technologies BMI-S-204-F Shielding Cabinet Two Piece SMD 32.00x32.00mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 32.00\n    y_part_size: 32.00\n    x_pad_spacer: [1.1, 4.9, 7.1, 10.9, 13.1, 16.4]\n    y_pad_spacer: [1.1, 4.9, 7.1, 10.9, 13.1, 16.4]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\n# page 13\nLaird_Technologies_BMI-S-105_38.10x25.40mm:\n    description: \"Laird Technologies BMI-S-105 Shielding Cabinet One Piece SMD 38.10x25.40mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 38.10\n    y_part_size: 25.40\n    x_pad_spacer: [1.65, 4.35, 7.65, 10.35, 13.65, 16.35, 19.45] # used: 3.3 - 2.7 - 3.3 - ...\n    y_pad_spacer: [1.65, 4.35, 7.65, 10.35, 13.1] # used: 3.3 - 2.7 -3.3\n    x_pad_mirror: True\n    y_pad_mirror: True\n\nLaird_Technologies_BMI-S-205-F_38.10x25.40mm:\n    description: \"Laird Technologies BMI-S-205-F Shielding Cabinet Two Piece SMD 38.10x25.40mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 38.10\n    y_part_size: 25.40\n    x_pad_spacer: [1.65, 4.35, 7.65, 10.35, 13.65, 16.35, 19.45] # used: 3.3 - 2.7 - 3.3 - ...\n    y_pad_spacer: [1.65, 4.35, 7.65, 10.35, 13.1] # used: 3.3 - 2.7 -3.3\n    x_pad_mirror: True\n    y_pad_mirror: True\n\n# page 14\nLaird_Technologies_BMI-S-106_36.83x33.68mm:\n    description: \"Laird Technologies BMI-S-106 Shielding Cabinet One Piece SMD 36.83x33.68mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 36.83\n    y_part_size: 33.68\n    x_pad_spacer: [1.1, 4.9, 7.1, 10.9, 13.1, 18.82] # footprint is 0.1mm wider than on datasheet\n    y_pad_spacer: [1.1, 4.9, 7.1, 10.9, 13.1, 17.24]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\nLaird_Technologies_BMI-S-206-F_36.83x33.68mm:\n    description: \"Laird Technologies BMI-S-206-F Shielding Cabinet Two Piece SMD 36.83x33.68mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 36.83\n    y_part_size: 33.68\n    x_pad_spacer: [1.1, 4.9, 7.1, 10.9, 13.1, 18.82] # footprint is 0.1mm wider than on datasheet\n    y_pad_spacer: [1.1, 4.9, 7.1, 10.9, 13.1, 17.24]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\n# page 15\nLaird_Technologies_BMI-S-107_44.37x44.37mm:\n    description: \"Laird Technologies BMI-S-107 Shielding Cabinet One Piece SMD 44.37x44.37mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 44.37\n    y_part_size: 44.37 # 2.3 3.8 2.2 3.8 2.2 3.8 2.2\n    x_pad_spacer: [1.15, 4.95, 7.15, 10.95, 13.15, 16.95, 19.15, 22.59] # footprint is 0.1mm wider than on datasheet and centered\n    y_pad_spacer: [1.15, 4.95, 7.15, 10.95, 13.15, 16.95, 19.15, 22.59] # footprint is 0.1mm wider than on datasheet and centered\n    x_pad_mirror: True\n    y_pad_mirror: True\n\nLaird_Technologies_BMI-S-207-F_44.37x44.37mm:\n    description: \"Laird Technologies BMI-S-207-F Shielding Cabinet Two Piece SMD 44.37x44.37mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 44.37\n    y_part_size: 44.37\n    x_pad_spacer: [1.15, 4.95, 7.15, 10.95, 13.15, 16.95, 19.15, 22.59] # footprint is 0.1mm wider than on datasheet and centered\n    y_pad_spacer: [1.15, 4.95, 7.15, 10.95, 13.15, 16.95, 19.15, 22.59] # footprint is 0.1mm wider than on datasheet and centered\n    x_pad_mirror: True\n    y_pad_mirror: True\n\n# page 16\nLaird_Technologies_BMI-S-208-F_39.60x39.60mm:\n    description: \"Laird Technologies BMI-S-208-F Shielding Cabinet Two Piece SMD 39.60x39.60mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 39.6\n    y_part_size: 39.6\n    x_pad_spacer: [1.9, 4.1, 7.9, 10.1, 13.9, 16.1, 20.2]\n    y_pad_spacer: [1.9, 4.1, 7.9, 10.1, 13.9, 16.1, 20.2]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\nLaird_Technologies_BMI-S-209-F_29.36x18.50mm:\n    description: \"Laird Technologies BMI-S-209-F Shielding Cabinet Two Piece SMD 29.36x18.50mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 29.36\n    y_part_size: 18.50\n    x_pad_spacer: [1.9, 4.1, 7.9, 10.1, 15.08]\n    y_pad_spacer: [1.9, 4.1, 9.65]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\n# page 17\nLaird_Technologies_BMI-S-210-F_44.00x30.50mm:\n    description: \"Laird Technologies BMI-S-210-F Shielding Cabinet Two Piece SMD 44.00x30.50mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 44.0\n    y_part_size: 30.5\n    x_pad_spacer: [1.1, 4.9, 7.1, 10.9, 13.1, 16.9, 19.1, 22.4]\n    y_pad_spacer: [1.1, 4.9, 7.1, 10.9, 13.1, 15.65]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\nLaird_Technologies_BMI-S-230-F_50.8x38.1mm:\n    description: \"Laird Technologies BMI-S-230-F Shielding Cabinet Two Piece SMD 50.8x38.1mm\"\n    datasheet: \"https://media.digikey.com/pdf/Data%20Sheets/Laird%20Technologies/BMI-S-230-F_Dwg.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 50.8\n    y_part_size: 38.1\n    x_pad_spacer: [1.9, 4.1, 7.9, 10.1, 13.9, 16.1, 19.9, 22.1, 25.8]\n    y_pad_spacer: [1.9, 4.1, 7.9, 10.1, 13.9, 16.1, 19.45]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\n# page 19\nLaird_Technologies_97-2002_25.40x25.40mm:\n    description: \"Laird Technologies 97-2002 EZ PEEL Shielding Cabinet One Piece SMD 25.40x25.40mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 0.38 # TODO: add solder mask?\n    x_part_size: 25.40\n    y_part_size: 25.40\n    x_pad_spacer: [12.825]\n    y_pad_spacer: [12.825]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\nLaird_Technologies_97-2003_12.70x13.37mm:\n    description: \"Laird Technologies 97-2003 EZ PEEL Shielding Cabinet One Piece SMD 12.70x13.37mm\"\n    datasheet: \"http://cdn.lairdtech.com/home/brandworld/files/Board%20Level%20Shields%20Catalog%20Download.pdf\"\n    courtjard: 0.25\n    pads_width: 0.38 # TODO: add solder mask?\n    x_part_size: 12.70\n    y_part_size: 13.37\n    x_pad_spacer: [6.475]\n    y_pad_spacer: [6.96]\n    x_pad_mirror: True\n    y_pad_mirror: True\n\n# TODO: 97-2004\n# TODO: 97-2005\n"
  },
  {
    "path": "scripts/Shielding/smd_shielding.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport argparse\nimport yaml\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load parent path of KicadModTree\n\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\n\n\n# https://stackoverflow.com/questions/4265546/python-round-to-nearest-05\ndef round_to(n, precision):\n    correction = 0.5 if n >= 0 else -0.5\n    return int(n/precision+correction) * precision\n\n\ndef calculate_pad_spacer(pad_spacer, mirror_spacer):\n    pad_spacer_pos = []\n\n    if mirror_spacer:\n        for spacer in reversed(pad_spacer):\n            pad_spacer_pos.append(spacer * -1)\n\n    pad_spacer_pos += pad_spacer\n\n    return pad_spacer_pos\n\n\ndef create_smd_shielding(name, **kwargs):\n    kicad_mod = Footprint(name)\n\n    # init kicad footprint\n    kicad_mod.setDescription(kwargs['description'])\n    kicad_mod.setTags('Shielding Cabinet')\n    kicad_mod.setAttribute('smd')\n    kicad_mod.append(Model(filename=\"${KISYS3DMOD}/RF_Shielding.3dshapes/\" + name + \".wrl\"))\n\n    # do some pre calculations\n    # TODO: when mirror=False, array has to have even number of array elements\n    x_pad_positions = calculate_pad_spacer(kwargs['x_pad_spacer'], kwargs.get('x_pad_mirror', True))\n    y_pad_positions = calculate_pad_spacer(kwargs['y_pad_spacer'], kwargs.get('y_pad_mirror', True))\n\n    x_pad_min = min(x_pad_positions)\n    x_pad_max = max(x_pad_positions)\n    y_pad_min = min(y_pad_positions)\n    y_pad_max = max(y_pad_positions)\n\n    x_pad_min_center = x_pad_min + kwargs['pads_width']/2.\n    x_pad_max_center = x_pad_max - kwargs['pads_width']/2.\n    y_pad_min_center = y_pad_min + kwargs['pads_width']/2.\n    y_pad_max_center = y_pad_max - kwargs['pads_width']/2.\n\n    x_part_min = -kwargs['x_part_size'] / 2.\n    x_part_max = kwargs['x_part_size'] / 2.\n    y_part_min = -kwargs['y_part_size'] / 2.\n    y_part_max = kwargs['y_part_size'] / 2.\n\n    # set general values\n    kicad_mod.append(Text(type='reference', text='REF**', at=[0, y_pad_min - kwargs['courtjard'] - 0.75], layer='F.SilkS'))\n    kicad_mod.append(Text(type='value', text=name, at=[0, y_pad_max + kwargs['courtjard'] + 0.75], layer='F.Fab'))\n    kicad_mod.append(Text(type='user', text='%R', at=[0, 0], layer='F.Fab'))\n\n    # create courtyard\n    x_courtjard_min = round_to(x_pad_min - kwargs['courtjard'], 0.05)\n    x_courtjard_max = round_to(x_pad_max + kwargs['courtjard'], 0.05)\n    y_courtjard_min = round_to(y_pad_min - kwargs['courtjard'], 0.05)\n    y_courtjard_max = round_to(y_pad_max + kwargs['courtjard'], 0.05)\n\n    kicad_mod.append(RectLine(start=[x_courtjard_min, y_courtjard_min],\n                              end=[x_courtjard_max, y_courtjard_max],\n                              layer='F.CrtYd'))\n\n    # create inner courtyard\n    pad_width = kwargs['pads_width']\n    x_courtjard_min = round_to(x_pad_min + pad_width + kwargs['courtjard'], 0.05)\n    x_courtjard_max = round_to(x_pad_max - pad_width - kwargs['courtjard'], 0.05)\n    y_courtjard_min = round_to(y_pad_min + pad_width + kwargs['courtjard'], 0.05)\n    y_courtjard_max = round_to(y_pad_max - pad_width - kwargs['courtjard'], 0.05)\n    kicad_mod.append(RectLine(start=[x_courtjard_min, y_courtjard_min],\n                              end=[x_courtjard_max, y_courtjard_max],\n                              layer='F.CrtYd'))\n\n    # create Fabriaction Layer\n    kicad_mod.append(RectLine(start=[x_part_min, y_part_min],\n                              end=[x_part_max, y_part_max],\n                              layer='F.Fab'))\n\n    # all pads have this kwargs, so we only write them one\n    general_kwargs = {'number': 1,\n                      'type': Pad.TYPE_SMT,\n                      'shape': Pad.SHAPE_RECT,\n                      'layers': ['F.Cu', 'F.Mask', 'F.Paste']}\n\n    # create edge pads\n    kicad_mod.append(Pad(at=[x_pad_min_center, y_pad_min_center],\n                         size=[kwargs['pads_width'], kwargs['pads_width']], **general_kwargs))\n    kicad_mod.append(Pad(at=[x_pad_max_center, y_pad_min_center],\n                         size=[kwargs['pads_width'], kwargs['pads_width']], **general_kwargs))\n    kicad_mod.append(Pad(at=[x_pad_max_center, y_pad_max_center],\n                         size=[kwargs['pads_width'], kwargs['pads_width']], **general_kwargs))\n    kicad_mod.append(Pad(at=[x_pad_min_center, y_pad_max_center],\n                         size=[kwargs['pads_width'], kwargs['pads_width']], **general_kwargs))\n\n    # iterate pairwise over pads\n    for pad_start, pad_end in zip(x_pad_positions[0::2], x_pad_positions[1::2]):\n        if pad_start == x_pad_min:\n            pad_start += kwargs['pads_width']\n        if pad_end == x_pad_max:\n            pad_end -= kwargs['pads_width']\n\n        kicad_mod.append(Pad(at=[(pad_start+pad_end)/2., y_pad_min_center],\n                         size=[abs(pad_start-pad_end), kwargs['pads_width']], **general_kwargs))\n        kicad_mod.append(Pad(at=[(pad_start+pad_end)/2., y_pad_max_center],\n                         size=[abs(pad_start-pad_end), kwargs['pads_width']], **general_kwargs))\n\n    for pad_start, pad_end in zip(y_pad_positions[0::2], y_pad_positions[1::2]):\n        if pad_start == y_pad_min:\n            pad_start += kwargs['pads_width']\n        if pad_end == y_pad_max:\n            pad_end -= kwargs['pads_width']\n\n        kicad_mod.append(Pad(at=[x_pad_min_center, (pad_start+pad_end)/2.],\n                         size=[kwargs['pads_width'], abs(pad_start-pad_end)], **general_kwargs))\n        kicad_mod.append(Pad(at=[x_pad_max_center, (pad_start+pad_end)/2.],\n                         size=[kwargs['pads_width'], abs(pad_start-pad_end)], **general_kwargs))\n\n    # iterate pairwise over pads for silk screen\n    for pad_start, pad_end in zip(x_pad_positions[1::2], x_pad_positions[2::2]):\n        pad_start += 0.3\n        pad_end -= 0.3\n\n        kicad_mod.append(Line(start=[pad_start, y_part_min - 0.15],\n                                  end=[pad_end, y_part_min - 0.15], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[pad_start, y_part_max + 0.15],\n                                  end=[pad_end, y_part_max + 0.15], layer='F.SilkS'))\n\n    for pad_start, pad_end in zip(y_pad_positions[1::2], y_pad_positions[2::2]):\n        pad_start += 0.3\n        pad_end -= 0.3\n\n        # check if line has relevant length\n        if pad_end - pad_start < 0.5:\n            continue\n\n        kicad_mod.append(Line(start=[x_part_min - 0.15, pad_start],\n                                  end=[x_part_min - 0.15, pad_end], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[x_part_max + 0.15, pad_start],\n                                  end=[x_part_max + 0.15, pad_end], layer='F.SilkS'))\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('{name}.kicad_mod'.format(name=name))\n\n\ndef parse_and_execute_yml_file(filepath):\n    with open(filepath, 'r') as stream:\n        try:\n            yaml_parsed = yaml.safe_load(stream)\n            for footprint in yaml_parsed:\n                print(\"generate {name}.kicad_mod\".format(name=footprint))\n                create_smd_shielding(footprint, **yaml_parsed.get(footprint))\n        except yaml.YAMLError as exc:\n            print(exc)\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='Parse *.kicad_mod.yml file(s) and create matching footprints')\n    parser.add_argument('files', metavar='file', type=str, nargs='+',\n                        help='yml-files to parse')\n    #parser.add_argument('-v', '--verbose', help='show more information when creating footprint', action='store_true')\n    # TODO: allow writing into sub file\n    args = parser.parse_args()\n    for filepath in args.files:\n        parse_and_execute_yml_file(filepath)\n"
  },
  {
    "path": "scripts/Shielding/wuerth_electronic_smd_shielding.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load parent path of  KicadModTree\n\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\n\n\ndef create_shielding(name, outer_size, size,\n                     attachment_width, attachment_length, attachment_positions, outer_attachment_length):\n\n    kicad_mod = Footprint(name)\n\n    # init kicad footprint\n    kicad_mod.setDescription('WE-SHC Shielding Cabinet SMD {size}x{size}mm'.format(size=size))\n    kicad_mod.setTags('Shielding Cabinet')\n    kicad_mod.setAttribute('smd')\n\n    # set general values\n    kicad_mod.append(Text(type='reference', text='REF**', at=[0, -outer_size / 2. - 1], layer='F.SilkS'))\n    kicad_mod.append(Text(type='value', text=name, at=[0, outer_size / 2. + 1], layer='F.Fab'))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-outer_size / 2. - 0.25, -outer_size / 2. - 0.25],\n                              end=[outer_size / 2. + 0.25, outer_size / 2. + 0.25],\n                              layer='F.CrtYd'))\n\n    # create Fabriaction Layer\n    kicad_mod.append(RectLine(start=[-size / 2., -size / 2.],\n                              end=[size / 2., size / 2.],\n                              layer='F.Fab'))\n\n    outer_pointing_pos = outer_size / 2. - attachment_width / 2.\n\n    general_kwargs = {'number': 1,\n                      'type': Pad.TYPE_SMT,\n                      'shape': Pad.SHAPE_RECT,\n                      'layers': ['F.Cu', 'F.Mask']}\n\n    vertical_kwargs = {'number': 1,\n                       'type': Pad.TYPE_SMT,\n                       'shape': Pad.SHAPE_RECT,\n                       'size': [attachment_width, attachment_length],\n                       'layers': ['F.Cu', 'F.Mask']}\n\n    horizontal_kwargs = {'number': 1,\n                         'type': Pad.TYPE_SMT,\n                         'shape': Pad.SHAPE_RECT,\n                         'size': [attachment_length, attachment_width],\n                         'layers': ['F.Cu', 'F.Mask']}\n\n    # create inner pads\n    for position in attachment_positions:\n        kicad_mod.append(Pad(at=[outer_pointing_pos, position / 2.], **vertical_kwargs))\n        kicad_mod.append(Pad(at=[outer_pointing_pos, -position / 2.], **vertical_kwargs))\n        kicad_mod.append(Pad(at=[-outer_pointing_pos, position / 2.], **vertical_kwargs))\n        kicad_mod.append(Pad(at=[-outer_pointing_pos, -position / 2.], **vertical_kwargs))\n\n        kicad_mod.append(Pad(at=[position / 2., outer_pointing_pos], **horizontal_kwargs))\n        kicad_mod.append(Pad(at=[position / 2., -outer_pointing_pos], **horizontal_kwargs))\n        kicad_mod.append(Pad(at=[-position / 2., outer_pointing_pos], **horizontal_kwargs))\n        kicad_mod.append(Pad(at=[-position / 2., -outer_pointing_pos], **horizontal_kwargs))\n\n    # create edge pads\n    kicad_mod.append(Pad(at=[outer_pointing_pos, outer_pointing_pos],\n                         size=[attachment_width, attachment_width], **general_kwargs))\n    kicad_mod.append(Pad(at=[outer_pointing_pos, -outer_pointing_pos],\n                         size=[attachment_width, attachment_width], **general_kwargs))\n    kicad_mod.append(Pad(at=[-outer_pointing_pos, outer_pointing_pos],\n                         size=[attachment_width, attachment_width], **general_kwargs))\n    kicad_mod.append(Pad(at=[-outer_pointing_pos, -outer_pointing_pos],\n                         size=[attachment_width, attachment_width], **general_kwargs))\n\n    inner_edge_pos = outer_size / 2 - attachment_width - (outer_attachment_length - attachment_width) / 2.\n    inner_edge_length = outer_attachment_length-attachment_width\n\n    kicad_mod.append(Pad(at=[inner_edge_pos, outer_pointing_pos],\n                         size=[inner_edge_length, attachment_width], **general_kwargs))\n    kicad_mod.append(Pad(at=[inner_edge_pos, -outer_pointing_pos],\n                         size=[inner_edge_length, attachment_width], **general_kwargs))\n    kicad_mod.append(Pad(at=[-inner_edge_pos, outer_pointing_pos],\n                         size=[inner_edge_length, attachment_width], **general_kwargs))\n    kicad_mod.append(Pad(at=[-inner_edge_pos, -outer_pointing_pos],\n                         size=[inner_edge_length, attachment_width], **general_kwargs))\n\n    kicad_mod.append(Pad(at=[outer_pointing_pos, inner_edge_pos],\n                         size=[attachment_width, inner_edge_length], **general_kwargs))\n    kicad_mod.append(Pad(at=[outer_pointing_pos, -inner_edge_pos],\n                         size=[attachment_width, inner_edge_length], **general_kwargs))\n    kicad_mod.append(Pad(at=[-outer_pointing_pos, inner_edge_pos],\n                         size=[attachment_width, inner_edge_length], **general_kwargs))\n    kicad_mod.append(Pad(at=[-outer_pointing_pos, -inner_edge_pos],\n                         size=[attachment_width, inner_edge_length], **general_kwargs))\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('{name}.kicad_mod'.format(name=name))\n\n\nif __name__ == '__main__':\n    # http://katalog.we-online.com/pbs/datasheet/36103205.pdf\n    create_shielding('Würth_36103205_20x20mm', 21.5, 20, 1, 2.6, [7.5], 3.3)\n\n    # http://katalog.we-online.com/pbs/datasheet/36103255.pdf\n    create_shielding('Würth_36103255_25x25mm', 26.5, 25, 1, 2.6, [5.1, 12.5], 3.3)\n\n    # http://katalog.we-online.com/pbs/datasheet/36103305.pdf\n    create_shielding('Würth_36103305_30x30mm', 31.5, 30, 1, 2.6, [7.5, 17.5], 3.3)\n\n    # http://katalog.we-online.com/pbs/datasheet/36103505.pdf\n    create_shielding('Würth_36103505_50x50mm', 51.5, 50, 1, 2.6, [7.5, 17.5, 27.5, 37.5], 3.3)\n\n    # http://katalog.we-online.com/pbs/datasheet/36103605.pdf\n    create_shielding('Würth_36103605_60x60mm', 61.5, 60, 1, 2.6, [7.5, 17.5, 27.5, 37.5, 47.5], 3.5)\n"
  },
  {
    "path": "scripts/Shielding/wuerth_electronic_tht_shielding.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load parent path of  KicadModTree\n\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\n\n\ndef create_shielding(name, outer_size, size,\n                     attachment_drill, attachment_diameter, attachment_positions):\n\n    attachment_positions = sorted(attachment_positions)\n\n    kicad_mod = Footprint(name)\n\n    # init kicad footprint\n    kicad_mod.setDescription('WE-SHC Shielding Cabinet THT {size}x{size}mm'.format(size=size))\n    kicad_mod.setTags('Shielding Cabinet')\n\n    courtjard_size = outer_size / 2. + attachment_diameter / 2. + 0.25\n\n    # set general values\n    kicad_mod.append(Text(type='reference', text='REF**', at=[0, -courtjard_size - 1], layer='F.SilkS'))\n    kicad_mod.append(Text(type='value', text=name, at=[0, courtjard_size + 1], layer='F.Fab'))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-courtjard_size, -courtjard_size],\n                              end=[courtjard_size, courtjard_size],\n                              layer='F.CrtYd'))\n\n    # create Fabriaction Layer\n    kicad_mod.append(RectLine(start=[-size / 2., -size / 2.],\n                              end=[size / 2., size / 2.],\n                              layer='F.Fab'))\n\n    general_kwargs = {'number': 1,\n                      'type': Pad.TYPE_THT,\n                      'shape': Pad.SHAPE_CIRCLE,\n                      'size': [attachment_diameter, attachment_diameter],\n                      'drill': attachment_drill,\n                      'layers': ['*.Cu', '*.Mask']}\n\n    # create pads\n    for position in attachment_positions:\n        kicad_mod.append(Pad(at=[outer_size / 2., position / 2.], **general_kwargs))\n        kicad_mod.append(Pad(at=[-outer_size / 2., position / 2.], **general_kwargs))\n        kicad_mod.append(Pad(at=[position / 2., outer_size / 2.], **general_kwargs))\n        kicad_mod.append(Pad(at=[position / 2., -outer_size / 2.], **general_kwargs))\n\n        if position != 0. or 2*outer_size == 2*position:\n            kicad_mod.append(Pad(at=[outer_size / 2., -position / 2.], **general_kwargs))\n            kicad_mod.append(Pad(at=[-outer_size / 2., -position / 2.], **general_kwargs))\n            kicad_mod.append(Pad(at=[-position / 2., outer_size / 2.], **general_kwargs))\n            kicad_mod.append(Pad(at=[-position / 2., -outer_size / 2.], **general_kwargs))\n\n    # create silk screen\n    silk_padding = 0.2\n    silk_outline = size / 2. + silk_padding\n\n    pad_padding = 0.4\n\n    if attachment_positions[0] != 0.:\n        line_end = attachment_positions[0] / 2. - attachment_diameter / 2. - pad_padding\n        kicad_mod.append(Line(start=[silk_outline, line_end], end=[silk_outline, -line_end], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[-silk_outline, -line_end], end=[-silk_outline, line_end], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[line_end, silk_outline], end=[-line_end, silk_outline], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[line_end, -silk_outline], end=[-line_end, -silk_outline], layer='F.SilkS'))\n\n    for begin, end in zip(attachment_positions, attachment_positions[1:]):\n        line_begin = begin / 2. + attachment_diameter / 2. + pad_padding\n        line_end = end / 2. - attachment_diameter / 2. - pad_padding\n        kicad_mod.append(Line(start=[silk_outline, line_begin], end=[silk_outline, line_end], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[silk_outline, -line_begin], end=[silk_outline, -line_end], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[-silk_outline, line_begin], end=[-silk_outline, line_end], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[-silk_outline, -line_begin], end=[-silk_outline, -line_end], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[line_begin, silk_outline], end=[line_end, silk_outline], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[line_begin, -silk_outline], end=[line_end, -silk_outline], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[-line_begin, silk_outline], end=[-line_end, silk_outline], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[-line_begin, -silk_outline], end=[-line_end, -silk_outline], layer='F.SilkS'))\n\n    if attachment_positions[-1] != outer_size:\n        line_begin = attachment_positions[-1] / 2. + attachment_diameter / 2. + pad_padding\n        line_end = outer_size / 2. + silk_padding\n        kicad_mod.append(Line(start=[silk_outline, line_begin], end=[silk_outline, line_end], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[silk_outline, -line_begin], end=[silk_outline, -line_end], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[-silk_outline, line_begin], end=[-silk_outline, line_end], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[-silk_outline, -line_begin], end=[-silk_outline, -line_end], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[line_begin, silk_outline], end=[line_end, silk_outline], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[line_begin, -silk_outline], end=[line_end, -silk_outline], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[-line_begin, silk_outline], end=[-line_end, silk_outline], layer='F.SilkS'))\n        kicad_mod.append(Line(start=[-line_begin, -silk_outline], end=[-line_end, -silk_outline], layer='F.SilkS'))\n\n    # fix KLC issue 6.3\n    # kicad_mod.insert(Translation(outer_size / 2., attachment_positions[-1] / 2.))\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('{name}.kicad_mod'.format(name=name))\n\n\nif __name__ == '__main__':\n    # http://katalog.we-online.de/pbs/datasheet/36503205.pdf\n    create_shielding('Würth_36503205_20x20mm', 20.5, 20.5, 1.1, 1.7, [5.08, 15.24])\n\n    # http://katalog.we-online.de/pbs/datasheet/36503255.pdf\n    create_shielding('Würth_36503255_25x25mm', 25.5, 25.5, 1.1, 1.7, [0, 10.16, 20.32])\n\n    # http://katalog.we-online.de/pbs/datasheet/36503305.pdf\n    create_shielding('Würth_36503305_30x30mm', 30.5, 30.5, 1.1, 1.7, [5.08, 15.24, 25.40])\n\n    # http://katalog.we-online.de/pbs/datasheet/36503505.pdf\n    create_shielding('Würth_36503505_50x50mm', 50.5, 50.5, 1.1, 1.7, [5.08, 15.24, 25.40, 35.56, 45.72])\n\n    # http://katalog.we-online.de/pbs/datasheet/36503605.pdf\n    create_shielding('Würth_36503605_60x60mm', 60.5, 60.5, 1.1, 1.7, [5.08, 15.24, 25.40, 35.56, 45.72, 55.88])\n"
  },
  {
    "path": "scripts/Shielding/wuerth_smd_shielding.kicad_mod.yaml",
    "content": "Würth_36103205_20x20mm:\n    description: \"WE-SHC Shielding Cabinet SMD 20x20mm\"\n    datasheet: \"http://katalog.we-online.com/pbs/datasheet/36103205.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 20\n    y_part_size: 20\n    x_pad_spacer: [2.45, 5.05, 7.45, 10.75]\n    y_pad_spacer: [2.45, 5.05, 7.45, 10.75]\n    x_pad_mirror: True\n    y_pad_mirror: True\nWürth_36103255_25x25mm:\n    description: \"WE-SHC Shielding Cabinet SMD 25x25mm\"\n    datasheet: \"http://katalog.we-online.com/pbs/datasheet/36103255.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 25\n    y_part_size: 25\n    x_pad_spacer: [2.55, 4.95, 7.55, 9.95, 13.25]\n    y_pad_spacer: [2.55, 4.95, 7.55, 9.95, 13.25]\n    x_pad_mirror: True\n    y_pad_mirror: True\nWürth_36103305_30x30mm:\n    description: \"WE-SHC Shielding Cabinet SMD 30x30mm\"\n    datasheet: \"http://katalog.we-online.com/pbs/datasheet/36103305.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 30\n    y_part_size: 30\n    x_pad_spacer: [2.45, 5.05, 7.45, 10.05, 12.45, 15.75]\n    y_pad_spacer: [2.45, 5.05, 7.45, 10.05, 12.45, 15.75]\n    x_pad_mirror: True\n    y_pad_mirror: True\nWürth_36103505_50x50mm:\n    description: \"WE-SHC Shielding Cabinet SMD 50x50mm\"\n    datasheet: \"http://katalog.we-online.com/pbs/datasheet/36103505.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 50\n    y_part_size: 50\n    x_pad_spacer: [2.45, 5.05, 7.45, 10.05, 12.45, 15.05, 17.45, 20.05, 22.45, 25.75]\n    y_pad_spacer: [2.45, 5.05, 7.45, 10.05, 12.45, 15.05, 17.45, 20.05, 22.45, 25.75]\n    x_pad_mirror: True\n    y_pad_mirror: True\nWürth_36103605_60x60mm:\n    description: \"WE-SHC Shielding Cabinet SMD 60x60mm\"\n    datasheet: \"http://katalog.we-online.com/pbs/datasheet/36103605.pdf\"\n    courtjard: 0.25\n    pads_width: 1\n    x_part_size: 60\n    y_part_size: 60\n    x_pad_spacer: [2.45, 5.05, 7.45, 10.05, 12.45, 15.05, 17.45, 20.05, 22.45, 25.05, 27.25, 30.75]\n    y_pad_spacer: [2.45, 5.05, 7.45, 10.05, 12.45, 15.05, 17.45, 20.05, 22.45, 25.05, 27.25, 30.75]\n    x_pad_mirror: True\n    y_pad_mirror: True\n"
  },
  {
    "path": "scripts/Socket/3M_Textool.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\n\n# load parent path of KicadModTree\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))\n\nfrom KicadModTree import *\n\ndef roundCrtYd(x):\n    sign = x / abs(x)\n    return int((x + 0.0001 * sign) * 100) / 100.0\n\ndef textool(args):\n    name = args[\"name\"]\n    nPads = args[\"n_pads\"]\n    dimA = args[\"a\"]\n    dimB = args[\"b\"]\n    dimC = args[\"c\"]\n    mils = args[\"c_mils\"]\n    lever = args[\"lever\"]\n    minWidth = args[\"min\"]\n    maxWidth = args[\"max\"]\n\n    widths = \"_W\" + str(minWidth)\n    for i in range(0, 15):\n        w = i * 2.54\n        if w > minWidth and w < maxWidth:\n            widths = widths + \"_W\" + str(w)\n    widths = widths + \"_W\" + str(maxWidth)\n\n    footprint_name = \"DIP_Socket-\" + str(nPads) + widths + \"_3M_\" + name\n\n    f = Footprint(footprint_name)\n    f.setDescription(\"3M \" + str(nPads) + \"-pin zero insertion force socket, through-hole, row spacing \" + str(dimC) + \" mm (\" + str(mils) + \" mils), http://multimedia.3m.com/mws/media/494546O/3mtm-dip-sockets-100-2-54-mm-ts0365.pdf\")\n    f.setTags(\"THT DIP DIL ZIF \" + str(dimC) + \"mm \" + str(mils) + \"mil Socket\")\n    f.append(Model(filename=\"${KISYS3DMOD}/Socket.3dshapes/\" + footprint_name + \".wrl\", at=[0.0, 0.0, 0.0], scale=[1.0, 1.0, 1.0], rotate=[0.0, 0.0, 0.0]))\n\n    pitch = 2.54\n\n    d = [1.0, 1.0]\n    p = [2.0, 1.44]\n\n    r1 = 0.9\n    r2 = 2.55\n\n    s1 = [0.6, 0.6]\n    s2 = [1.0, 1.0]\n\n    t1 = 0.09\n    t2 = 0.15\n\n    wCrtYd = 0.05\n    wFab = 0.1\n    wSilkS = 0.12\n\n    silk = 0.1\n    crtYd = 0.5\n\n    xLeftPads = 0.0\n    xLeftFab = xLeftPads - (dimB - dimC) / 2\n    xLeftSilk = xLeftFab - silk\n    xLeftCrtYd = roundCrtYd(xLeftFab - crtYd)\n\n    xRightPads = dimC\n    xRightFab = xLeftFab + dimB\n    xRightSilk = xRightFab + silk\n    xRightCrtYd = roundCrtYd(xRightFab + crtYd)\n\n    xLeftLever = -5.0\n    xP1Ind = -4.95\n    x06 = -3.7\n    x07 = -3.5\n    x08 = -3.2\n    x09 = -2.85\n    x10 = -1.9\n    x11 = -1.7\n    x12 = -1.65\n    xRightLever = -0.4\n    xMiddle = dimC / 2\n\n    xLeftLeverCrtYd = roundCrtYd(xLeftLever - crtYd)\n    xRightLeverCrtYd = roundCrtYd(xRightLever + crtYd)\n\n    yTopPads = 0.0\n    yTopFab = -10.56\n    yTopSilk = yTopFab - silk\n    yTopCrtYd = roundCrtYd(yTopFab - crtYd)\n\n    yBottomFab = yTopFab + dimA\n    yBottomSilk = yBottomFab + silk\n    yBottomCrtYd = roundCrtYd(yBottomFab + crtYd)\n\n    # These four are the lever\n    yTopLever = yTopFab - lever # -25.4\n    y02 = yTopLever + 1.4       # -24.0\n    y03 = yTopLever + 5.0       # -20.4\n    y04 = yTopLever + 7.0       # -18.4\n\n    yRef = yTopFab - 1\n    yValue = yBottomFab + 1\n    yFabRef = (yTopFab + yBottomFab) / 2\n\n    y09 = -9.75\n    y10 = -9.4\n    y11 = -8.8\n    y12 = -8.4\n    y13 = -6.35\n    yBottomLever = -3.9\n    yFirstLine = -1.27\n    ySecondLine = 1.27\n\n    yTopLeverCrtYd = roundCrtYd(yTopLever - crtYd)\n    yBottomLeverCrtYd = roundCrtYd(yBottomLever + crtYd)\n\n    # Text\n    f.append(Text(type=\"reference\", text=\"REF**\", at=[xMiddle, yRef],\n                  layer=\"F.SilkS\", size=s2, thickness=t2))\n    f.append(Text(type=\"value\", text=footprint_name, at=[xMiddle, yValue],\n                  layer=\"F.Fab\", size=s1, thickness=t1))\n    f.append(Text(type=\"user\", text=\"%R\", at=[xMiddle, yFabRef],\n                  layer=\"F.Fab\", size=s2, thickness=t2))\n\n    # Courtyard\n    f.append(PolygoneLine(polygone=[[xLeftLeverCrtYd, yTopLeverCrtYd],\n                                    [xRightLeverCrtYd, yTopLeverCrtYd],\n                                    [xRightLeverCrtYd, yTopCrtYd],\n                                    [xRightCrtYd, yTopCrtYd],\n                                    [xRightCrtYd, yBottomCrtYd],\n                                    [xLeftCrtYd, yBottomCrtYd],\n                                    [xLeftCrtYd, yBottomLeverCrtYd],\n                                    [xLeftLeverCrtYd, yBottomLeverCrtYd],\n                                    [xLeftLeverCrtYd, yTopLeverCrtYd]],\n                          layer=\"F.CrtYd\", width=wCrtYd))\n\n    # Fab Lever\n    f.append(PolygoneLine(polygone=[[xLeftLever, y02],\n                                    [x06, yTopLever],\n                                    [x11, yTopLever],\n                                    [xRightLever, y02],\n                                    [xLeftLever, y02],\n                                    [xLeftLever, y03],\n                                    [xRightLever, y03],\n                                    [xRightLever, y02]],\n                          layer=\"F.Fab\", width=wFab))\n    f.append(Line(start=[xLeftLever, y03], end=[x07, y04], layer=\"F.Fab\", width=wFab))\n    f.append(Line(start=[xRightLever, y03], end=[x10, y04], layer=\"F.Fab\", width=wFab))\n    f.append(PolygoneLine(polygone=[[x07, y09],\n                                    [x07, y04],\n                                    [x10, y04],\n                                    [x10, yTopFab]],\n                          layer=\"F.Fab\", width=wFab))\n\n    # Fab Outline\n    f.append(PolygoneLine(polygone=[[xRightFab, yBottomFab],\n                                    [xLeftFab, yBottomFab],\n                                    [xLeftFab, y10],\n                                    [x09, yTopFab],\n                                    [xRightFab, yTopFab],\n                                    [xRightFab, yBottomFab]],\n                          layer=\"F.Fab\", width=wFab))\n\n    # Silk Outline\n    f.append(PolygoneLine(polygone=[[xLeftSilk, yBottomLever],\n                                    [xLeftSilk, yBottomSilk],\n                                    [xRightSilk, yBottomSilk],\n                                    [xRightSilk, yTopSilk],\n                                    [xLeftSilk, yTopSilk],\n                                    [xLeftSilk, y11]],\n                          layer=\"F.SilkS\", width=wSilkS))\n\n    # Silk Lever\n    f.append(Line(start=[x12, yTopSilk], end=[x12, y12], layer=\"F.SilkS\", width=wSilkS))\n    f.append(Circle(center=[x08, y13], radius=r2, layer=\"F.SilkS\", width=wSilkS))\n    f.append(Circle(center=[x08, y13], radius=r1, layer=\"F.SilkS\", width=wSilkS))\n\n    # Silk Pin 1 Indicator\n    f.append(Line(start=[xP1Ind, ySecondLine], end=[xP1Ind, yFirstLine],\n                  layer=\"F.SilkS\", width=wSilkS))\n\n    # Pads\n    pShape = Pad.SHAPE_RECT\n    for i in range(0, nPads >> 1):\n        y = yTopPads + i * pitch\n        f.append(Pad(number=str(i+1), type=Pad.TYPE_THT, shape=pShape,\n                     at=[xLeftPads, y], size=p, layers=Pad.LAYERS_THT, drill=d))\n        pShape = Pad.SHAPE_OVAL\n        f.append(Pad(number=str(nPads-i), type=Pad.TYPE_THT, shape=pShape,\n                     at=[xRightPads, y], size=p, layers=Pad.LAYERS_THT, drill=d))\n\n    file_handler = KicadFileHandler(f)\n    file_handler.writeFile(footprint_name + \".kicad_mod\")\n\n\nif __name__ == '__main__':\n    parser = ModArgparser(textool)\n    # the root node of .yml files is parsed as name\n    parser.add_parameter(\"name\", type=str, required=True)\n    parser.add_parameter(\"n_pads\", type=int, required=True)\n    parser.add_parameter(\"a\", type=float, required=True)\n    parser.add_parameter(\"b\", type=float, required=True)\n    parser.add_parameter(\"c\", type=float, required=True)\n    parser.add_parameter(\"c_mils\", type=int, required=True)\n    parser.add_parameter(\"lever\", type=float, required=False, default=12.3)\n    parser.add_parameter(\"min\", type=float, required=True)\n    parser.add_parameter(\"max\", type=float, required=True)\n\n    # now run our script which handles the whole part of parsing the files\n    parser.run()\n"
  },
  {
    "path": "scripts/Socket/3M_Textool.yaml",
    "content": "214-3339-00-0602J:\n  n_pads: 14\n  a: 33.0\n  b: 15.2\n  c: 7.62\n  c_mils: 300\n  min: 4.3\n  max: 10.9\n216-3340-00-0602J:\n  n_pads: 16\n  a: 35.3\n  b: 15.2\n  c: 7.62\n  c_mils: 300\n  min: 4.3\n  max: 10.9\n218-3341-00-0602J:\n  n_pads: 18\n  a: 37.8\n  b: 15.2\n  c: 7.62\n  c_mils: 300\n  min: 4.3\n  max: 10.9\n220-3342-00-0602J:\n  n_pads: 20\n  a: 40.4\n  b: 15.2\n  c: 7.62\n  c_mils: 300\n  min: 4.3\n  max: 10.9\n222-3343-00-0602J:\n  n_pads: 22\n  a: 42.9\n  b: 17.8\n  c: 10.16\n  c_mils: 400\n  min: 6.9\n  max: 13.5\n224-1275-00-0602J:\n  n_pads: 24\n  a: 45.3\n  b: 22.9\n  c: 15.24\n  c_mils: 600\n  min: 11.9\n  max: 18.5\n224-5248-00-0602J:\n  n_pads: 24\n  a: 45.5\n  b: 15.2\n  c: 7.62\n  c_mils: 300\n  min: 4.3\n  max: 10.9\n228-1277-00-0602J:\n  n_pads: 28\n  a: 50.4\n  b: 22.9\n  c: 15.24\n  c_mils: 600\n  min: 11.9\n  max: 18.5\n228-4817-00-0602J:\n  n_pads: 28\n  a: 50.5\n  b: 17.8\n  c: 10.16\n  c_mils: 400\n  min: 6.9\n  max: 13.5\n232-1285-00-0602J:\n  n_pads: 32\n  a: 55.5\n  b: 22.9\n  c: 15.24\n  c_mils: 600\n  min: 11.9\n  max: 18.5\n240-1280-00-0602J:\n  n_pads: 40\n  a: 65.6\n  b: 22.9\n  c: 15.24\n  c_mils: 600\n  min: 11.9\n  max: 18.5\n240-3639-00-0602J:\n  n_pads: 40\n  a: 65.5\n  b: 33.0\n  c: 25.40\n  c_mils: 1000\n  min: 22.1\n  max: 28.7\n242-1281-00-0602J:\n  n_pads: 42\n  a: 68.2\n  b: 22.9\n  c: 15.24\n  c_mils: 600\n  min: 11.9\n  max: 18.5\n"
  },
  {
    "path": "scripts/TerminalBlock_4Ucon/make_TerminalBlock_4Ucon.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_terminal_blocks import *\n\n\n\n\n\nif __name__ == '__main__':\n\n    script_generated_note=\"script-generated using https://github.com/pointhi/kicad-footprint-generator/scripts/TerminalBlock_4Ucon\";\n    classname=\"TerminalBlock_4Ucon\"\n    \n    \n\n \n    pins=[2,3,4,5,6,7,8,9,10,11,12,13,14,15]\n    rm=3.5\n    package_height=8.3\n    leftbottom_offset=[2.25,package_height-3.7]\n    ddrill=1.3\n    pad=[2.6,2.6]\n    bevel_height=[3.5]\n    opening=[2.8,3.75]\n    opening_yoffset=package_height-0.7-opening[1]\n    secondHoleDiameter=2\n    secondHoleOffset=[0,-(3.7-2.1)]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,3]\n    nibbleSize=[]\n    nibblePos=[]\n    for pi in range(0,len(pins)):\n        p=pins[pi];\n        itemno=10691+p;\n        name=\"{0}\".format(itemno);\n        webpage=\"http://www.4uconnector.com/online/object/4udrawing/{0}.pdf\".format(itemno);\n        classname_description=\"Terminal Block 4Ucon ItemNo. {0}\".format(itemno);\n        footprint_name=\"TerminalBlock_4Ucon_1x{2:02}_P{1:3.2f}mm_Vertical\".format(name, rm, p)\n        makeTerminalBlockVertical(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, \n                                  opening=opening, opening_yoffset=opening_yoffset, \n                                  bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n\n\n    \n    pins=[2,3,4,5,6,7,8,9,10,11,12,13,14,15]\n    itemnos=[19963,20193,20001,20223,19964,10684,19965,10686,10687,10688,10689,10690,10691,10692]\n    rm=3.5\n    package_height=7\n    leftbottom_offset=[2.1, package_height-3.4]\n    ddrill=1.2\n    pad=[2.4,2.4]\n    screw_diameter=2.75\n    bevel_height=[1.5]\n    slit_screw=False\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,2.8]\n    nibbleSize=[]\n    nibblePos=[]\n    for pi in range(0,len(pins)):\n        p=pins[pi];\n        itemno=itemnos[pi];\n        name=\"{0}\".format(itemno);\n        webpage=\"http://www.4uconnector.com/online/object/4udrawing/{0}.pdf\".format(itemno);\n        classname_description=\"Terminal Block 4Ucon ItemNo. {0}\".format(itemno);\n        footprint_name=\"TerminalBlock_4Ucon_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n     \n    \n    \n    \n    \n    "
  },
  {
    "path": "scripts/TerminalBlock_Altech/Altech.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport os\nimport math\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load parent path of KicadModTree\nimport argparse\nimport yaml\nfrom KicadModTree import *\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"tools\"))  # load parent path of tools\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"general\"))  # load parent path of tools\nfrom StandardBox import *\n\ndef qfn(args):\n\n    extraffablines = []\n\n    name = args[\"name\"]\n    description = args[\"description\"]\n    datasheet = args[\"datasheet\"]\n    tags = args[\"tags\"]\n    manufacture = args[\"manufacture\"]\n    serie = args[\"serie\"]\n    \n    W = args[\"W\"]\n    H = args[\"H\"]\n    WD = args[\"WD\"]\n    A1 = args[\"A1\"]\n    pinnumbers = args[\"pin_number\"]\n    PE = args[\"PE\"]\n    PS = args[\"PS\"]\n    PD = args[\"PD\"]\n    PL = args[\"PL\"]\n    PF = args[\"PF\"]\n    SW = args[\"SW\"]\n    DD = args[\"DD\"]\n    PD = args[\"PD\"]\n    rotation = args[\"rotation\"]\n    dest_dir_3D_prefix = args[\"dest_dir_3D_prefix\"]\n\n    \n    for pinnumber in pinnumbers:\n        footprint_name = ''\n        footprint_name = footprint_name + manufacture + '_' + serie\n        footprint_name = footprint_name + '_1x' + '{:02d}'.format(pinnumber)\n        footprint_name = footprint_name + '_P' + '{:.2f}'.format(PS) + \"mm\"\n        footprint_name = footprint_name + '_45-Degree'\n    \n        f = Footprint(footprint_name)\n\n        \n        file3Dname = \"${KISYS3DMOD}/\" + dest_dir_3D_prefix + \"/\" + footprint_name + \".wrl\"\n        words = footprint_name.split(\"_\")\n        if words[-1].lower().startswith('handsolder'):\n            words[-1] = ''\n            ff = '_'.join(words)\n            file3Dname = \"${KISYS3DMOD}/\" + dest_dir_3D_prefix + \"/\" + ff + \".wrl\"\n            \n        lw = ((2.0 * PE) + ((pinnumber - 1) * PS))\n        at = [0.0 - PE, W - WD]\n        size = [lw, W]\n        extratexts = None\n        SmdTht = None\n        pins = []\n        dx = 0.0\n        for ii in range(1, pinnumber + 1):\n            pins.append([\"tht\", str(ii), dx, 0.0, PD, PD, DD])\n            dx = dx + PS\n        f.append(StandardBox(footprint=f, description=description, datasheet=datasheet, at=at, size=size, tags=tags, SmdTht=SmdTht, extratexts=extratexts, pins=pins, file3Dname=file3Dname ))\n        #\n        #\n        file_handler = KicadFileHandler(f)\n        file_handler.writeFile(footprint_name + \".kicad_mod\")\n\n\nif __name__ == '__main__':\n\tparser = ModArgparser(qfn)\n\t# the root node of .yml files is parsed as name\n\tparser.add_parameter(\"name\",        type=str,   required=True)\n\tparser.add_parameter(\"description\", type=str,   required=True)\n\tparser.add_parameter(\"datasheet\",   type=str,   required=True)\n\tparser.add_parameter(\"tags\",        type=str,   required=True)\n\tparser.add_parameter(\"manufacture\", type=str,   required=True)\n\tparser.add_parameter(\"serie\",       type=str,   required=True)\n\n\tparser.add_parameter(\"W\",           type=float, required=True)\n\tparser.add_parameter(\"H\",           type=float, required=True)\n\tparser.add_parameter(\"WD\",          type=float, required=True)\n\tparser.add_parameter(\"A1\",          type=float, required=True)\n\tparser.add_parameter(\"pin_number\",  type=list,  required=True)\n\tparser.add_parameter(\"PE\",          type=float, required=True)\n\tparser.add_parameter(\"PS\",          type=float, required=True)\n\tparser.add_parameter(\"PD\",          type=list,  required=True)\n\tparser.add_parameter(\"PL\",          type=float, required=True)\n\tparser.add_parameter(\"PF\",          type=str,   required=True)\n\tparser.add_parameter(\"SW\",          type=float, required=True)\n\tparser.add_parameter(\"DD\",          type=float, required=True)\n\tparser.add_parameter(\"PD\",          type=float, required=True)\n\tparser.add_parameter(\"rotation\",    type=str,   required=True)\n\tparser.add_parameter(\"dest_dir_3D_prefix\",    type=str,   required=True)\n\n\t# now run our script which handles the whole part of parsing the files\n\tparser.run()\n"
  },
  {
    "path": "scripts/TerminalBlock_Altech/Altech.yml",
    "content": "AK300:\n  description: \"Altech AK300 serie terminal block\"\n  datasheet: \"http://www.altechcorp.com/PDFS/PCBMETRC.PDF\"\n  tags: \"Altech AK300 serie connector\"\n  manufacture: 'Altech' # Model name\n  serie: 'AK300'        # Model name\n  W: 12.5               # Package width\n  H: 12.5               # Package height\n  WD: 6.5               # > Y distance form pin center to package edge\n  A1: 0.1               # package board seperation\n  pin_number: [ 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]  # Which pin configuration\n  PE: 2.5               # Distance from edge to pin\n  PS: 5.0               # Distance between pins\n  PD: [1.0, 0.8]        # Pin size, [1.0] diameter 1 mm, [1.0, 0.8] rectangle 1.0x0.8\n  PL: 4.5               # Pin length\n  PF: 'rect'            # Pin form 'round' or 'rect'\n  SW: 2.7               # Blender width\n  DD: 1.5               # Drill diameter\n  PD: 3.0               # Pad diameter\n  rotation: 0           # Rotation if required\n  dest_dir_3D_prefix: 'TerminalBlock_Altech.3dshapes'  # Destination directory\n"
  },
  {
    "path": "scripts/TerminalBlock_MetzConnect/make_SingleTerminalBlock_MetzConnect.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_terminal_blocks import *\n\n\n\n\n\nif __name__ == '__main__':\n\n    script_generated_note=\"script-generated using https://github.com/pointhi/kicad-footprint-generator/scripts/TerminalBlock_MetzConnect\";\n    classname=\"TerminalBlock_MetzConnect\"\n        \n    block_size=[4,4]\n    block_offset=[0,0]\n    pins=[[1.5,0],[-1.5,0]]\n    ddrill=1.5\n    pad=[3,3]\n    screw_diameter=3\n    screw_offset=[0,0]\n    slit_screw=True\n    name=\"360272\"\n    webpage=\"http://www.metz-connect.com/de/system/files/METZ_CONNECT_U_Contact_Katalog_Anschlusssysteme_fuer_Leiterplatten_DE_31_07_2017_OFF_024803.pdf?language=en page 131\"\n    footprint_name=\"TerminalBlock_MetzConnect_{0}_1x01_Horizontal_ScrewM2.6\".format(name)\n    classname_description=\"single screw terminal block Metz Connect {0}\".format(name)\n    makeScrewTerminalSingleStd(footprint_name, block_size=block_size, block_offset=block_offset, pins=pins, ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, screw_offset=screw_offset, slit_screw=slit_screw,\n                        tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n       \n    block_size=[5,4]\n    block_offset=[0.5,0]\n    name=\"360273\"\n    footprint_name=\"TerminalBlock_MetzConnect_{0}_1x01_Horizontal_ScrewM2.6_WireProtection\".format(name)\n    classname_description=\"single screw terminal block Metz Connect {0}\".format(name)\n    makeScrewTerminalSingleStd(footprint_name, block_size=block_size, block_offset=block_offset, pins=pins, ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, screw_offset=screw_offset, slit_screw=slit_screw,\n                        tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n      \n    block_size=[5,5]\n    block_offset=[0,0]\n    pins=[[2,0],[-2,0]]\n    ddrill=1.5\n    pad=[3,3]\n    screw_diameter=4\n    screw_offset=[0,0]\n    slit_screw=True\n    name=\"360410\"\n    webpage=\"http://www.metz-connect.com/de/system/files/METZ_CONNECT_U_Contact_Katalog_Anschlusssysteme_fuer_Leiterplatten_DE_31_07_2017_OFF_024803.pdf?language=en page 132\"\n    footprint_name=\"TerminalBlock_MetzConnect_{0}_1x01_Horizontal_ScrewM3.0\".format(name)\n    classname_description=\"single screw terminal block Metz Connect {0}\".format(name)\n    makeScrewTerminalSingleStd(footprint_name, block_size=block_size, block_offset=block_offset, pins=pins, ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, screw_offset=screw_offset, slit_screw=slit_screw,\n                        tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n    name=\"360381\"\n    webpage=\"http://www.metz-connect.com/de/system/files/METZ_CONNECT_U_Contact_Katalog_Anschlusssysteme_fuer_Leiterplatten_DE_31_07_2017_OFF_024803.pdf?language=en page 133\"\n    footprint_name=\"TerminalBlock_MetzConnect_{0}_1x01_Horizontal_ScrewM3.0\".format(name)\n    classname_description=\"single screw terminal block Metz Connect {0}\".format(name)\n    makeScrewTerminalSingleStd(footprint_name, block_size=block_size, block_offset=block_offset, pins=pins, ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, screw_offset=screw_offset, slit_screw=slit_screw,\n                        tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n       \n    block_size=[6,4]\n    block_offset=[1,0]\n    name=\"360322\"\n    footprint_name=\"TerminalBlock_MetzConnect_{0}_1x01_Horizontal_ScrewM3.0_WireProtection\".format(name)\n    classname_description=\"single screw terminal block Metz Connect {0}\".format(name)\n    makeScrewTerminalSingleStd(footprint_name, block_size=block_size, block_offset=block_offset, pins=pins, ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, screw_offset=screw_offset, slit_screw=slit_screw,\n                        tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n      \n    block_size=[9, 7.3]\n    block_offset=[0,0]\n    pins=[[2,0],[-2,0]]\n    ddrill=1.5\n    pad=[3,3]\n    screw_diameter=4\n    screw_offset=[0,0]\n    slit_screw=True\n    name=\"360291\"\n    webpage=\"http://www.metz-connect.com/de/system/files/METZ_CONNECT_U_Contact_Katalog_Anschlusssysteme_fuer_Leiterplatten_DE_31_07_2017_OFF_024803.pdf?language=en page 133\"\n    footprint_name=\"TerminalBlock_MetzConnect_{0}_1x01_Horizontal_ScrewM3.0_Boxed\".format(name)\n    classname_description=\"single screw terminal block Metz Connect {0}\".format(name)\n    makeScrewTerminalSingleStd(footprint_name, block_size=block_size, block_offset=block_offset, pins=pins, ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, screw_offset=screw_offset, slit_screw=slit_screw,\n                        tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n                                       \n    block_size=[9, 7.3]\n    block_offset=[0,0]\n    pins=[[0,0]]\n    ddrill=1.5\n    pad=[3,3]\n    screw_diameter=4\n    screw_offset=[0,0]\n    slit_screw=True\n    name=\"360271\"\n    webpage=\"http://www.metz-connect.com/de/system/files/METZ_CONNECT_U_Contact_Katalog_Anschlusssysteme_fuer_Leiterplatten_DE_31_07_2017_OFF_024803.pdf?language=en page 134\"\n    footprint_name=\"TerminalBlock_MetzConnect_{0}_1x01_Horizontal_ScrewM3.0_Boxed\".format(name)\n    classname_description=\"single screw terminal block Metz Connect {0}\".format(name)\n    makeScrewTerminalSingleStd(footprint_name, block_size=block_size, block_offset=block_offset, pins=pins, ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, screw_offset=screw_offset, slit_screw=slit_screw,\n                        tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n                                       \n    block_size=[9,9]\n    block_offset=[0,0]\n    pins=[[4,4],[-4,4],[4,-4],[-4,-4]]\n    ddrill=1.6\n    pad=[3.2,3.2]\n    screw_diameter=7\n    screw_offset=[0,0]\n    slit_screw=True\n    name=\"360425\"\n    webpage=\"http://www.metz-connect.com/de/system/files/METZ_CONNECT_U_Contact_Katalog_Anschlusssysteme_fuer_Leiterplatten_DE_31_07_2017_OFF_024803.pdf?language=en page 134\"\n    footprint_name=\"TerminalBlock_MetzConnect_{0}_1x01_Horizontal_ScrewM4.0_Boxed\".format(name)\n    classname_description=\"single screw terminal block Metz Connect {0}\".format(name)\n    makeScrewTerminalSingleStd(footprint_name, block_size=block_size, block_offset=block_offset, pins=pins, ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, screw_offset=screw_offset, slit_screw=slit_screw,\n                        tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n                                  "
  },
  {
    "path": "scripts/TerminalBlock_MetzConnect/make_TerminalBlock_MetzConnect.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_terminal_blocks import *\n\n\n\n\n\nif __name__ == '__main__':\n\n    script_generated_note=\"script-generated using https://github.com/pointhi/kicad-footprint-generator/scripts/TerminalBlock_MetzConnect\";\n    classname=\"TerminalBlock_MetzConnect\"\n        \n    pins=[2,3,4,5,6]\n    rm=5\n    package_height=12.5\n    leftbottom_offset=[rm/2, 6.5]\n    ddrill=1.4\n    pad=[2.7,2.7]\n    screw_diameter=2.2\n    bevel_height=[5.4,9.2]\n    vsegment_lines_offset=[]\n    opening=[3.5,4]\n    opening_xoffset=0\n    opening_yoffset=1\n    opening_elliptic=False\n    secondDrillDiameter=0\n    secondDrillOffset=[2.5,-5]\n    secondDrillPad=pad\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[1.25,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[1.25,-5.75]\n    fifthHoleDiameter=0\n    fifthHoleOffset=[1.25,-0.75]\n    secondEllipseSize=[3.6,2.8]\n    secondEllipseOffset=[0,-4.4]\n    fabref_offset=[0,-1]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type205_RT045{0:02}UBLC\".format(p)\n        webpage=\"http://www.metz-connect.com/de/system/files/productfiles/Datenblatt_312051_RT045xxUBLC_OFF-022759T.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_45Degree\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlock45Degree(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad,  vsegment_lines_offset=vsegment_lines_offset,\n                                  opening=opening, opening_xoffset=opening_xoffset, opening_yoffset=opening_yoffset, opening_elliptic=opening_elliptic,\n                                  bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, fifthHoleDiameter=fifthHoleDiameter,fifthHoleOffset=fifthHoleOffset,\n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  secondEllipseSize=secondEllipseSize,secondEllipseOffset=secondEllipseOffset,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n\n    pins=range(2,6+1)\n    rm=3.81\n    package_height=7.3\n    leftbottom_offset=[1.85, 3.6]\n    ddrill=0.7\n    pad=[1.4,1.4]\n    screw_diameter=2.5\n    bevel_height=[0.6,1.9,package_height-2]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=[2,0.5]\n    thirdHoleOffset=[0,-(3.6-0.5/2)]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,2.45]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type086_RT034{0:02}HBLC\".format(p)\n        webpage=\"http://www.metz-connect.com/de/system/files/productfiles/Datenblatt_310861_RT034xxHBLC_OFF-026114K.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n    pins=range(2,6+1)\n    rm=5.0\n    package_height=10.5\n    leftbottom_offset=[2.5, 4]\n    ddrill=1.4\n    pad=[2.8,2.8]\n    screw_diameter=3.2\n    bevel_height=[2,package_height-4.5,package_height-3.5]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,4.5]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type011_RT055{0:02}HBWC\".format(p)\n        webpage=\"http://www.metz-connect.com/de/system/files/productfiles/Datenblatt_310111_RT055xxHBLC_OFF-022717S.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n                                  \n\n    pins=range(2,5+1)\n    rm=10\n    package_height=8.2\n    leftbottom_offset=[2.9, 4.1]\n    ddrill=1.3\n    pad=[2.6,2.6]\n    screw_diameter=3\n    bevel_height=[2,package_height-2]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,3]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type067_RT019{0:02}HDWC\".format(p)\n        webpage=\"http://www.metz-connect.com/de/system/files/productfiles/Datenblatt_310671_RT019xxHDWC_OFF-023605N.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n\n    pins=range(2,3+1)\n    rm=9.52\n    package_height=12.5\n    leftbottom_offset=[4.76, 8]\n    ddrill=1.3\n    pad=[2.6,2.6]\n    screw_diameter=4\n    bevel_height=[0.5,4.5,package_height-2]\n    slit_screw=True\n    screw_pin_offset=[0,0.5]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=[2,1]\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,3.5]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type703_RT10N{0:02}HGLU\".format(p)\n        webpage=\"http://www.metz-connect.com/de/system/files/productfiles/Datenblatt_317031_RT10NxxHGLU_OFF-022897S.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n  \n    pins=range(2,6+1)\n    rm=5.0\n    package_height=8.3\n    leftbottom_offset=[2.5, 4]\n    ddrill=1.3\n    pad=[2.6,2.6]\n    screw_diameter=3\n    bevel_height=[0.5,2,package_height-2]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=[2,1]\n    thirdHoleOffset=[0,-(4.3-0.5)]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,2.9]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type094_RT035{0:02}HBLU\".format(p)\n        webpage=\"http://www.metz-connect.com/ru/system/files/productfiles/Data_sheet_310941_RT035xxHBLU_OFF-022742T.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n    pins=range(2,6+1)\n    rm=5.08\n    package_height=8\n    leftbottom_offset=[2.54, 4]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=3\n    bevel_height=[2,package_height-2]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,3]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type101_RT016{0:02}HBWC\".format(p)\n        webpage=\"http://www.metz-connect.com/de/system/files/productfiles/Datenblatt_311011_RT016xxHBWC_OFF-022771S.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n    pins=range(2,6+1)\n    rm=3.5\n    package_height=6.5\n    leftbottom_offset=[rm/2, 3.7]\n    ddrill=1.2\n    pad=[2.3,2.3]\n    screw_diameter=2.75\n    bevel_height=[1.5]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,2.5]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type059_RT063{0:02}HBWC\".format(p)\n        webpage=\"http://www.metz-connect.com/de/system/files/productfiles/Datenblatt_310591_RT063xxHBWC_OFF-022684T.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n\n    pins=range(2,3+1)\n    rm=5.08\n    package_height=11\n    leftbottom_offset=[2.54, 5.5]\n    ddrill=1.4\n    pad=[2.6,2.6]\n    screw_diameter=3.5\n    bevel_height=[0.5,3,package_height-1.8]\n    slit_screw=True\n    screw_pin_offset=[0,-0.3]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,3.5]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type073_RT026{0:02}HBLU\".format(p)\n        webpage=\"http://www.metz-connect.com/de/system/files/productfiles/Datenblatt_310731_RT026xxHBLU_OFF-022792U.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n    pins=range(2,3+1)\n    rm=6.35\n    package_height=12.5\n    leftbottom_offset=[3.175, 8]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=4\n    bevel_height=[0.5,5.5,package_height-2]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=[2,1]\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,3.5]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type701_RT11L{0:02}HGLU\".format(p)\n        webpage=\"http://www.metz-connect.com/de/system/files/productfiles/Datenblatt_317011_RT11LxxHGLU_OFF-022798U.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n\n    pins=range(2,6+1)\n    rm=7.5\n    package_height=9\n    leftbottom_offset=[3.75, 4.5]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=3\n    bevel_height=[2,package_height-2]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[rm/2,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,3.5]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type171_RT137{0:02}HBWC\".format(p)\n        webpage=\"http://www.metz-connect.com/de/system/files/productfiles/Datenblatt_311711_RT137xxHBWC_OFF-022811Q.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n \n    pins=range(2,6+1)\n    rm=7.5\n    package_height=11\n    leftbottom_offset=[3.75, 5.5]\n    ddrill=1.4\n    pad=[2.6,2.6]\n    screw_diameter=3\n    bevel_height=[0.6,2.5,package_height-1.9]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[rm/2,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,4]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type175_RT027{0:02}HBLC\".format(p)\n        webpage=\"http://www.metz-connect.com/de/system/files/productfiles/Datenblatt_311751_RT027xxHBLC_OFF-022814U.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n    pins=range(2,4+1)\n    rm=5\n    package_height=8\n    leftbottom_offset=[2.5,4]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=3\n    bevel_height=[2,package_height-2]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[rm/2,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,3]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"Type055_RT015{0:02}HDWU\".format(p)\n        webpage=\"http://www.metz-connect.com/de/system/files/productfiles/Datenblatt_310551_RT015xxHDWU_OFF-022723S.pdf\"\n        footprint_name=\"TerminalBlock_MetzConnect_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block Metz Connect {0}\".format(name, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n                                  "
  },
  {
    "path": "scripts/TerminalBlock_Philmore/make_TerminalBlock_Philmore.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_terminal_blocks import *\n\n\n\n\n\nif __name__ == '__main__':\n\n    script_generated_note=\"script-generated using https://github.com/pointhi/kicad-footprint-generator/scripts/TerminalBlock_Philmore\";\n    classname=\"TerminalBlock_Philmore\"\n    \n    \n\n    \n    pins=range(2,3+1)\n    rm=5\n    package_height=10.2\n    leftbottom_offset=[rm/2, 5.4]\n    ddrill=1.2\n    pad=[2.4,2.4]\n    screw_diameter=2.75\n    bevel_height=[0.5,1.6]\n    slit_screw=False\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,2.5]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"TB13{0}\".format(p);\n        webpage=\"http://www.philmore-datak.com/mc/Page%20197.pdf\";\n        classname_description=\"Terminal Block Philmore \".format(name);\n        footprint_name=\"TerminalBlock_Philmore_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n     \n    \n    \n    \n    \n    "
  },
  {
    "path": "scripts/TerminalBlock_Phoenix/make_TerminalBlock_Phoenix.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_terminal_blocks import *\n\n\n\n\n\nif __name__ == '__main__':\n\n    script_generated_note=\"script-generated using https://github.com/pointhi/kicad-footprint-generator/scripts/TerminalBlock_Phoenix\";\n    classname=\"TerminalBlock_Phoenix\"\n    \n    \n \n    pins=range(2,8+1)\n    rm=2.5\n    package_height=5\n    leftbottom_offset=[3-0.65, 0.9, 0.65]\n    ddrill=1.2\n    pad=[2,2]\n    bevel_height=[]\n    opening=[2,1]\n    opening_xoffset=1\n    opening_yoffset=3.0\n    secondDrillDiameter=ddrill\n    secondDrillOffset=[0,-3.1]\n    secondDrillPad=pad\n    secondHoleDiameter=2\n    secondHoleOffset=[-1,-0.5]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[-1,-1]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,-3.56]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"PTSM-0,5-{0}-{1:1.2}-V-THR\".format(p,rm);\n        webpage=\"http://www.produktinfo.conrad.com/datenblaetter/550000-574999/556444-da-01-de-LEITERPLATTENKL__PTSM_0_5__4_2_5_V_THR.pdf\";\n        classname_description=\"Terminal Block Phoenix {0}\".format(name);\n        footprint_name=\"TerminalBlock_Phoenix_{0}_1x{2:02}_P{1:3.2f}mm_Vertical\".format(name, rm, p)\n        makeTerminalBlockVertical(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, opening_xoffset=opening_xoffset, opening_yoffset=opening_yoffset, opening=opening,\n                                  ddrill=ddrill, pad=pad, bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n   \n \n    pins=range(2,8+1)\n    rm=2.5\n    package_height=10\n    leftbottom_offset=[2.35, 2.8]\n    ddrill=1.2\n    pad=[1.8,3]\n    screw_diameter=0\n    bevel_height=[]\n    slit_screw=False\n    screw_pin_offset=[0,0]\n    secondDrillDiameter=ddrill\n    secondDrillOffset=[0,-5]\n    secondDrillPad=pad\n    secondHoleDiameter=[1,1]\n    secondHoleOffset=[0,6.5]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,0]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"PTSM-0,5-{0}-{1:1.2}-H-THR\".format(p,rm);\n        webpage=\"http://www.produktinfo.conrad.com/datenblaetter/550000-574999/556441-da-01-de-LEITERPLATTENKL__PTSM_0_5__8_2_5_H_THR.pdf\";\n        classname_description=\"Terminal Block Phoenix {0}\".format(name);\n        footprint_name=\"TerminalBlock_Phoenix_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n   \n \n    pins=range(2,16+1)\n    rm=5.08\n    package_height=9.8\n    leftbottom_offset=[rm/2, 4.6]\n    ddrill=1.3\n    pad=[2.6,2.6]\n    screw_diameter=3\n    bevel_height=[0.5,2,6.9]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,3.5]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"MKDS-1,5-{0}-{1:2.3}\".format(p,rm);\n        webpage=\"http://www.farnell.com/datasheets/100425.pdf\";\n        classname_description=\"Terminal Block Phoenix {0}\".format(name);\n        footprint_name=\"TerminalBlock_Phoenix_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n     \n   \n    pins=range(2,16+1)\n    rm=5\n    package_height=9.8\n    leftbottom_offset=[rm/2, 4.6]\n    ddrill=1.3\n    pad=[2.6,2.6]\n    screw_diameter=3\n    bevel_height=[0.5,2,6.9]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,3.5]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"MKDS-1,5-{0}\".format(p);\n        webpage=\"http://www.farnell.com/datasheets/100425.pdf\";\n        classname_description=\"Terminal Block Phoenix {0}\".format(name);\n        footprint_name=\"TerminalBlock_Phoenix_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n  \n\n    \n    pins=range(2,16+1)\n    rm=5.08\n    package_height=11.2\n    leftbottom_offset=[rm/2, 5.3]\n    ddrill=1.3\n    pad=[2.6,2.6]\n    screw_diameter=4\n    bevel_height=[0.5,3,9.2]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,3.4]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"MKDS-3-{0}-{1:2.3}\".format(p,rm);\n        webpage=\"http://www.farnell.com/datasheets/2138224.pdf\";\n        classname_description=\"Terminal Block Phoenix {0}\".format(name);\n        footprint_name=\"TerminalBlock_Phoenix_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n     \n    \n     \n\n    \n    pins=range(2,16+1)\n    rm=3.5\n    package_height=7.6\n    leftbottom_offset=[rm/2, package_height-3.1]\n    ddrill=1.2\n    pad=[2.4,2.4]\n    screw_diameter=3\n    bevel_height=[0.4,1.5]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondDrillDiameter=0\n    secondDrillOffset=[0,2.54]\n    secondDrillPad=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,1.7]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"PT-1,5-{0}-{1:1.2}-H\".format(p,rm);\n        webpage=\"\";\n        classname_description=\"Terminal Block Phoenix {0}\".format(name);\n        footprint_name=\"TerminalBlock_Phoenix_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n    \n    \n     \n\n    \n    pins=range(2,16+1)\n    rm=5.0\n    package_height=9\n    leftbottom_offset=[rm/2, package_height-4]\n    ddrill=1.3\n    pad=[2.6,2.6]\n    screw_diameter=4\n    bevel_height=[0.4,1.5]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondDrillDiameter=0\n    secondDrillOffset=[0,2.54]\n    secondDrillPad=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,2.4]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"PT-1,5-{0}-{1:1.2}-H\".format(p,rm);\n        webpage=\"http://www.mouser.com/ds/2/324/ItemDetail_1935161-922578.pdf\";\n        classname_description=\"Terminal Block Phoenix {0}\".format(name);\n        footprint_name=\"TerminalBlock_Phoenix_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n      \n\n    \n    pins=range(2,3+1)\n    rm=2.54\n    package_height=6.2\n    leftbottom_offset=[1.5, 3.1]\n    ddrill=1.1\n    pad=[2.2,2.2]\n    screw_diameter=2.2\n    bevel_height=[0.5,5.8]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondDrillDiameter=1.1\n    secondDrillOffset=[0,2.54]\n    secondDrillPad=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,2.0]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"MPT-0,5-{0}-{1:2.3}\".format(p,rm);\n        webpage=\"http://www.mouser.com/ds/2/324/ItemDetail_1725656-920552.pdf\";\n        classname_description=\"Terminal Block Phoenix {0}\".format(name);\n        footprint_name=\"TerminalBlock_Phoenix_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n    \n   \n    pins=range(4,12+1)\n    rm=2.54\n    package_height=6.2\n    leftbottom_offset=[1.5, 3.1]\n    ddrill=1.1\n    pad=[2.2,2.2]\n    screw_diameter=2.2\n    bevel_height=[0.5,5.8]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondDrillDiameter=0\n    secondDrillOffset=[0,2.54]\n    secondDrillPad=[0,0]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,-4]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,2.0]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"MPT-0,5-{0}-{1:2.3}\".format(p,rm);\n        webpage=\"http://www.mouser.com/ds/2/324/ItemDetail_1725672-916605.pdf\";\n        classname_description=\"Terminal Block Phoenix {0}\".format(name);\n        footprint_name=\"TerminalBlock_Phoenix_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n    \n    \n    \n    \n    "
  },
  {
    "path": "scripts/TerminalBlock_RND/make_TerminalBlock_RND.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_terminal_blocks import *\n\n\n\n\n\nif __name__ == '__main__':\n\n    script_generated_note=\"script-generated using https://github.com/pointhi/kicad-footprint-generator/scripts/TerminalBlock_RND\";\n    classname=\"TerminalBlock_RND\"\n\n    pins=range(2,12+1)\n    rm=5\n    package_height=10\n    leftbottom_offset=[rm/2,package_height-2.3]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    bevel_height=[3.5]\n    opening=[4.1,5.4]\n    opening_yoffset=package_height-1-opening[1]\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=[0,3]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        makeTerminalBlockVertical(footprint_name=\"TerminalBlock_RND_205-{0:05}_1x{2:02}_P{1:3.2f}mm_Vertical\".format(274+p, rm, p), \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, \n                                  opening=opening, opening_yoffset=opening_yoffset, \n                                  bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize,nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name=\"${KISYS3DMOD}/TerminalBlock_RND\", classname=\"TerminalBlock_RND\", classname_description=\"terminal block RND 205-{0:05}\".format(76+p), webpage=\"http://cdn-reichelt.de/documents/datenblatt/C151/RND_205-00276_DB_EN.pdf\", script_generated_note=script_generated_note)\n\n    \n    pins=range(2,12+1)\n    rm=5.08\n    package_height=10.6\n    leftbottom_offset=[2.54, 5.3]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=3\n    bevel_height=[0.6,2.8,package_height-2]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=[2.5,.5]\n    secondHoleOffset=[0,-(package_height-leftbottom_offset[1])+secondHoleDiameter[1]]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    nibbleSize=[]#[0.6,1.2]\n    nibblePos=[]#[-nibbleSize[0],0.25]\n    fabref_offset=0\n    for p in pins:\n        name=\"205-{0:05}\".format(285+p)\n        footprint_name=\"TerminalBlock_RND_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block RND {0}\".format(name)\n        webpage=\"http://cdn-reichelt.de/documents/datenblatt/C151/RND_205-00287_DB_EN.pdf\"\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n                                  \n    pins=range(2,12+1)\n    rm=5\n    package_height=8.1\n    leftbottom_offset=[2.5, 4.05]\n    ddrill=1.1\n    pad=[2.1,2.1]\n    screw_diameter=3\n    bevel_height=[0.6,1.2,package_height-2]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=[2.5,1]\n    secondHoleOffset=[0,-(package_height-leftbottom_offset[1])+secondHoleDiameter[1]/2]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[rm/2,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[rm/2,-(package_height-leftbottom_offset[1])+secondHoleDiameter[1]/2]\n    fabref_offset=0\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"205-{0:05}\".format(43+p)\n        footprint_name=\"TerminalBlock_RND_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block RND {0}\".format(name)\n        webpage=\"http://cdn-reichelt.de/documents/datenblatt/C151/RND_205-00045_DB_EN.pdf\"\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n    pins=range(2,12+1)\n    rm=5\n    package_height=12.6\n    leftbottom_offset=[rm/2, 6.5]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=2.2\n    bevel_height=[7.7,9.8]\n    vsegment_lines_offset=[]\n    opening=[3.0,5]\n    opening_xoffset=0\n    opening_yoffset=2\n    opening_elliptic=False\n    secondDrillDiameter=0\n    secondDrillOffset=[2.5,-5]\n    secondDrillPad=pad\n    secondHoleDiameter=0\n    secondHoleOffset=[0,0]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[1.25,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[1.25,-5.75]\n    fifthHoleDiameter=0\n    fifthHoleOffset=[1.25,-0.75]\n    secondEllipseSize=[3.2,2.5]\n    secondEllipseOffset=[0,-4.7]\n    fabref_offset=[0,-1]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"205-{0:05}\".format(54+p)\n        footprint_name=\"TerminalBlock_RND_{0}_1x{2:02}_P{1:3.2f}mm_45Degree\".format(name, rm, p)\n        classname_description=\"terminal block RND {0}\".format(name)\n        webpage=\"http://cdn-reichelt.de/documents/datenblatt/C151/RND_205-00056_DB_EN.pdf\"\n        makeTerminalBlock45Degree(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad,  vsegment_lines_offset=vsegment_lines_offset,\n                                  opening=opening, opening_xoffset=opening_xoffset, opening_yoffset=opening_yoffset, opening_elliptic=opening_elliptic,\n                                  bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, fifthHoleDiameter=fifthHoleDiameter,fifthHoleOffset=fifthHoleOffset,\n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  secondEllipseSize=secondEllipseSize,secondEllipseOffset=secondEllipseOffset,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n   \n    pins=range(2,12+1)\n    rm=10\n    package_height=10.3\n    leftbottom_offset=[rm/4, 5]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=3\n    bevel_height=[0.6,1.2,package_height-2]\n    slit_screw=False\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=[2.5,1]\n    secondHoleOffset=[0,-(package_height-leftbottom_offset[1])+secondHoleDiameter[1]/2]\n    thirdHoleDiameter=screw_diameter\n    thirdHoleOffset=[rm/2,0]\n    fourthHoleDiameter=[2.5,1]\n    fourthHoleOffset=[rm/2,-(package_height-leftbottom_offset[1])+secondHoleDiameter[1]/2]\n    fabref_offset=[0,3]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"205-{0:05}\".format(76+p)\n        footprint_name=\"TerminalBlock_RND_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block RND {0}\".format(name)\n        webpage=\"http://cdn-reichelt.de/documents/datenblatt/C151/RND_205-00078_DB_EN.pdf\"\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n    \n    pins=range(2,12+1)\n    rm=7.5\n    package_height=10.3\n    leftbottom_offset=[rm/2, 5]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=3\n    bevel_height=[0.6,1.2,package_height-2]\n    slit_screw=False\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=[2.5,1]\n    secondHoleOffset=[0,-(package_height-leftbottom_offset[1])+secondHoleDiameter[1]/2]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[rm/2,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[rm/2,-(package_height-leftbottom_offset[1])+secondHoleDiameter[1]/2]\n    fabref_offset=[0,3]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"205-{0:05}\".format(65+p)\n        footprint_name=\"TerminalBlock_RND_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block RND {0}\".format(name)\n        webpage=\"http://cdn-reichelt.de/documents/datenblatt/C151/RND_205-00067_DB_EN.pdf\"\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n                                  \n    pins=range(2,12+1)\n    rm=10\n    package_height=8.1\n    leftbottom_offset=[2.5, 4.05]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=3\n    bevel_height=[0.6,1.2,package_height-2]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=[2.5,1]\n    secondHoleOffset=[0,-(package_height-leftbottom_offset[1])+secondHoleDiameter[1]/2]\n    thirdHoleDiameter=screw_diameter\n    thirdHoleOffset=[rm/2,0]\n    fourthHoleDiameter=[2.5,1]\n    fourthHoleOffset=[rm/2,-(package_height-leftbottom_offset[1])+secondHoleDiameter[1]/2]\n    fabref_offset=0\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"205-{0:05}\".format(296+p)\n        footprint_name=\"TerminalBlock_RND_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block RND {0}\".format(name)\n        webpage=\"http://cdn-reichelt.de/documents/datenblatt/C151/RND_205-00298_DB_EN.pdf\"\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n \n    \n    pins=range(2,12+1)\n    rm=5.08\n    package_height=8.45\n    leftbottom_offset=[2.54, 4.05]\n    ddrill=1.1\n    pad=[2.1,2.1]\n    screw_diameter=2.5\n    bevel_height=[0.5,1.6,package_height-1.85]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=[2.5,1]\n    secondHoleOffset=[0,-(package_height-leftbottom_offset[1])+secondHoleDiameter[1]/2]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    nibbleSize=[]#[0.6,1.2]\n    nibblePos=[]#[-nibbleSize[0],0.25]\n    fabref_offset=0\n    for p in pins:\n        name=\"205-{0:05}\".format(230+p)\n        footprint_name=\"TerminalBlock_RND_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block RND {0}\".format(name)\n        webpage=\"http://cdn-reichelt.de/documents/datenblatt/C151/RND_205-00232_DB_EN.pdf\"\n        makeTerminalBlockStd(footprint_name=footprint_name,\n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n    \n    pins=range(2,12+1)\n    rm=5\n    package_height=7.6\n    leftbottom_offset=[2.5, 3.5]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=3\n    bevel_height=[0.6,1.2,package_height-1.7]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=1.1\n    secondHoleOffset=[0,-3]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    nibbleSize=[]#[0.6,1.2]\n    nibblePos=[]#[-nibbleSize[0],0.25]\n    fabref_offset=0\n    for p in pins:\n        name=\"205-{0:05}\".format(10+p)\n        footprint_name=\"TerminalBlock_RND_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block RND {0}\".format(name)\n        webpage=\"http://cdn-reichelt.de/documents/datenblatt/C151/RND_205-00012_DB_EN.pdf\"\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n                                  \n    pins=range(2,12+1)\n    rm=10.16\n    package_height=8.3\n    leftbottom_offset=[2.54, 4.55]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=3\n    bevel_height=[0.6, 1.2, package_height-1.5]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=[2.5,1]\n    secondHoleOffset=[0,-(package_height-leftbottom_offset[1])+secondHoleDiameter[1]/2]\n    thirdHoleDiameter=screw_diameter\n    thirdHoleOffset=[rm/2,0]\n    fourthHoleDiameter=secondHoleDiameter\n    fourthHoleOffset=[rm/2,secondHoleOffset[1]]\n    fabref_offset=0 #[0,2.5]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"205-{0:05}\".format(239+p)\n        footprint_name=\"TerminalBlock_RND_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block RND {0}\".format(name)\n        webpage=\"http://cdn-reichelt.de/documents/datenblatt/C151/RND_205-00023_DB_EN.pdf\"\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n    pins=range(2,12+1)\n    rm=5\n    package_height=9\n    leftbottom_offset=[2.5, 4]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=3\n    bevel_height=[1.5]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=1.8\n    secondHoleOffset=[0,-3]\n    thirdHoleDiameter=0\n    thirdHoleOffset=[0,0]\n    fourthHoleDiameter=0\n    fourthHoleOffset=[0,0]\n    fabref_offset=0 #[0,3.8]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"205-{0:05}\".format(p-1)\n        footprint_name=\"TerminalBlock_RND_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block RND {0}\".format(name)\n        webpage=\"http://cdn-reichelt.de/documents/datenblatt/C151/RND_205-00001_DB_EN.pdf\"\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n\n                                  \n    pins=range(2,12+1)\n    rm=10\n    package_height=9\n    leftbottom_offset=[2.5, 4]\n    ddrill=1.3\n    pad=[2.5,2.5]\n    screw_diameter=3\n    bevel_height=[1.5]\n    slit_screw=True\n    screw_pin_offset=[0,0]\n    secondHoleDiameter=1.8\n    secondHoleOffset=[0,-3]\n    thirdHoleDiameter=screw_diameter\n    thirdHoleOffset=[rm/2,0]\n    fourthHoleDiameter=1.8\n    fourthHoleOffset=[rm/2,-3]\n    fabref_offset=[0,3.8]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"205-{0:05}\".format(21+p)\n        footprint_name=\"TerminalBlock_RND_{0}_1x{2:02}_P{1:3.2f}mm_Horizontal\".format(name, rm, p)\n        classname_description=\"terminal block RND {0}\".format(name)\n        webpage=\"http://cdn-reichelt.de/documents/datenblatt/C151/RND_205-00023_DB_EN.pdf\"\n        makeTerminalBlockStd(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, screw_diameter=screw_diameter, bevel_height=bevel_height, slit_screw=slit_screw, screw_pin_offset=screw_pin_offset, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name='${KISYS3DMOD}/'+classname, classname=classname, classname_description=classname_description, \n                                  webpage=webpage, script_generated_note=script_generated_note)\n"
  },
  {
    "path": "scripts/TerminalBlock_TE-Connectivity/make_TerminalBlock_TE-Connectivity.py",
    "content": "#!/usr/bin/env python\n\nfrom __future__ import division\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_terminal_blocks import *\n\n\nif __name__ == '__main__':\n    script_generated_note = (\"script-generated using https://github.com\"\n            \"/pointhi/kicad-footprint-generator/scripts/TerminalBlock_TE-Connectivity\")\n    long_classname = \"TerminalBlock_TE-Connectivity\"\n    classname = \"TerminalBlock_TE\"\n\n    pins = range(2,12+1)\n    rm = 2.54\n    package_height = 6.5\n    leftbottom_offset = [1.5, 3.25]\n    ddrill = 1.1\n    pad = [2.1,2.1]\n    screw_diameter = 2.2\n    bevel_height = [0.4,5.5]\n    slit_screw = True\n    screw_pin_offset = [0,0]\n    secondDrillDiameter = 0\n    secondDrillOffset = [0,2.54]\n    secondDrillPad = [0,0]\n    secondHoleDiameter = 0\n    secondHoleOffset = [0,0]\n    thirdHoleDiameter = 0\n    thirdHoleOffset = [0,-4]\n    fourthHoleDiameter = 0\n    fourthHoleOffset = [0,0]\n    fabref_offset = [0,2.0]\n    nibbleSize = []\n    nibblePos = []\n    for p in pins:\n        name_prefix = \"{}-\".format(p // 10) if p // 10 > 0 else \"\"\n        name = \"{}282834-{}\".format(name_prefix, p % 10)\n        webpage = (\"http://www.te.com/commerce/DocumentDelivery/DDEController\"\n                \"?Action=showdoc&DocId=Customer+Drawing%7F282834%7FC1%7Fpdf\"\n                \"%7FEnglish%7FENG_CD_282834_C1.pdf\")\n        classname_description = \"Terminal Block TE {0}\".format(name)\n        footprint_name = \"{}_{}_1x{:02}_P{:3.2f}mm_Horizontal\".format(\n                classname, name, p, rm)\n        makeTerminalBlockStd(footprint_name=footprint_name,\n                pins=p,\n                rm=rm, \n                package_height=package_height,\n                leftbottom_offset=leftbottom_offset, \n                ddrill=ddrill,\n                pad=pad,\n                screw_diameter=screw_diameter,\n                bevel_height=bevel_height,\n                slit_screw=slit_screw,\n                screw_pin_offset=screw_pin_offset,\n                secondHoleDiameter=secondHoleDiameter,\n                secondHoleOffset=secondHoleOffset,\n                thirdHoleDiameter=thirdHoleDiameter,\n                thirdHoleOffset=thirdHoleOffset,\n                fourthHoleDiameter=fourthHoleDiameter,\n                fourthHoleOffset=fourthHoleOffset, \n                secondDrillDiameter=secondDrillDiameter,\n                secondDrillOffset=secondDrillOffset,\n                secondDrillPad=secondDrillPad,\n                nibbleSize=nibbleSize,\n                nibblePos=nibblePos,\n                fabref_offset=fabref_offset,\n                tags_additional=[],\n                lib_name='${KISYS3DMOD}/'+long_classname,\n                classname=classname,\n                classname_description=classname_description,\n                webpage=webpage,\n                script_generated_note=script_generated_note)\n"
  },
  {
    "path": "scripts/TerminalBlock_WAGO/make_TerminalBlock_WAGO.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_terminal_blocks import *\n\n\n\n\n\nif __name__ == '__main__':\n\n    script_generated_note=\"script-generated using https://github.com/pointhi/kicad-footprint-generator/scripts/TerminalBlock_WAGO\";\n    classname=\"TerminalBlock_WAGO\"\n    \n    \n\n   \n    \n    pins=[1,2,3,4,5,6,7,8,9,10,12,16,24]\n    rm=7.5\n    package_height=15\n    leftbottom_offset=[2.75, 6.7, 3.75]\n    ddrill=1.2\n    pad=[2,3]\n    screw_diameter=2.2\n    bevel_height=[2.9]\n    vsegment_lines_offset=[-1.25]\n    opening=[2.9,2.3]\n    opening_xoffset=1.25\n    opening_yoffset=1.45\n    opening_elliptic=True\n    secondDrillDiameter=ddrill\n    secondDrillOffset=[2.5,-5]\n    secondDrillPad=pad\n    secondHoleDiameter=[4,4.4]\n    secondHoleOffset=[1.25,0]\n    thirdHoleDiameter=[4,1]\n    thirdHoleOffset=[1.25,0]\n    fourthHoleDiameter=3#4\n    fourthHoleOffset=[1.25,-5.75]\n    fifthHoleDiameter=0\n    fifthHoleOffset=[2.5,-0.75]\n    secondEllipseSize=[0,0]\n    secondEllipseOffset=[1.25,2.5]\n    fabref_offset=[0,-1]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"804-{0}\".format(300+p);\n        webpage=\"\";\n        classname_description=\"Terminal Block WAGO {0}\".format(name);\n        footprint_name=\"TerminalBlock_WAGO_{0}_1x{2:02}_P{1:3.2f}mm_45Degree\".format(name, rm, p)\n        makeTerminalBlock45Degree(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, vsegment_lines_offset=vsegment_lines_offset,\n                                  opening=opening, opening_xoffset=opening_xoffset, opening_yoffset=opening_yoffset, opening_elliptic=opening_elliptic,\n                                  bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, fifthHoleDiameter=fifthHoleDiameter,fifthHoleOffset=fifthHoleOffset,\n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  secondEllipseSize=secondEllipseSize,secondEllipseOffset=secondEllipseOffset,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n\n     \n     \n\n    \n    pins=[1,2,3,4,5,6,7,8,9,10,12,16,24]\n    rm=5\n    package_height=15\n    leftbottom_offset=[2.75, 6.7, 3.75]\n    ddrill=1.2\n    pad=[2,3]\n    screw_diameter=2.2\n    bevel_height=[2.9]\n    vsegment_lines_offset=[-1.25]\n    opening=[2.9,2.3]\n    opening_xoffset=1.25\n    opening_yoffset=1.45\n    opening_elliptic=True\n    secondDrillDiameter=ddrill\n    secondDrillOffset=[2.5,-5]\n    secondDrillPad=pad\n    secondHoleDiameter=[4,4.4]\n    secondHoleOffset=[1.25,0]\n    thirdHoleDiameter=[4,1]\n    thirdHoleOffset=[1.25,0]\n    fourthHoleDiameter=3#4\n    fourthHoleOffset=[1.25,-5.75]\n    fifthHoleDiameter=0\n    fifthHoleOffset=[1.25,-0.75]\n    secondEllipseSize=[0,0]\n    secondEllipseOffset=[1.25,2.5]\n    fabref_offset=[0,-1]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"804-{0}\".format(100+p);\n        webpage=\"\";\n        classname_description=\"Terminal Block WAGO {0}\".format(name);\n        footprint_name=\"TerminalBlock_WAGO_{0}_1x{2:02}_P{1:3.2f}mm_45Degree\".format(name, rm, p)\n        makeTerminalBlock45Degree(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad,  vsegment_lines_offset=vsegment_lines_offset,\n                                  opening=opening, opening_xoffset=opening_xoffset, opening_yoffset=opening_yoffset, opening_elliptic=opening_elliptic,\n                                  bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, fifthHoleDiameter=fifthHoleDiameter,fifthHoleOffset=fifthHoleOffset,\n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  secondEllipseSize=secondEllipseSize,secondEllipseOffset=secondEllipseOffset,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n\n\n    pins=[1,2,3,4,6,8,12,16,24,36,48]\n    rm=5\n    package_height=14\n    leftbottom_offset=[3.5, 9, 3.8]\n    ddrill=1.15\n    pad=[1.5,3]\n    screw_diameter=2.2\n    bevel_height=[1,6.7,9.5]\n    opening=[4,3.3]\n    opening_xoffset=0.5\n    opening_yoffset=1.3#package_height-leftbottom_offset[1]-opening[1]/2\n    secondDrillDiameter=ddrill\n    secondDrillOffset=[0,5]\n    secondDrillPad=pad\n    secondHoleDiameter=[5,14]\n    secondHoleOffset=[0.5,2]\n    thirdHoleDiameter=[4,1]\n    thirdHoleOffset=[0.5,3.2]\n    fourthHoleDiameter=[1,2.5]\n    fourthHoleOffset=[0.5,-3.4]\n    fabref_offset=[0,-1]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"236-{0}\".format(100+p);\n        webpage=\"\";\n        classname_description=\"Terminal Block WAGO {0}\".format(name);\n        footprint_name=\"TerminalBlock_WAGO_{0}_1x{2:02}_P{1:3.2f}mm_45Degree\".format(name, rm, p)\n        makeTerminalBlock45Degree(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, \n                                  opening=opening, opening_xoffset=opening_xoffset, opening_yoffset=opening_yoffset, \n                                  bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n        name=\"236-{0}\".format(400+p);\n        webpage=\"\";\n        classname_description=\"Terminal Block WAGO {0}\".format(name);\n        footprint_name=\"TerminalBlock_WAGO_{0}_1x{2:02}_P{1:3.2f}mm_45Degree\".format(name, rm, p)\n        makeTerminalBlock45Degree(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, \n                                  opening=opening, opening_xoffset=opening_xoffset, opening_yoffset=opening_yoffset, \n                                  bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n\n    pins=[1,2,3,4,6,8,12,16,24]\n    rm=7.5\n    package_height=14\n    leftbottom_offset=[3.5, 9, 6.3]\n    ddrill=1.15\n    pad=[1.5,3]\n    screw_diameter=2.2\n    bevel_height=[1,6.7,9.5]\n    opening=[4,3.3]\n    opening_xoffset=0.5\n    opening_yoffset=1.3#package_height-leftbottom_offset[1]-opening[1]/2\n    secondDrillDiameter=ddrill\n    secondDrillOffset=[0,5]\n    secondDrillPad=pad\n    secondHoleDiameter=[rm,package_height]\n    secondHoleOffset=[1.75,2]\n    thirdHoleDiameter=[4,1]\n    thirdHoleOffset=[0.5,3.2]\n    fourthHoleDiameter=1,2.5\n    fourthHoleOffset=[0.5,-3.4]\n    fabref_offset=[0,-1]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"236-{0}\".format(200+p);\n        webpage=\"\";\n        classname_description=\"Terminal Block WAGO {0}\".format(name);\n        footprint_name=\"TerminalBlock_WAGO_{0}_1x{2:02}_P{1:3.2f}mm_45Degree\".format(name, rm, p)\n        makeTerminalBlock45Degree(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, \n                                  opening=opening, opening_xoffset=opening_xoffset, opening_yoffset=opening_yoffset, \n                                  bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n        name=\"236-{0}\".format(500+p);\n        webpage=\"\";\n        classname_description=\"Terminal Block WAGO {0}\".format(name);\n        footprint_name=\"TerminalBlock_WAGO_{0}_1x{2:02}_P{1:3.2f}mm_45Degree\".format(name, rm, p)\n        makeTerminalBlock45Degree(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, \n                                  opening=opening, opening_xoffset=opening_xoffset, opening_yoffset=opening_yoffset, \n                                  bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n\n    pins=[1,2,3,4,6,8,12,16,24]\n    rm=10\n    package_height=14\n    leftbottom_offset=[3.5, 9, 8.8]\n    ddrill=1.15\n    pad=[1.5,3]\n    screw_diameter=2.2\n    bevel_height=[1,6.7,9.5]\n    opening=[4,3.3]\n    opening_xoffset=0.5\n    opening_yoffset=1.3#package_height-leftbottom_offset[1]-opening[1]/2\n    secondDrillDiameter=ddrill\n    secondDrillOffset=[0,5]\n    secondDrillPad=pad\n    secondHoleDiameter=[rm,package_height]\n    secondHoleOffset=[3,2]\n    thirdHoleDiameter=[4,1]\n    thirdHoleOffset=[0.5,3.2]\n    fourthHoleDiameter=1,2.5\n    fourthHoleOffset=[0.5,-3.4]\n    fabref_offset=[0,-1]\n    nibbleSize=[]\n    nibblePos=[]\n    for p in pins:\n        name=\"236-{0}\".format(300+p);\n        webpage=\"\";\n        classname_description=\"Terminal Block WAGO {0}\".format(name);\n        footprint_name=\"TerminalBlock_WAGO_{0}_1x{2:02}_P{1:3.2f}mm_45Degree\".format(name, rm, p)\n        makeTerminalBlock45Degree(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, \n                                  opening=opening, opening_xoffset=opening_xoffset, opening_yoffset=opening_yoffset, \n                                  bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n        name=\"236-{0}\".format(600+p);\n        webpage=\"\";\n        classname_description=\"Terminal Block WAGO {0}\".format(name);\n        footprint_name=\"TerminalBlock_WAGO_{0}_1x{2:02}_P{1:3.2f}mm_45Degree\".format(name, rm, p)\n        makeTerminalBlock45Degree(footprint_name=footprint_name, \n                                  pins=p, rm=rm, \n                                  package_height=package_height, leftbottom_offset=leftbottom_offset, \n                                  ddrill=ddrill, pad=pad, \n                                  opening=opening, opening_xoffset=opening_xoffset, opening_yoffset=opening_yoffset, \n                                  bevel_height=bevel_height, secondHoleDiameter=secondHoleDiameter, secondHoleOffset=secondHoleOffset, thirdHoleDiameter=thirdHoleDiameter, thirdHoleOffset=thirdHoleOffset, fourthHoleDiameter=fourthHoleDiameter, fourthHoleOffset=fourthHoleOffset, \n                                  secondDrillDiameter=secondDrillDiameter,secondDrillOffset=secondDrillOffset,secondDrillPad=secondDrillPad,\n                                  nibbleSize=nibbleSize, nibblePos=nibblePos, fabref_offset=fabref_offset,\n                                  tags_additional=[], lib_name=\"${KISYS3DMOD}/\"+classname, classname=classname, classname_description=classname_description, webpage=webpage, script_generated_note=script_generated_note)\n"
  },
  {
    "path": "scripts/Vigortronix/vigotronix.py",
    "content": "#!/usr/bin/env python\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\n\n\n#sizes,shapes,etc]\n#prefix, serie, Type, W, L, H, PDiam, pin1x, pin1y, pin2x, pin2y, pin3x, pin3y, pin4x, pin4y\nconverters = [\n    [\"ACDC-Conv_Vigortronix\", \"VTX-214-010-XXX\",            0,   56.0, 36.0, 25.5,   1.5,   0, 0,   12, 0,    0, 48,    5, 48 ],\n    [\"ACDC-Conv_Vigortronix\", \"VTX-214-010-XXX_Miniature\",  0,   45.5, 30.0, 24.0,   1.5,   0, 0,   12, 0,   12, 39,    5, 39,],\n]\n\nimport sys\nimport os\nimport math\n\noutput_dir = os.getcwd()\n\n#if specified as an argument, extract the target directory for output footprints\nif len(sys.argv) > 1:\n    out_dir = sys.argv[1]\n    \n    if os.path.isabs(out_dir) and os.path.isdir(out_dir):\n        output_dir = out_dir\n    else:\n        out_dir = os.path.join(os.getcwd(),out_dir)\n        if os.path.isdir(out_dir):\n            output_dir = out_dir\n\nif output_dir and not output_dir.endswith(os.sep):\n    output_dir += os.sep\n        \n#import KicadModTree files\nsys.path.append(\"..\\\\..\")\nfrom KicadModTree import *\nfrom KicadModTree.nodes.specialized.PadArray import PadArray\n\n\n\nfor converter in converters:\n    prefix,Serie,Type,W,L,H,PDiam,pin1x, pin1y, pin2x, pin2y, pin3x, pin3y, pin4x, pin4y=converter\n\n    if Type == 0:\n\n        desc = \"Vigortronix \" + Serie + \" serie of ACDC converter\"\n        tags = \"Vigortronix \" + Serie + \" serie of ACDC converter\"\n        TargetDir = \"Converters_DCDC_ACDC.3dshapes\"\n        Datasheet = \"http://www.vigortronix.com/10WattACDCPCBPowerModule.aspx\"\n        PadSize = 2.0 * PDiam\n    \n        fp_name = prefix + \"_\" + Serie\n        fp = Footprint(fp_name)\n        description = desc + \", \" + Datasheet\n\n        x1 = 0\n        y1 = 0\n        x2 = 0\n        y2 = 0\n        #\n        # Add the component outline\n        #\n        # Top line\n        Layer = ['F.Fab', 'F.SilkS', 'F.CrtYd']\n        LayerW = [0.1, 0.12, 0.05]\n        LayerD = [0, 0.12, 0.25]\n        for i in range(0, 3):\n            myLayer = Layer[i]\n            myLayerW = LayerW[i]\n            myLayerD = LayerD[i]\n            #\n            # Top line\n            if (i == 0):\n                x1 = 0 - ((L - (pin2x - pin1x)) / 2.0) - myLayerD\n                y1 = 0 - ((W - (pin3y - pin1y)) / 2.0) - myLayerD\n                x2 = -1\n                y2 = y1\n                fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n                #\n                x1 = x2;\n                y1 = y2\n                x2 = 0\n                y2 = y1 + 1\n                fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n                #\n                x1 = x2;\n                y1 = y2\n                x2 = 1\n                y2 = y1 - 1\n                fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n                #\n                x1 = x2;\n                y1 = y2\n                x2 = L - ((L - (pin2x - pin1x)) / 2.0) + myLayerD\n                y2 = y1\n                fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n                #\n            else:\n                x1 = 0 - ((L - (pin2x - pin1x)) / 2.0) - myLayerD\n                y1 = 0 - ((W - (pin3y - pin1y)) / 2.0) - myLayerD\n                x2 = L - ((L - (pin2x - pin1x)) / 2.0) + myLayerD\n                y2 = y1\n                fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n            #\n            # Right Line\n            #\n            x1 = x2\n            y1 = y2\n            x2 = x1\n            y2 = W - ((W - (pin3y - pin1y)) / 2.0) + myLayerD\n            fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n            #\n            # Bottom Line\n            #\n            x1 = x2\n            y1 = y2\n            x2 = 0 - ((L - (pin2x - pin1x)) / 2.0) - myLayerD\n            y2 = y2\n            fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n            #\n            # Left Line\n            #\n            x1 = x2\n            y1 = y2\n            x2 = 0 - ((L - (pin2x - pin1x)) / 2.0) - myLayerD\n            y2 = 0 - ((W - (pin3y - pin1y)) / 2.0) - myLayerD\n            fp.append(Line(start=[round(x1, 2), round(y1, 2)],end=[round(x2, 2), round(y2, 2)],layer=myLayer,width=myLayerW))\n            #\n            #\n            # Add holes\n            #\n            if (i == 0):\n                fp.append(Pad(number=1,at=[pin1x, pin1y], layers=Pad.LAYERS_THT, shape=Pad.SHAPE_RECT,   type=Pad.TYPE_THT,  size=[PadSize,PadSize], drill=round(PDiam, 2)))\n                fp.append(Pad(number=2,at=[pin2x, pin2y], layers=Pad.LAYERS_THT, shape=Pad.SHAPE_CIRCLE, type=Pad.TYPE_THT,  size=[PadSize,PadSize], drill=round(PDiam, 2)))\n                fp.append(Pad(number=3,at=[pin3x, pin3y], layers=Pad.LAYERS_THT, shape=Pad.SHAPE_CIRCLE, type=Pad.TYPE_THT,  size=[PadSize,PadSize], drill=round(PDiam, 2)))\n                fp.append(Pad(number=4,at=[pin4x, pin4y], layers=Pad.LAYERS_THT, shape=Pad.SHAPE_CIRCLE, type=Pad.TYPE_THT,  size=[PadSize,PadSize], drill=round(PDiam, 2)))\n\n    fp.setTags(tags)\n    fp.setDescription(description)\n    #\n    # Set general values\n    #\n    cx = 0 - ((L - (pin2x - pin1x)) / 2.0) + 2\n    cy = 0 - ((W - (pin3y - pin1y)) / 2.0) - 1.5\n    fp.append(Text(type='reference', text='REF**', at=[round(cx, 2), round(cy, 2)], layer='F.SilkS'))\n    #\n    cx = (pin2x - pin1x) / 2.0\n    cy = ((pin3y - pin1y)) - ((L - (pin3y - pin1y)) / 2.0)\n    fp.append(Text(type='value', text=fp_name,     at=[round(cx, 2), round(cy, 2)], layer='F.Fab'))\n    #\n    cx = (L / 2.0) + (0 - ((L - (pin2x - pin1x)) / 2.0) - myLayerD)\n    cy = (pin3y - pin1y) / 2.0\n    fp.append(Text(type='user', text=\"%R\",         at=[round(cx, 2), round(cy, 2)], layer='F.Fab'))\n    \n    #\n    # Add 3D model\n    #\n    fp.append(Model(filename=\"${KISYS3DMOD}/\" + TargetDir + \"/\" + fp_name + \".wrl\", at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n    \n\n    #filename\n    filename = output_dir + fp_name + \".kicad_mod\"\n    \n    file_handler = KicadFileHandler(fp)\n    file_handler.writeFile(filename)\n    "
  },
  {
    "path": "scripts/example_kicadmodtree_script.py",
    "content": "#!/usr/bin/env python\n\n'''\nkicad-footprint-generator is free software: you can redistribute it and/or\nmodify it under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nkicad-footprint-generator is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\n'''\n\nimport sys\nimport os\nsys.path.append(os.path.join(sys.path[0],\"..\"))\n#sys.path.append('../..') # enable package import from parent directory\n\nfrom KicadModTree import *\nfrom KicadModTree.nodes.specialized.PadArray import PadArray\n\nif __name__ == '__main__':\n    footprint_name = \"example_footprint\"\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(\"A example footprint\")\n    kicad_mod.setTags(\"example\")\n\n    # set general values\n    kicad_mod.append(Text(type='reference', text='REF**', at=[0,-3], layer='F.SilkS'))\n    kicad_mod.append(Text(type='value', text=footprint_name, at=[1.5,3], layer='F.Fab'))\n\n    # create silscreen\n    kicad_mod.append(RectLine(start=[-2,-2], end=[5,2], layer='F.SilkS', width=0.15))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[-2.25,-2.25], end=[5.25,2.25], layer='F.CrtYd', width=0.05, offset=2))\n\n    # create pads\n    kicad_mod.append(Pad(number=7, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=[0,0], size=[2,2], drill=1.2, layers=['*.Cu', '*.Mask', 'F.SilkS']))\n    kicad_mod.append(Pad(number=22, type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, at=[3,0], size=[2,2], drill=1.2, layers=['*.Cu', '*.Mask', 'F.SilkS']))\n    \n    kicad_mod.append(Pad(number=12, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, at=[3,0], size=[2,2], drill=1.2, layers=['*.Cu', '*.Mask', 'F.SilkS']))\n\n    # add model\n    kicad_mod.append(Model(filename=\"example.3dshapes/example_footprint.wrl\"\n                          ,at=[0,0,0]\n                          ,scale=[1,1,1]\n                          ,rotate=[0,0,0]))\n    \n    kicad_mod.append(PadArray(pincount=10,spacing=[1,-1],center=[0,0], initial=5, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[1,2], layers=[\"*.Cu\"]))\n                          \n    # output kicad model\n    #print(kicad_mod)\n\n    # print render tree\n    #print(kicad_mod.getRenderTree())\n    #print(kicad_mod.getCompleteRenderTree())\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('example_footprint.kicad_mod')\n\n    \n    "
  },
  {
    "path": "scripts/general/StandardBox.py",
    "content": "# KicadModTree is free software: you can redistribute it and/or\r\n# modify it under the terms of the GNU General Public License as published by\r\n# the Free Software Foundation, either version 3 of the License, or\r\n# (at your option) any later version.\r\n#\r\n# KicadModTree is distributed in the hope that it will be useful,\r\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n# GNU General Public License for more details.\r\n#\r\n# You should have received a copy of the GNU General Public License\r\n# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.\r\n#\r\n# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>\r\n\r\n\r\n#\r\n# This module Create a standard box in various layers including a pin 1 marker tap or chamfer\r\n#\r\nfrom KicadModTree import *\r\nfrom KicadModTree.Point import *\r\nfrom KicadModTree.PolygonPoints import *\r\nfrom KicadModTree.nodes.Node import Node\r\nfrom KicadModTree.nodes.base.Line import Line\r\nfrom KicadModTree.nodes.base.Text import Text\r\n\r\n\r\nclass koaLine:\r\n\r\n    def __init__(self, sx, sy, ex, ey, layer, width):\r\n        self.sx = sx\r\n        self.sy = sy\r\n        self.ex = ex\r\n        self.ey = ey\r\n        self.k = 0.0\r\n        self.m = 0.0\r\n        self.l = 0.0\r\n        self.IsVertical = False\r\n        self.layer = layer\r\n        self.width = width\r\n\r\n        if ex != sx:\r\n            self.k = (ey - sy) / (ex - sx)\r\n            self.m = sy - (self.k * sx)\r\n        else:\r\n            self.IsVertical = True\r\n\r\n        #\r\n        # Get the line lenght\r\n        #\r\n        x1 = min(self.sx, self.ex)\r\n        x2 = max(self.sx, self.ex)\r\n        y1 = min(self.sy, self.ey)\r\n        y2 = max(self.sy, self.ey)\r\n\r\n        x1 = x2 - x1\r\n        y1 = y2 - y1\r\n\r\n        self.l = sqrt((x1 * x1) + (y1 * y1))\r\n\r\n\r\nclass StandardBox(Node):\r\n    r\"\"\"Add a Polygone Line to the render tree\r\n\r\n    :param \\**kwargs:\r\n        See below\r\n\r\n    :Keyword Arguments:\r\n        * *footprint* (``list(Point)``) --\r\n          The foot print\r\n        * *description* (``str``) --\r\n          The description\r\n        * *datasheet* (``str``) --\r\n          The url to the data sheet\r\n        * *at* (``Point``) --\r\n          Where is upper left corner, in cartesian cordinate system (minus y below x axis)\r\n        * *size* (``Point``) --\r\n          The width and height of the rectangle\r\n        * *tags* (``str``) --\r\n          A foot prints tag attribute\r\n        * *SmdTht* (``str``) --\r\n          A foot prints tht/smd attribute\r\n        * *extratexts* (``list(x, y, 'text', layer, sizex, sizey)``) --\r\n          A list of extra txts to be placed on the footprint\r\n        * *pins* (``list(type, number, x, y, sizex, sizey, drill)``) --\r\n          List of tht/smd/npth holes\r\n        * *file3Dname* (``str``) --\r\n          The path to the 3D model name\r\n\r\n    :Example:\r\n\r\n    #\r\n    # pycodestyle complain over long lines so the complete on is placed in a comment instead\r\n    #\r\n    # StandardBox(footprint=f, description=description, datasheet=datasheet, at=at, size=size, tags=fptag, SmdTht=SmdTht,\r\n    # extratexts=extratexts, pins=pins, file3Dname = \"${KISYS3DMOD}/\" + dir3D + \"/\" + footprint_name + \".wrl\")))\r\n    #\r\n    >>> from KicadModTree import *\r\n    >>> StandardBox(footprint=f, description=description, ....)\r\n    \"\"\"\r\n\r\n    def __init__(self, **kwargs):\r\n        Node.__init__(self)\r\n\r\n        #\r\n        self.virtual_childs = []\r\n        #\r\n        self._initPosition(**kwargs)\r\n        self._initSize(**kwargs)\r\n        self._initFootPrint(**kwargs)\r\n        #\r\n        #\r\n        #\r\n        self._initDesriptionNode(**kwargs)\r\n        self._initTagNode(**kwargs)\r\n        self._initAttributeNode(**kwargs)\r\n        self._initFile3DNameNode(**kwargs)\r\n        self._initExtraTextNode(**kwargs)\r\n\r\n        self.extraffablines = kwargs.get('extraffablines')\r\n        self.typeOfBox = str(kwargs.get('typeOfBox'))\r\n        self.pins = kwargs.get('pins')\r\n\r\n        #\r\n        # Create foot print parts\r\n        #\r\n        #\r\n        self._createPinsNode()\r\n        self._createFFabLine()\r\n        self._createPin1MarkerLine()\r\n        self._createFSilkSLine()\r\n        self._createFCrtYdLine()\r\n        #\r\n\r\n    def getVirtualChilds(self):\r\n        #\r\n        #\r\n        return self.virtual_childs\r\n\r\n    def _initPosition(self, **kwargs):\r\n        if not kwargs.get('at'):\r\n            raise KeyError('Upper left position not declared (like \"at: [0,0]\")')\r\n        self.at = Point2D(kwargs.get('at'))\r\n        self.at.y = 0.0 - self.at.y\r\n\r\n    def _initSize(self, **kwargs):\r\n        if not kwargs.get('size'):\r\n            raise KeyError('Size not declared (like \"size: [1,1]\")')\r\n        if type(kwargs.get('size')) in [int, float]:\r\n            # when the attribute is a simple number, use it for x and y\r\n            self.size = Point2D([kwargs.get('size'), kwargs.get('size')])\r\n        else:\r\n            size_original = kwargs.get('size')\r\n            self.corners = []\r\n            if len(size_original ) > 2:\r\n                self.corners = size_original[2:]\r\n            self.size = Point2D(size_original[0], size_original[1])\r\n\r\n    def _initFootPrint(self, **kwargs):\r\n        if not kwargs.get('footprint'):\r\n            raise KeyError('footprint node is missing')\r\n\r\n        self.footprint = kwargs.get('footprint')\r\n        #\r\n        self.footprint_name = self.footprint.name\r\n        #\r\n        self.FFabWidth = 0.10\r\n        self.FSilkSWidth = 0.12\r\n        self.FCrtYdWidth = 0.05\r\n        #\r\n        self.p1m = 3.0\r\n        self.REF_P_w = 1.0\r\n        self.REF_P_h = 1.0\r\n        #\r\n        if self.size.x < 8.0 or self.size.y < 8.0:\r\n            dd = self.size.y / 3.0\r\n            if self.size.x < self.size.y:\r\n                dd = self.size.x / 3.0\r\n\r\n            self.p1m = dd\r\n            if dd < self.REF_P_w:\r\n                self.REF_P_w = dd\r\n                self.REF_P_h = self.REF_P_w\r\n\r\n        new_node = Text(type='user', text='%R', at=[self.at.x + (self.size.x / 2.0),\r\n                        self.at.y + (self.size.y / 2.0)], layer='F.Fab', size=[self.REF_P_w, self.REF_P_h])\r\n        new_node._parent = self\r\n        self.virtual_childs.append(new_node)\r\n        #\r\n        #\r\n        new_node = Text(type='reference', text='REF**', at=[self.at.x + 2.5, self.at.y - 1.2], layer='F.SilkS')\r\n        new_node._parent = self\r\n        self.virtual_childs.append(new_node)\r\n        #\r\n        #\r\n        new_node = Text(type=\"value\", text=self.footprint_name,\r\n                        at=[self.at.x + (self.size.x / 2.0), self.at.y + self.size.y + 1.0], layer=\"F.Fab\")\r\n        new_node._parent = self\r\n        self.virtual_childs.append(new_node)\r\n\r\n    def _initDesriptionNode(self, **kwargs):\r\n        if not kwargs.get('description'):\r\n            raise KeyError('Description not declared (like description: \"Bul Holder )')\r\n        if not kwargs.get('datasheet'):\r\n            raise KeyError('datasheet not declared (like datasheet: http://www.bulgin.com/media/bulgin/data/Battery_holders.pdf)')\r\n        self.description = str(kwargs.get('description')) + \" (Script generated with StandardBox.py) (\" + str(kwargs.get('datasheet')) + \")\"\r\n        self.footprint.setDescription(self.description)\r\n\r\n    def _initTagNode(self, **kwargs):\r\n        if not kwargs.get('tags'):\r\n            raise KeyError('tags not declared (like \"tags: \"Bulgin Battery Holder, BX0033, Battery Type 1xPP3\")')\r\n        self.tags = str(kwargs.get('tags'))\r\n        self.footprint.setTags(self.tags)\r\n\r\n    def _initAttributeNode(self, **kwargs):\r\n        if kwargs.get('SmdTht'):\r\n            self.SmdTht = str(kwargs.get('SmdTht'))\r\n            if self.SmdTht == \"smd\":\r\n                self.footprint.setAttribute(\"smd\")\r\n\r\n    def _initFile3DNameNode(self, **kwargs):\r\n        if not kwargs.get('file3Dname'):\r\n            raise KeyError('file3Dname not declared')\r\n        self.file3Dname = str(kwargs.get('file3Dname'))\r\n        self.footprint.append(Model(filename=self.file3Dname,\r\n                                    at=[0.0, 0.0, 0.0],\r\n                                    scale=[1.0, 1.0, 1.0],\r\n                                    rotate=[0.0, 0.0, 0.0]))\r\n\r\n    def _initExtraTextNode(self, **kwargs):\r\n        if kwargs.get('extratexts'):\r\n            self.extratexts = kwargs.get('extratexts')\r\n            #\r\n            for n in self.extratexts:\r\n                at = [n[0], 0.0-n[1]]\r\n                stss = n[2]\r\n                new_node = Text(type=\"user\", text=stss, at=at)\r\n                #\r\n                if len(n) > 3:\r\n                    new_node.layer = n[3]\r\n                if len(n) > 5:\r\n                    new_node.size = Point2D([n[4], n[5]])\r\n                new_node._parent = self\r\n                self.virtual_childs.append(new_node)\r\n\r\n    def _createFFabLine(self):\r\n        ffabline = []\r\n        self.boxffabline = []\r\n        #\r\n        #\r\n        x = self.at.x\r\n        y = self.at.y\r\n        w = self.size.x\r\n        h = self.size.y\r\n        self.boxffabline.append(koaLine(x, y, x + w, y, 'F.Fab', self.FFabWidth))\r\n        self.boxffabline.append(koaLine(x + w, y, x + w, y + h, 'F.Fab', self.FFabWidth))\r\n        self.boxffabline.append(koaLine(x + w, y + h, x, y + h, 'F.Fab', self.FFabWidth))\r\n        self.boxffabline.append(koaLine(x, y + h, x, y, 'F.Fab', self.FFabWidth))\r\n        #\r\n        # Add a chamfer\r\n        #\r\n        dd = w * 0.25\r\n        if dd > 1.0:\r\n            dd = 1.0\r\n        if w < 2.0:\r\n            dd = w / 3.0\r\n        if h < 2.0:\r\n            dd = h / 3.0\r\n        #\r\n        #\r\n        x0 = x + dd\r\n        y0 = y\r\n        x9 = x0\r\n        y9 = y0\r\n        #\r\n        x1 = x + w\r\n        y1 = y\r\n        x2 = x1\r\n        y2 = y1\r\n        #\r\n        x3 = x + w\r\n        y3 = y + h\r\n        x4 = x3\r\n        y4 = y3\r\n        #\r\n        x5 = x\r\n        y5 = y + h\r\n        x6 = x5\r\n        y6 = y5\r\n        #\r\n        x7 = x\r\n        y7 = y + dd\r\n        x8 = x7\r\n        y8 = y7\r\n        #\r\n        #\r\n        for nn in self.corners:\r\n\r\n            if nn[0] == 'ULP':\r\n                x0 = x + nn[1]\r\n                x9 = x0\r\n                y8 = y + nn[2]\r\n                y9 = y8\r\n                y7 = y8\r\n                new_node = Line(start=Point2D(x9, y9), end=Point2D(x0, y0), layer='F.Fab', width=self.FFabWidth)\r\n                new_node._parent = self\r\n                self.virtual_childs.append(new_node)\r\n\r\n            if nn[0] == 'ULR':\r\n                x0 = x + nn[1]\r\n                y7 = y + nn[1]\r\n                x8 = x7\r\n                x9 = x7\r\n                y8 = y7\r\n                y9 = y7\r\n                new_node = Arc(center=Point2D(x0, y7), start=Point2D(x7, y7), layer='F.Fab', width=self.FFabWidth, angle=90.0)\r\n                new_node._parent = self\r\n                self.virtual_childs.append(new_node)\r\n                \r\n                \r\n            if nn[0] == 'URP':\r\n                x1 = (x + w) - nn[1]\r\n                y2 = y + nn[2]\r\n                new_node = Line(start=Point2D(x1, y1), end=Point2D(x1, y2), layer='F.Fab', width=self.FFabWidth)\r\n                new_node._parent = self\r\n                self.virtual_childs.append(new_node)\r\n                #\r\n                new_node = Line(start=Point2D(x1, y2), end=Point2D(x2, y2), layer='F.Fab', width=self.FFabWidth)\r\n                new_node._parent = self\r\n                self.virtual_childs.append(new_node)\r\n\r\n            if nn[0] == 'URR':\r\n                x1 = (x + w) - nn[1]\r\n                y2 = y + nn[1]\r\n                new_node = Arc(center=Point2D(x1, y2), start=Point2D(x1, y1), layer='F.Fab', width=self.FFabWidth, angle=90.0)\r\n                new_node._parent = self\r\n                self.virtual_childs.append(new_node)\r\n                \r\n            if nn[0] == 'LRP':\r\n                x4 = (x + w) - nn[1]\r\n                y3 = (y + h) - nn[1]\r\n                new_node = Line(start=Point2D(x3, y3), end=Point2D(x4, y3), layer='F.Fab', width=self.FFabWidth)\r\n                new_node._parent = self\r\n                self.virtual_childs.append(new_node)\r\n                #\r\n                new_node = Line(start=Point2D(x4, y3), end=Point2D(x4, y4), layer='F.Fab', width=self.FFabWidth)\r\n                new_node._parent = self\r\n                self.virtual_childs.append(new_node)\r\n\r\n            if nn[0] == 'LRR':\r\n                x4 = (x + w) - nn[1]\r\n                y3 = (y + h) - nn[1]\r\n                new_node = Arc(center=Point2D(x4, y3), start=Point2D(x3, y3), layer='F.Fab', width=self.FFabWidth, angle=90.0)\r\n                new_node._parent = self\r\n                self.virtual_childs.append(new_node)\r\n                \r\n            if nn[0] == 'LLR':\r\n                x5 = x + nn[1]\r\n                y6 = (y + h) - nn[1]\r\n                new_node = Arc(center=Point2D(x5, y6), start=Point2D(x5, y5), layer='F.Fab', width=self.FFabWidth, angle=90.0)\r\n                new_node._parent = self\r\n                self.virtual_childs.append(new_node)\r\n\r\n            if nn[0] == 'LLP':\r\n                x5 = x + nn[1]\r\n                y6 = (y + h) - nn[2]\r\n                new_node = Line(start=Point2D(x5, y5), end=Point2D(x5, y6), layer='F.Fab', width=self.FFabWidth)\r\n                new_node._parent = self\r\n                self.virtual_childs.append(new_node)\r\n                #\r\n                new_node = Line(start=Point2D(x5, y6), end=Point2D(x6, y6), layer='F.Fab', width=self.FFabWidth)\r\n                new_node._parent = self\r\n                self.virtual_childs.append(new_node)\r\n\r\n        ffabline.append(koaLine(x0, y0, x1, y1, 'F.Fab', self.FFabWidth))\r\n        ffabline.append(koaLine(x2, y2, x3, y3, 'F.Fab', self.FFabWidth))\r\n        ffabline.append(koaLine(x4, y4, x5, y5, 'F.Fab', self.FFabWidth))\r\n        ffabline.append(koaLine(x6, y6, x7, y7, 'F.Fab', self.FFabWidth))\r\n        ffabline.append(koaLine(x8, y8, x9, y9, 'F.Fab', self.FFabWidth))\r\n        #\r\n        #\r\n        for n in ffabline:\r\n            new_node = Line(start=Point2D(round(n.sx, 2), round(n.sy, 2)), end=Point2D(round(n.ex, 2), round(n.ey, 2)), layer=n.layer, width=n.width)\r\n            if n.width < 0.0:\r\n                new_node = Line(start=Point2D(round(n.sx, 2), round(n.sy, 2)), end=Point2D(round(n.ex, 2), round(n.ey, 2)), layer=n.layer)\r\n            new_node._parent = self\r\n            self.virtual_childs.append(new_node)\r\n\r\n    def _createPin1MarkerLine(self):\r\n        #\r\n        # Add pin 1 marker line\r\n        #\r\n        x1 = self.at.x - 0.5\r\n        y1 = self.at.y - 0.5\r\n        #\r\n        new_node = Line(start=Point2D(round(x1, 2), round(y1 + self.p1m, 2)), end=Point2D(round(x1, 2), round(y1, 2)), layer='F.SilkS', width=self.FSilkSWidth)\r\n        new_node._parent = self\r\n        self.virtual_childs.append(new_node)\r\n        #\r\n        new_node = Line(start=Point2D(round(x1, 2), round(y1, 2)), end=Point2D(round(x1 + self.p1m, 2), round(y1, 2)), layer='F.SilkS', width=self.FSilkSWidth)\r\n        new_node._parent = self\r\n        self.virtual_childs.append(new_node)\r\n\r\n    def _createFSilkSLine(self):\r\n        self.fsilksline = []\r\n        #\r\n        #\r\n        #\r\n        # Check all holes and pads, if a pad or hole is on the silk line\r\n        # then jump over the pad/hole\r\n        #\r\n        for n in self.boxffabline:\r\n            x1 = min(n.sx, n.ex)\r\n            y1 = min(n.sy, n.ey)\r\n            x2 = max(n.sx, n.ex)\r\n            y2 = max(n.sy, n.ey)\r\n            #\r\n            #\r\n            if (x1 < 0.0 and y1 < 0.0 and y2 < 0.0) or (x1 < 0.0 and y1 > 0.0 and y2 > 0.0):\r\n                #\r\n                # Top and bottom line\r\n                #\r\n                x1_t = x1 - 0.12\r\n                x2_t = x2 + 0.12\r\n                x3_t = x1_t\r\n                x4_t = x2_t\r\n                #\r\n                if y1 < 0.0:\r\n                    # Top line\r\n                    y1_t = y1 - 0.12\r\n                    y2_t = y2 - 0.12\r\n                    y3_t = y1_t\r\n                    y4_t = y2_t\r\n                    #\r\n                    for nn in self.corners:\r\n                        if nn[0] == 'URR':\r\n                            x2_t = x2_t - (nn[1] + 0.12)\r\n                        if nn[0] == 'ULR':\r\n                            x1_t = x1_t + (nn[1] + 0.12)\r\n                        if nn[0] == 'ULP':\r\n                            x3_t = x1_t\r\n                            x1_t = x1_t + (nn[1])\r\n                            y3_t = y1_t + (nn[2])\r\n                        if nn[0] == 'URP':\r\n                            x4_t = x2_t\r\n                            x2_t = x2_t - (nn[1])\r\n                            y4_t = y1_t + (nn[2])\r\n                else:\r\n                    # Bottom line\r\n                    y1_t = y1 + 0.12\r\n                    y2_t = y2 + 0.12\r\n                    y3_t = y1_t\r\n                    y4_t = y2_t\r\n                    #\r\n                    for nn in self.corners:\r\n                        if nn[0] == 'LRR':\r\n                            x2_t = x2_t - (nn[1] + 0.12)\r\n                        if nn[0] == 'LLR':\r\n                            x1_t = x1_t + (nn[1] + 0.12)\r\n                        if nn[0] == 'LLP':\r\n                            x3_t = x1_t\r\n                            x1_t = x1_t + (nn[1])\r\n                            y3_t = y1_t - (nn[2])\r\n                        if nn[0] == 'LRP':\r\n                            x4_t = x2_t\r\n                            x2_t = x2_t - (nn[1])\r\n                            y4_t = y1_t - (nn[2])\r\n                    \r\n                #\r\n                EndLine = True\r\n                foundPad = False\r\n                UseCorner = True\r\n                while EndLine:\r\n                    px1 = 10000000.0\r\n                    px2 = 10000000.0\r\n                    foundPad = False\r\n                    for n in self.pad:\r\n                        n_min_x = n.at.x - (n.size.x / 2.0)\r\n                        n_min_y = n.at.y - (n.size.y / 2.0)\r\n                        n_max_x = n_min_x + n.size.x\r\n                        n_max_y = n_min_y + n.size.y\r\n                        dd = max(0.25, n.solder_mask_margin)\r\n\r\n                        if (n_min_y - 0.25) <= y1_t and (n_max_y + 0.25) > y1_t and n_max_x > x1_t and n_min_x < x2_t:\r\n                            #\r\n                            # This pad is in SilkS line's path\r\n                            #\r\n                            if n_min_x < px1:\r\n                                px1 = n_min_x\r\n                                px2 = n_max_x\r\n                                foundPad = True\r\n                    if foundPad:\r\n                        #\r\n                        # Found at least one pad that is in SilkS's line\r\n                        #\r\n                        if (px1 - 0.25) > x1_t:\r\n                            #\r\n                            # It does not cover the start point\r\n                            #\r\n                            self.fsilksline.append(koaLine(x1_t, y1_t, px1 - 0.25, y2_t, 'F.SilkS', self.FSilkSWidth))\r\n                        x1_t = px2 + 0.25\r\n                    else:\r\n                        #\r\n                        # No pads was in the way\r\n                        #\r\n                        if y1 < 0.0 and UseCorner:\r\n                            # Top line\r\n                            for nn in self.corners:\r\n                                if nn[0] == 'ULR':\r\n                                    urcdy0 = y1_t + (nn[1] + 0.12)\r\n                                    urcdx1 = x1_t - (nn[1] + 0.12)\r\n                                    new_node = Arc(center=Point2D(x1_t, urcdy0), start=Point2D(urcdx1, urcdy0), layer='F.SilkS', width=self.FSilkSWidth, angle=90.0)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    \r\n                                if nn[0] == 'ULP':\r\n                                    new_node = Line(start=Point2D(x1_t, y3_t), end=Point2D(x1_t, y1_t), layer='F.SilkS', width=self.FSilkSWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    new_node = Line(start=Point2D(x1_t, y3_t), end=Point2D(x3_t, y3_t), layer='F.SilkS', width=self.FSilkSWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    #\r\n                                if nn[0] == 'URP':\r\n                                    urcdy0 = y4_t + (nn[2])\r\n                                    new_node = Line(start=Point2D(x2_t, y4_t), end=Point2D(x2_t, y2_t), layer='F.SilkS', width=self.FSilkSWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    new_node = Line(start=Point2D(x2_t, y4_t), end=Point2D(x4_t, y4_t), layer='F.SilkS', width=self.FSilkSWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                            \r\n                        if y1 > 0.0 and UseCorner:\r\n                            # Bottom line\r\n                            for nn in self.corners:\r\n                                if nn[0] == 'LLR':\r\n                                    urcdy0 = y1_t - (nn[1] + 0.12)\r\n                                    new_node = Arc(center=Point2D(x1_t, urcdy0), start=Point2D(x1_t, y1_t), layer='F.SilkS', width=self.FSilkSWidth, angle=90.0)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    \r\n                                if nn[0] == 'LLP':\r\n                                    new_node = Line(start=Point2D(x1_t, y3_t), end=Point2D(x1_t, y1_t), layer='F.SilkS', width=self.FSilkSWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    new_node = Line(start=Point2D(x1_t, y3_t), end=Point2D(x3_t, y3_t), layer='F.SilkS', width=self.FSilkSWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    #\r\n                                if nn[0] == 'LRP':\r\n                                    urcdy0 = y4_t + (nn[2])\r\n                                    new_node = Line(start=Point2D(x2_t, y4_t), end=Point2D(x2_t, y2_t), layer='F.SilkS', width=self.FSilkSWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    new_node = Line(start=Point2D(x2_t, y4_t), end=Point2D(x4_t, y4_t), layer='F.SilkS', width=self.FSilkSWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                        #\r\n                        self.fsilksline.append(koaLine(x1_t, y1_t, x2_t, y2_t, 'F.SilkS', self.FSilkSWidth))\r\n                        EndLine = False\r\n\r\n                    if x1_t >= x2:\r\n                        EndLine = False\r\n                    \r\n                    UseCorner = False\r\n                    \r\n                if not foundPad and y1 < 0:\r\n                    # \r\n                    for nn in self.corners:\r\n                        if nn[0] == 'URR':\r\n                            urcdy1 = y1_t + (nn[1] + 0.12)\r\n                            new_node = Arc(center=Point2D(x2_t, urcdy1), start=Point2D(x2_t, y2_t), layer='F.SilkS', width=self.FSilkSWidth, angle=90.0)\r\n                            new_node._parent = self\r\n                            self.virtual_childs.append(new_node)\r\n                    \r\n                    \r\n                if not foundPad and y1 > 0:\r\n                    # \r\n                    for nn in self.corners:\r\n                        if nn[0] == 'LRR':\r\n                            urcdx1 = x2_t + (nn[1] + 0.12)\r\n                            urcdy1 = y2_t - (nn[1] + 0.12)\r\n                            new_node = Arc(center=Point2D(x2_t, urcdy1), start=Point2D(urcdx1, urcdy1), layer='F.SilkS', width=self.FSilkSWidth, angle=90.0)\r\n                            new_node._parent = self\r\n                            self.virtual_childs.append(new_node)\r\n                        \r\n            if (x1 < 0.0 and y1 < 0.0 and y2 > 0.0) or (x1 > 0.0 and y1 < 0.0 and y2 > 0.0):\r\n                #\r\n                # Left and right line\r\n                #\r\n                y1_t = y1 - 0.12\r\n                y2_t = y2 + 0.12\r\n                #\r\n                if x1 < 0.0:\r\n                    # Left line\r\n                    x1_t = min(x1 - 0.12, x2 - 0.12)\r\n                    x2_t = max(x1 - 0.12, x2 - 0.12)\r\n                    \r\n                    for nn in self.corners:\r\n                        if nn[0] == 'ULR':\r\n                            y1_t = y1_t + (nn[1] + 0.12)\r\n                        if nn[0] == 'LLR':\r\n                            y2_t = y2_t - (nn[1] + 0.12)\r\n                        if nn[0] == 'ULP':\r\n                            y1_t = y1_t + (nn[2])\r\n                        if nn[0] == 'LLP':\r\n                            y2_t = y2_t - (nn[2])\r\n                    \r\n                else:\r\n                    # Right line\r\n                    x1_t = min(x1 + 0.12, x2 + 0.12)\r\n                    x2_t = max(x1 + 0.12, x2 + 0.12)\r\n                    \r\n                    #\r\n                    for nn in self.corners:\r\n                        if nn[0] == 'URR':\r\n                            y1_t = y1_t + (nn[1] + 0.12)\r\n                        if nn[0] == 'LRR':\r\n                            y2_t = y2_t - (nn[1] + 0.12)\r\n                        if nn[0] == 'URP':\r\n                            y1_t = y1_t + (nn[2])\r\n                        if nn[0] == 'LRP':\r\n                            y2_t = y2_t - (nn[2])\r\n                    \r\n                #\r\n                EndLine = True\r\n                while EndLine:\r\n                    py1 = 10000000.0\r\n                    py2 = 10000000.0\r\n                    foundPad = False\r\n\r\n                    for n in self.pad:\r\n                        n_min_x = n.at.x - (n.size.x / 2.0)\r\n                        n_min_y = n.at.y - (n.size.y / 2.0)\r\n                        n_max_x = n_min_x + n.size.x\r\n                        n_max_y = n_min_y + n.size.y\r\n                        dd = max(0.25, n.solder_mask_margin)\r\n\r\n                        if (n_min_x <= x1_t) and (n_max_x > x1_t) and n_max_y > y1_t and n_min_y < y2_t:\r\n                            #\r\n                            # This pad is in SilkS line's path\r\n                            #\r\n                            if n_min_y < py1:\r\n                                py1 = n_min_y\r\n                                py2 = n_max_y\r\n                                foundPad = True\r\n                    if foundPad:\r\n                        #\r\n                        # Found at least one pad that is in SilkS's line\r\n                        #\r\n                        if (py1 - dd) > y1_t:\r\n                            #\r\n                            # It does not cover the start point\r\n                            #\r\n                            self.fsilksline.append(koaLine(x1_t, y1_t, x2_t, py1 - dd, 'F.SilkS', self.FSilkSWidth))\r\n                        y1_t = py2 + dd\r\n                    else:\r\n                        #\r\n                        # No pads was in the way\r\n                        #\r\n                        self.fsilksline.append(koaLine(x1_t, y1_t, x2_t, y2_t, 'F.SilkS', self.FSilkSWidth))\r\n                        EndLine = False\r\n\r\n                    if y1_t >= y2:\r\n                        EndLine = False\r\n        #\r\n        #\r\n        for n in self.fsilksline:\r\n            new_node = Line(start=Point2D(round(n.sx, 2), round(n.sy, 2)), end=Point2D(round(n.ex, 2), round(n.ey, 2)), layer=n.layer, width=n.width)\r\n            if n.width < 0.0:\r\n                new_node = Line(start=Point2D(round(n.sx, 2), round(n.sy, 2)), end=Point2D(round(n.ex, 2), round(n.ey, 2)), layer=n.layer)\r\n            new_node._parent = self\r\n            self.virtual_childs.append(new_node)\r\n\r\n    def _createFCrtYdLine(self):\r\n        self.fcrtydline = []\r\n        #\r\n        #\r\n        #\r\n        # Check all holes and pads, if a pad or hole is on the crtyrd line\r\n        # then jump over the pad/hole\r\n        #\r\n        for n in self.boxffabline:\r\n            x1 = min(n.sx, n.ex)\r\n            y1 = min(n.sy, n.ey)\r\n            x2 = max(n.sx, n.ex)\r\n            y2 = max(n.sy, n.ey)\r\n            #\r\n            #\r\n            if (x1 < 0.0 and y1 < 0.0 and y2 < 0.0) or (x1 < 0.0 and y1 > 0.0 and y2 > 0.0):\r\n                #\r\n                # Top and bottom line\r\n                #\r\n                x1_t = x1 - 0.25\r\n                x2_t = x2 + 0.25\r\n                x3_t = x1_t\r\n                x4_t = x2_t\r\n                #\r\n                if y1 < 0.0:\r\n                    # Top line\r\n                    y1_t = y1 - 0.25\r\n                    y2_t = y2 - 0.25\r\n                    y3_t = y1_t\r\n                    y4_t = y2_t\r\n                    #\r\n                    for nn in self.corners:\r\n                        if nn[0] == 'URR':\r\n                            x2_t = x2_t - (nn[1] + 0.25)\r\n                        if nn[0] == 'ULR':\r\n                            x1_t = x1_t + (nn[1] + 0.25)\r\n                        if nn[0] == 'ULP':\r\n                            x3_t = x1_t\r\n                            x1_t = x1_t + (nn[1])\r\n                            y3_t = y1_t + (nn[2])\r\n                        if nn[0] == 'URP':\r\n                            x4_t = x2_t\r\n                            x2_t = x2_t - (nn[1])\r\n                            y4_t = y1_t + (nn[2])\r\n                    \r\n                else:\r\n                    # Bottom line\r\n                    y1_t = y1 + 0.25\r\n                    y2_t = y2 + 0.25\r\n                    y3_t = y1_t\r\n                    y4_t = y2_t\r\n                    #\r\n                    for nn in self.corners:\r\n                        if nn[0] == 'LRR':\r\n                            x2_t = x2_t - (nn[1] + 0.25)\r\n                        if nn[0] == 'LLR':\r\n                            x1_t = x1_t + (nn[1] + 0.25)\r\n                        if nn[0] == 'LLP':\r\n                            x3_t = x1_t\r\n                            x1_t = x1_t + (nn[1])\r\n                            y3_t = y1_t - (nn[2])\r\n                        if nn[0] == 'LRP':\r\n                            x4_t = x2_t\r\n                            x2_t = x2_t - (nn[1])\r\n                            y4_t = y1_t - (nn[2])\r\n                #\r\n                EndLine = True\r\n                UseCorner = True\r\n                while EndLine:\r\n                    px1 = 10000000.0\r\n                    py1 = 10000000.0\r\n                    px2 = 10000000.0\r\n                    py2 = 10000000.0\r\n                    foundPad = False\r\n\r\n                    for n in self.pad:\r\n                        n_min_x = n.at.x - (n.size.x / 2.0)\r\n                        n_min_y = n.at.y - (n.size.y / 2.0)\r\n                        n_max_x = n_min_x + n.size.x\r\n                        n_max_y = n_min_y + n.size.y\r\n                        dd = max(0.25, n.solder_mask_margin)\r\n\r\n                        if (n_min_y - dd) <= y1_t and (n_max_y + dd) > y1_t and n_max_x > x1_t and n_min_x < x2_t:\r\n                            #\r\n                            # This pad is in CrtYd line's path\r\n                            #\r\n                            if n_min_x < px1:\r\n                                px1 = n_min_x\r\n                                py1 = n_min_y\r\n                                px2 = n_max_x\r\n                                py2 = n_max_y\r\n                                foundPad = True\r\n                    if foundPad:\r\n                        #\r\n                        # Found at least one pad that is in CrtYd's line\r\n                        #\r\n                        if (px1 - dd) > x1_t:\r\n                            #\r\n                            # It does not cover the start point\r\n                            #\r\n                            self.fcrtydline.append(koaLine(x1_t, y1_t, px1 - dd, y2_t, 'F.CrtYd', self.FCrtYdWidth))\r\n                            if y1 < 0.0:\r\n                                # Top line\r\n                                self.fcrtydline.append(koaLine(px1 - dd, y2_t, px1 - dd, py1 - dd, 'F.CrtYd', self.FCrtYdWidth))\r\n                                self.fcrtydline.append(koaLine(px1 - dd, py1 - dd, px2 + dd, py1 - dd, 'F.CrtYd', self.FCrtYdWidth))\r\n                                self.fcrtydline.append(koaLine(px2 + dd, py1 - dd, px2 + dd, y2_t, 'F.CrtYd', self.FCrtYdWidth))\r\n                            else:\r\n                                # Bottom line\r\n                                self.fcrtydline.append(koaLine(px1 - dd, y2_t, px1 - dd, py2 + dd, 'F.CrtYd', self.FCrtYdWidth))\r\n                                self.fcrtydline.append(koaLine(px1 - dd, py2 + dd, px2 + dd, py2 + dd, 'F.CrtYd', self.FCrtYdWidth))\r\n                                self.fcrtydline.append(koaLine(px2 + dd, py2 + dd, px2 + dd, y2_t, 'F.CrtYd', self.FCrtYdWidth))\r\n                        x1_t = px2 + dd\r\n                    else:\r\n                        #\r\n                        # No pads was in the way\r\n                        #\r\n                        #\r\n                        # No pads was in the way\r\n                        #\r\n                        if y1 < 0.0 and UseCorner:\r\n                            # Top line\r\n                            for nn in self.corners:\r\n                                if nn[0] == 'ULR':\r\n                                    urcdy0 = y1_t + (nn[1] + 0.25)\r\n                                    urcdx1 = x1_t - (nn[1] + 0.25)\r\n                                    new_node = Arc(center=Point2D(x1_t, urcdy0), start=Point2D(urcdx1, urcdy0), layer='F.CrtYd', width=self.FCrtYdWidth, angle=90.0)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    \r\n                                if nn[0] == 'ULP':\r\n                                    new_node = Line(start=Point2D(x1_t, y3_t), end=Point2D(x1_t, y1_t), layer='F.CrtYd', width=self.FCrtYdWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    new_node = Line(start=Point2D(x1_t, y3_t), end=Point2D(x3_t, y3_t), layer='F.CrtYd', width=self.FCrtYdWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    #\r\n                                if nn[0] == 'URP':\r\n                                    urcdy0 = y4_t + (nn[2])\r\n                                    new_node = Line(start=Point2D(x2_t, y4_t), end=Point2D(x2_t, y2_t), layer='F.CrtYd', width=self.FCrtYdWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    new_node = Line(start=Point2D(x2_t, y4_t), end=Point2D(x4_t, y4_t), layer='F.CrtYd', width=self.FCrtYdWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                            \r\n                        if y1 > 0.0 and UseCorner:\r\n                            # Bottom line\r\n                            for nn in self.corners:\r\n                                if nn[0] == 'LLR':\r\n                                    urcdy0 = y1_t - (nn[1] + 0.25)\r\n                                    new_node = Arc(center=Point2D(x1_t, urcdy0), start=Point2D(x1_t, y1_t), layer='F.CrtYd', width=self.FCrtYdWidth, angle=90.0)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    \r\n                                if nn[0] == 'LLP':\r\n                                    new_node = Line(start=Point2D(x1_t, y3_t), end=Point2D(x1_t, y1_t), layer='F.CrtYd', width=self.FCrtYdWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    new_node = Line(start=Point2D(x1_t, y3_t), end=Point2D(x3_t, y3_t), layer='F.CrtYd', width=self.FCrtYdWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    #\r\n                                if nn[0] == 'LRP':\r\n                                    urcdy0 = y4_t + (nn[2])\r\n                                    new_node = Line(start=Point2D(x2_t, y4_t), end=Point2D(x2_t, y2_t), layer='F.CrtYd', width=self.FCrtYdWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                                    new_node = Line(start=Point2D(x2_t, y4_t), end=Point2D(x4_t, y4_t), layer='F.CrtYd', width=self.FCrtYdWidth)\r\n                                    new_node._parent = self\r\n                                    self.virtual_childs.append(new_node)\r\n                        #\r\n                        self.fcrtydline.append(koaLine(x1_t, y1_t, x2_t, y2_t, 'F.CrtYd', self.FCrtYdWidth))\r\n                        EndLine = False\r\n\r\n                    UseCorner = False\r\n\r\n                    if x1_t >= x2:\r\n                        EndLine = False\r\n                    \r\n                if not foundPad and y1 < 0:\r\n                    # \r\n                    for nn in self.corners:\r\n                        if nn[0] == 'URR':\r\n                            urcdy1 = y1_t + (nn[1] + 0.25)\r\n                            new_node = Arc(center=Point2D(x2_t, urcdy1), start=Point2D(x2_t, y2_t), layer='F.CrtYd', width=self.FCrtYdWidth, angle=90.0)\r\n                            new_node._parent = self\r\n                            self.virtual_childs.append(new_node)\r\n                    \r\n                    \r\n                if not foundPad and y1 > 0:\r\n                    # \r\n                    for nn in self.corners:\r\n                        if nn[0] == 'LRR':\r\n                            urcdx1 = x2_t + (nn[1] + 0.25)\r\n                            urcdy1 = y2_t - (nn[1] + 0.25)\r\n                            new_node = Arc(center=Point2D(x2_t, urcdy1), start=Point2D(urcdx1, urcdy1), layer='F.CrtYd', width=self.FCrtYdWidth, angle=90.0)\r\n                            new_node._parent = self\r\n                            self.virtual_childs.append(new_node)\r\n\r\n            if (x1 < 0.0 and y1 < 0.0 and y2 > 0.0) or (x1 > 0.0 and y1 < 0.0 and y2 > 0.0):\r\n                #\r\n                # Left and right line\r\n                #\r\n                y1_t = y1 - 0.25\r\n                y2_t = y2 + 0.25\r\n                #\r\n                if x1 < 0.0:\r\n                    # Left line\r\n                    x1_t = x1 - 0.25\r\n                    x2_t = x1 - 0.25\r\n                    #\r\n                    for nn in self.corners:\r\n                        if nn[0] == 'ULR':\r\n                            y1_t = y1_t + (nn[1] + 0.25)\r\n                        if nn[0] == 'LLR':\r\n                            y2_t = y2_t - (nn[1] + 0.25)\r\n                        if nn[0] == 'ULP':\r\n                            y1_t = y1_t + (nn[2])\r\n                        if nn[0] == 'LLP':\r\n                            y2_t = y2_t - (nn[2])\r\n\r\n                else:\r\n\r\n                    # Right line\r\n                    x1_t = x1 + 0.25\r\n                    x2_t = x2 + 0.25\r\n                    #\r\n                    for nn in self.corners:\r\n                        if nn[0] == 'URR':\r\n                            y1_t = y1_t + (nn[1] + 0.25)\r\n                        if nn[0] == 'LRR':\r\n                            y2_t = y2_t - (nn[1] + 0.25)\r\n                        if nn[0] == 'URP':\r\n                            y1_t = y1_t + (nn[2])\r\n                        if nn[0] == 'LRP':\r\n                            y2_t = y2_t - (nn[2])\r\n                #\r\n                EndLine = True\r\n                while EndLine:\r\n                    px1 = 10000000.0\r\n                    py1 = 10000000.0\r\n                    px2 = 10000000.0\r\n                    py2 = 10000000.0\r\n                    foundPad = False\r\n\r\n                    for n in self.pad:\r\n                        n_min_x = n.at.x - (n.size.x / 2.0)\r\n                        n_min_y = n.at.y - (n.size.y / 2.0)\r\n                        n_max_x = n_min_x + n.size.x\r\n                        n_max_y = n_min_y + n.size.y\r\n                        dd = max(0.26, n.solder_mask_margin)\r\n\r\n                        if (n_min_x <= x1_t) and (n_max_x >= x1_t) and n_max_y >= y1_t and n_min_y <= y2_t:\r\n                            #\r\n                            # This pad is in CrtYd line's path\r\n                            #\r\n                            if n_min_y < py1:\r\n                                px1 = n_min_x\r\n                                py1 = n_min_y\r\n                                px2 = n_max_x\r\n                                py2 = n_max_y\r\n                                foundPad = True\r\n                    if foundPad:\r\n                        #\r\n                        # Found at least one pad that is in CrtYd's line\r\n                        #\r\n                        if (py1 - dd) > y1_t:\r\n                            #\r\n                            # It does not cover the start point\r\n                            #\r\n                            self.fcrtydline.append(koaLine(x1_t, y1_t, x2_t, py1 - dd, 'F.CrtYd', self.FCrtYdWidth))\r\n                            if x1 < 0.0:\r\n                                # Left line\r\n                                self.fcrtydline.append(koaLine(x2_t, py1 - dd, px1 - dd, py1 - dd,\r\n                                                               'F.CrtYd', self.FCrtYdWidth))\r\n                                self.fcrtydline.append(koaLine(px1 - dd, py1 - dd, px1 - dd, py2 + dd,\r\n                                                               'F.CrtYd', self.FCrtYdWidth))\r\n                                self.fcrtydline.append(koaLine(px1 - dd, py2 + dd, x2_t, py2 + dd,\r\n                                                               'F.CrtYd', self.FCrtYdWidth))\r\n                            else:\r\n                                # Right line\r\n                                self.fcrtydline.append(koaLine(x2_t, py1 - dd, px2 + dd, py1 - dd,\r\n                                                               'F.CrtYd', self.FCrtYdWidth))\r\n                                self.fcrtydline.append(koaLine(px2 + dd, py1 - dd, px2 + dd, py2 + dd,\r\n                                                               'F.CrtYd', self.FCrtYdWidth))\r\n                                self.fcrtydline.append(koaLine(px2 + dd, py2 + dd, x2_t, py2 + dd,\r\n                                                               'F.CrtYd', self.FCrtYdWidth))\r\n\r\n                        y1_t = py2 + dd\r\n                    else:\r\n                        #\r\n                        # No pads was in the way\r\n                        #\r\n                        self.fcrtydline.append(koaLine(x1_t, y1_t, x2_t, y2_t, 'F.CrtYd', self.FCrtYdWidth))\r\n                        EndLine = False\r\n\r\n                    if y1_t >= y2:\r\n                        EndLine = False\r\n        #\r\n        #\r\n        for n in self.fcrtydline:\r\n            new_node = Line(start=Point2D(round(n.sx, 2), round(n.sy, 2)), end=Point2D(round(n.ex, 2), round(n.ey, 2)), layer=n.layer, width=n.width)\r\n            if n.width < 0.0:\r\n                new_node = Line(start=Point2D(round(n.sx, 2), round(n.sy, 2)), end=Point2D(round(n.ex, 2), round(n.ey, 2)), layer=n.layer)\r\n            new_node._parent = self\r\n            self.virtual_childs.append(new_node)\r\n\r\n    def calculateBoundingBox(self):\r\n        min_x = self.at.x\r\n        min_y = self.at.y\r\n        max_x = min_x + self.size.x\r\n        max_y = min_y + self.size.y\r\n\r\n        for child in self.virtual_childs():\r\n            child_outline = child.calculateBoundingBox()\r\n\r\n            min_x = min([min_x, child_outline['min']['x']])\r\n            min_y = min([min_y, child_outline['min']['y']])\r\n            max_x = max([max_x, child_outline['max']['x']])\r\n            max_y = max([max_y, child_outline['max']['y']])\r\n\r\n        return {'min': Point2D(min_x, min_y), 'max': Point2D(max_x, max_y)}\r\n\r\n    def _createPinsNode(self):\r\n        #\r\n        # Add pin and holes\r\n        #\r\n        self.pad = []\r\n\r\n        c = 1\r\n        for n in self.pins:\r\n            c = n[1]\r\n            x = n[2]\r\n            y = n[3]\r\n            sx = n[4]\r\n            sy = n[5]\r\n            dh = n[6]\r\n            if n[0] == 'tht':\r\n                if c == '1':\r\n                    new_pad = Pad(number=c, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\r\n                                  at=[x, 0.0 - y], size=[sx, sy], drill=dh, layers=Pad.LAYERS_THT)\r\n                    self.footprint.append(new_pad)\r\n                    self.pad.append(new_pad)\r\n                else:\r\n                    new_pad = Pad(number=c, type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE,\r\n                                  at=[x, 0.0 - y], size=[sx, sy], drill=dh, layers=Pad.LAYERS_THT)\r\n                    self.footprint.append(new_pad)\r\n                    self.pad.append(new_pad)\r\n            if n[0] == 'thtr':\r\n                if c == '1':\r\n                    new_pad = Pad(number=c, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,\r\n                                  at=[x, 0.0 - y], size=[sx, sy], drill=dh, layers=Pad.LAYERS_THT)\r\n                    self.footprint.append(new_pad)\r\n                    self.pad.append(new_pad)\r\n                else:\r\n                    new_pad = Pad(number=c, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL,\r\n                                  at=[x, 0.0 - y], size=[sx, sy], drill=dh, layers=Pad.LAYERS_THT)\r\n                    self.footprint.append(new_pad)\r\n                    self.pad.append(new_pad)\r\n            elif n[0] == 'smd':\r\n                    new_pad = Pad(number=c, type=Pad.TYPE_SMT, shape=Pad.SHAPE_ROUNDRECT, radius_ratio=0.25, \r\n                                  at=[x, 0.0 - y], size=[sx, sy], drill=dh, layers=Pad.LAYERS_SMT)\r\n                    self.footprint.append(new_pad)\r\n                    self.pad.append(new_pad)\r\n            elif n[0] == 'npth':\r\n                    if sy == 0:\r\n                        new_pad = Pad(type=Pad.TYPE_NPTH, shape=Pad.SHAPE_CIRCLE,\r\n                                      at=[x, 0.0 - y], size=[sx, sx], drill=dh, layers=Pad.LAYERS_NPTH)\r\n                        self.footprint.append(new_pad)\r\n                        self.pad.append(new_pad)\r\n                    else:\r\n                        new_pad = Pad(type=Pad.TYPE_NPTH, shape=Pad.SHAPE_RECT,\r\n                                      at=[x, 0.0 - y], size=[sx, sy], drill=dh, layers=Pad.LAYERS_NPTH)\r\n                        self.footprint.append(new_pad)\r\n                        self.pad.append(new_pad)\r\n            #\r\n"
  },
  {
    "path": "scripts/general/new more powerfull generator found under SMD_chip_package_rlc-etc",
    "content": ""
  },
  {
    "path": "scripts/general/smd_chip.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\n\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load parent path of KicadModTree\n\nfrom KicadModTree import *  # NOQA\nfrom KicadModTree.nodes.base.Pad import Pad  # NOQA\n\n\ndef smd_chip(args):\n    # init kicad footprint\n    kicad_mod = Footprint(args['name'])\n    kicad_mod.setDescription(args['description'])\n    kicad_mod.setTags(args['tags'])\n    kicad_mod.setAttribute('smd')\n\n    # set general values\n    text_x = 0.\n    text_y = max([args['pad_y'] / 2., args['part_y'] / 2.]) + args['courtyard'] + 0.75\n\n    kicad_mod.append(Text(type='reference', text='REF**', at=[text_x, -text_y], layer='F.SilkS'))\n    kicad_mod.append(Text(type='user', text='%R', at=[text_x, -text_y], layer='F.Fab'))\n    kicad_mod.append(Text(type='value', text=args['name'], at=[text_x, text_y], layer='F.Fab'))\n\n    # create silkscreen\n    silk_x = args['part_x'] / 2.\n    silk_y = max([args['pad_y'] / 2., args['part_y'] / 2.]) + min(max(0.15, args['courtyard'] - 0.05), 0.2)\n\n    kicad_mod.append(Line(start=[silk_x, silk_y], end=[-silk_x, silk_y], layer='F.SilkS'))\n    kicad_mod.append(Line(start=[silk_x, -silk_y], end=[-silk_x, -silk_y], layer='F.SilkS'))\n\n    # create fabrication layer\n    kicad_mod.append(RectLine(start=[args['part_x'] / 2., args['part_y'] / 2.],\n                              end=[-args['part_x'] / 2., -args['part_y'] / 2.],\n                              layer='F.Fab'))\n\n    # create courtyard\n    courtyard_x = args['courtyard'] + max([args['pad_spacing'] / 2. + args['pad_x'], args['part_x'] / 2.])\n    courtyard_y = args['courtyard'] + max([args['pad_y'] / 2., args['part_y'] / 2.])\n\n    kicad_mod.append(RectLine(start=[courtyard_x, courtyard_y],\n                              end=[-courtyard_x, -courtyard_y],\n                              layer='F.CrtYd'))\n\n    # create pads\n    pad_settings = {'type': Pad.TYPE_SMT,\n                    'shape': Pad.SHAPE_RECT,\n                    'size': [args['pad_x'], args['pad_y']],\n                    'layers': Pad.LAYERS_SMT}\n\n    pad_x_center = (args['pad_spacing'] + args['pad_x'])  / 2.\n\n    kicad_mod.append(Pad(number=1, at=[-pad_x_center, 0], **pad_settings))\n    kicad_mod.append(Pad(number=2, at=[pad_x_center, 0], **pad_settings))\n\n    # add model\n    kicad_mod.append(Model(filename=\"{model_dir}.3dshapes/{name}.wrl\".format(**args),\n                           at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))\n\n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('{}.kicad_mod'.format(args['name']))\n\n\nif __name__ == '__main__':\n    parser = ModArgparser(smd_chip)\n    parser.add_parameter(\"name\", type=str, required=True)  # the root node of .yml files is parsed as name\n    parser.add_parameter(\"description\", type=str, required=True)\n    parser.add_parameter(\"tags\", type=str, required=True)\n    parser.add_parameter(\"model_dir\", type=str, required=True)\n    parser.add_parameter(\"courtyard\", type=float, required=False, default=0.25)\n    parser.add_parameter(\"part_x\", type=float, required=True)\n    parser.add_parameter(\"part_y\", type=float, required=True)\n    parser.add_parameter(\"pad_x\", type=float, required=True)\n    parser.add_parameter(\"pad_y\", type=float, required=True)\n    parser.add_parameter(\"pad_spacing\", type=float, required=True)\n\n    parser.run()  # now run our script which handles the whole part of parsing the files\n"
  },
  {
    "path": "scripts/pin-headers_socket-strips/make_idc_headers.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_pin_headers import *  # NOQA\n\n\nif __name__ == '__main__':\n    # from http://multimedia.3m.com/mws/media/22448O/3m-four-wall-header-3000-series-100-x-100-ts-0772.pdf\n    # and  http://www.selecom.it/pdf/06din416.pdf\n    # and  https://www.reboul.fr/storage/00003af6.pdf\n    # and  http://www.oupiin.com/product_iii.html?c1=10&c2=54\n    # and  http://www.assmann-wsw.com/fileadmin/catalogue/04_Multiflex_rev4-0.pdf\n    # and  https://docs.google.com/spreadsheets/d/16SsEcesNF15N3Lb4niX7dcUr-NY5_MFPQhobNuNppn4/edit#gid=0\n    \n    tags_additional = []\n    extra_description = 'https://docs.google.com/spreadsheets/d/16SsEcesNF15N3Lb4niX7dcUr-NY5_MFPQhobNuNppn4/edit#gid=0'\n\n    rm=2.54\n    cols = 2\n    ddrill=1\n    pad=[1.7,1.7]\n    \n    orientation='Vertical'\n    latching = True\n    body_width=8.8\n    body_overlen=10.97\n    body_offset=0\n    mating_overlen=3.92\n    wall_thickness=1.2\n    notch_width=4.1\n    latch_lengths = [0,6.5,9.5,12] # these values roughly represent the referenced parts with the latch open\n    latch_width=4.4 # large enough to handle all referenced parts and measured empirically\n    mh_ddrill=2.69\n    mh_pad=[8,8] # 3M 3000 datasheet says 5/16\" screw head which is ~8mm; existing KiCad footprint is 5.46mm\n    mh_overlen=8.94 # existing KiCad footprint is 8.89\n    mh_offset=1.02 # existing KiCad footprint is 1.02\n    mh_number='MP'\n\n    for rows in [5,6,7,8,10,12,13,15,17,20,25,30,32]:\n        for latch_len in latch_lengths:\n            for mh_ddrill, mh_pad, mh_overlen in zip([0, mh_ddrill], [[0,0], mh_pad], [0, mh_overlen]):\n            #for mh_ddrill, mh_pad, mh_overlen in zip([0], [[0,0]], [0]):\n                makeIdcHeader(rows, cols, rm, rm, body_width,\n                                    body_overlen, body_overlen, body_offset,\n                                    ddrill, pad,\n                                    mating_overlen, wall_thickness, notch_width,\n                                    orientation, latching,\n                                    latch_len, latch_width,\n                                    mh_ddrill, mh_pad, mh_overlen, mh_offset, mh_number,\n                                    tags_additional, extra_description, \"Connector_IDC\", \"IDC-Header\", \"IDC header\",\n                                    [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n    \n    # the above datasheets cover both horizontal and vertical\n    # latches are assumed to hang off the PCB so they aren't included here\n    # for this footprint the body outline is hard-coded into the script\n    orientation='Horizontal'\n    body_width=1.24+15.53 # # existing KiCad footprint is 1.27+15.88\n    body_offset=-1.24 # existing KiCad footprint is -1.27\n    latch_len=0\n    mh_ddrill=2.69 # not sure why this needs to be here when it's above...\n    mh_pad=[8,8] # existing KiCad footprint is 3.05mm\n    mh_overlen=5.905 # existing KiCad footprint is 5.84\n    mh_offset=1.8 # existing KiCad footprint is 1.78\n    \n    for rows in [5,6,7,8,10,12,13,15,17,20,25,30,32]:\n        for mh_ddrill, mh_pad, mh_overlen in zip([0, mh_ddrill], [[0,0], mh_pad], [0, mh_overlen]):\n            makeIdcHeader(rows, cols, rm, rm, body_width,\n                                body_overlen, body_overlen, body_offset,\n                                ddrill, pad,\n                                mating_overlen, wall_thickness, notch_width,\n                                orientation, latching,\n                                latch_len, latch_width,\n                                mh_ddrill, mh_pad, mh_overlen, mh_offset, mh_number,\n                                tags_additional, extra_description, \"Connector_IDC\", \"IDC-Header\", \"IDC header\",\n                                [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n\n    \n    # from http://multimedia.3m.com/mws/media/330367O/3m-four-wall-header-2500-series-ts-0770.pdf\n    # and  https://www.te.com/commerce/DocumentDelivery/DDEController?Action=srchrtrv&DocNm=1761681&DocType=Customer+Drawing&DocLang=English\n    # and  https://cdn.amphenol-icc.com/media/wysiwyg/files/drawing/75869.pdf\n    # and  https://katalog.we-online.de/em/datasheet/6120xx21621.pdf\n    # and  https://docs.google.com/spreadsheets/d/16SsEcesNF15N3Lb4niX7dcUr-NY5_MFPQhobNuNppn4/edit#gid=0\n    \n    orientation='Vertical'\n    latching = False\n    has_latch=False\n    body_width=8.9\n    body_overlen=5.1\n    body_offset=0\n    mating_overlen=3.91\n    \n    for rows in [3,4,5,6,7,8,10,12,13,15,17,20,25,30,32]:\n        makeIdcHeader(rows, cols, rm, rm, body_width,\n                            body_overlen, body_overlen, body_offset,\n                            ddrill, pad,\n                            mating_overlen, wall_thickness, notch_width,\n                            orientation, latching,\n                            0, 0,\n                            0, [0,0], 0, 0, 0,\n                            tags_additional, extra_description, \"Connector_IDC\", \"IDC-Header\", \"IDC box header\",\n                            [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n\n    # from http://multimedia.3m.com/mws/media/22504O/3mtm-100-in-loprof-hdr-100x-100strt-ra-4-wall-ts0818.pdf\n    # and  https://b2b.harting.com/files/download/PRD/PDF_TS/09185XXX323_100154466DRW007A.pdf\n    # and  http://suddendocs.samtec.com/prints/tst-1xx-xx-xx-x-xx-xx-mkt.pdf\n    # and  https://katalog.we-online.de/em/datasheet/6120xx21721.pdf\n    # and  https://cdn.amphenol-icc.com/media/wysiwyg/files/drawing/75867.pdf\n    # and  https://docs.google.com/spreadsheets/d/16SsEcesNF15N3Lb4niX7dcUr-NY5_MFPQhobNuNppn4/edit#gid=0\n    \n    orientation='Horizontal'\n    body_offset=4.38 # distance from pin 1 row to the closest edge of the plastic body\n    \n    for rows in [3,4,5,6,7,8,10,12,13,15,17,20,25,30,32]:\n        makeIdcHeader(rows, cols, rm, rm, body_width,\n                            body_overlen, body_overlen, body_offset,\n                            ddrill, pad,\n                            mating_overlen, wall_thickness, notch_width,\n                            orientation, latching,\n                            0, 0,\n                            0, [0,0], 0, 0, 0,\n                            tags_additional, extra_description, \"Connector_IDC\", \"IDC-Header\", \"IDC box header\",\n                            [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n"
  },
  {
    "path": "scripts/pin-headers_socket-strips/make_pin_headers.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_pin_headers import *  # NOQA\n\n\n\n\nif __name__ == '__main__':\n    # common settings\n    # from http://katalog.we-online.de/em/datasheet/6130xx11121.pdf\n    # and  http://katalog.we-online.de/em/datasheet/6130xx21121.pdf\n    # and  http://katalog.we-online.de/em/datasheet/6130xx11021.pdf\n    # and  http://katalog.we-online.de/em/datasheet/6130xx21021.pdf\n    # and  https://cdn.harwin.com/pdfs/M20-877.pdf\n    # and  https://cdn.harwin.com/pdfs/M20-876.pdf\n\n    rm=2.54\n    ddrill=1\n    pad=[1.7,1.7]\n    singlecol_packwidth=2.54\n    singlecol_packoffset=0\n    angled_pack_width=2.54\n    angled_pack_offset=1.5\n    angled_pin_length=6\n    angled_pin_width=0.64\n    rmx_pad_offset=[1.655,2.525]\n    rmx_pin_length=[2.54,3.6]\n    pin_width=0.64\n    single_pad_smd=[2.51,1.0]\n    dual_pad_smd=[3.15,1.0]\n\n    for cols in [1,2]:\n        for rows in range(1,41):\n            makePinHeadStraight(rows, cols, rm, rm, cols * singlecol_packwidth + singlecol_packoffset,\n                                singlecol_packwidth / 2 + singlecol_packoffset,\n                                singlecol_packwidth / 2 + singlecol_packoffset, ddrill, pad, [], \"/Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n            makePinHeadAngled(rows, cols, rm, rm, angled_pack_width, angled_pack_offset, angled_pin_length, angled_pin_width, ddrill, pad,\n                              [], \"/Pin_Headers\", \"Pin_Header\", \"pin header\", [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n            if rows != 1 or cols == 2:\n              if cols == 2:\n                  makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset[cols-1], rmx_pin_length[cols-1], pin_width, cols * singlecol_packwidth + singlecol_packoffset,\n                                      singlecol_packwidth / 2 + singlecol_packoffset,\n                                      singlecol_packwidth / 2 + singlecol_packoffset, dual_pad_smd,\n                                         True, [], \"/Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                         [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n              if cols==1:\n                  makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset[cols-1], rmx_pin_length[cols-1], pin_width,\n                                     cols * singlecol_packwidth + singlecol_packoffset,\n                                     singlecol_packwidth / 2 + singlecol_packoffset,\n                                     singlecol_packwidth / 2 + singlecol_packoffset, single_pad_smd,\n                                     True, [], \"/Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                     [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n                  makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset[cols-1], rmx_pin_length[cols-1], pin_width,\n                                     cols * singlecol_packwidth + singlecol_packoffset,\n                                     singlecol_packwidth / 2 + singlecol_packoffset,\n                                     singlecol_packwidth / 2 + singlecol_packoffset, single_pad_smd,\n                                     False, [], \"/Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                     [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n\n    rm=2.00\n    ddrill=0.8\n    pad=[1.35, 1.35]\n    singlecol_packwidth=2.0\n    singlecol_packoffset=0\n    angled_pack_width=1.5\n    angled_pack_offset=3-1.5\n    angled_pin_length=4.2\n    angled_pin_width=0.5\n    rmx_pad_offset=[1.175,2.085]\n    rmx_pin_length=[2.1,2.875]\n    pin_width=0.5\n    single_pad_smd=[2.35,0.85]\n    dual_pad_smd=[2.58,1.0]\n    for cols in [1, 2]:\n        for rows in range(1, 41):\n            makePinHeadStraight(rows, cols, rm, rm, cols * singlecol_packwidth + singlecol_packoffset,\n                                singlecol_packwidth / 2 + singlecol_packoffset,\n                                singlecol_packwidth / 2 + singlecol_packoffset, ddrill, pad, [], \"Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n            makePinHeadAngled(rows, cols, rm, rm, angled_pack_width, angled_pack_offset, angled_pin_length,\n                              angled_pin_width, ddrill, pad,\n                              [], \"Pin_Headers\", \"Pin_Header\", \"pin header\", [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n            if rows != 1 or cols == 2:\n              if cols == 2:\n                  makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset[cols-1], rmx_pin_length[cols-1], pin_width,\n                                         cols * singlecol_packwidth + singlecol_packoffset,\n                                         singlecol_packwidth / 2 + singlecol_packoffset,\n                                         singlecol_packwidth / 2 + singlecol_packoffset, dual_pad_smd,\n                                         True, [], \"Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                         [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n              if cols == 1:\n                  makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset[cols-1], rmx_pin_length[cols-1], pin_width,\n                                         cols * singlecol_packwidth + singlecol_packoffset,\n                                         singlecol_packwidth / 2 + singlecol_packoffset,\n                                         singlecol_packwidth / 2 + singlecol_packoffset, single_pad_smd,\n                                         True, [], \"Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                         [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n                  makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset[cols-1], rmx_pin_length[cols-1], pin_width,\n                                         cols * singlecol_packwidth + singlecol_packoffset,\n                                         singlecol_packwidth / 2 + singlecol_packoffset,\n                                         singlecol_packwidth / 2 + singlecol_packoffset, single_pad_smd,\n                                         False, [], \"Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                         [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n\n    # From https://cdn.harwin.com/pdfs/M50-393.pdf\n    # https://cdn.harwin.com/pdfs/M50-363.pdf\n    # https://cdn.harwin.com/pdfs/M50-353.pdf\n    # https://cdn.harwin.com/pdfs/M50-360.pdf\n    # and http://www.mouser.com/ds/2/181/M50-360R-1064294.pdfs\n    rm = 1.27\n    ddrill = 0.65\n    pad = [1.0, 1.0]\n    package_width=[2.1,3.41]\n    singlecol_packwidth = 1.27\n    angled_pack_width=1.0\n    angled_pack_offset=0.5\n    angled_pin_length=4.0\n    angled_pin_width=0.4\n    rmx_pad_offset=[1.5,1.95]\n    rmx_pin_length=[2.5, 2.75]\n    pin_width=0.4\n    single_pad_smd=[3.0,0.65]\n    dual_pad_smd=[2.4,0.74]\n    for cols in [1, 2]:\n        for rows in range(1, 41):\n            makePinHeadStraight(rows, cols, rm, rm, package_width[cols-1],\n                                singlecol_packwidth / 2 ,\n                                singlecol_packwidth / 2 , ddrill, pad, [], \"Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n            makePinHeadAngled(rows, cols, rm, rm, angled_pack_width, angled_pack_offset, angled_pin_length,\n                              angled_pin_width, ddrill, pad,\n                              [], \"Pin_Headers\", \"Pin_Header\", \"pin header\", [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n            if rows != 1 or cols == 2:\n                if cols == 2:\n                    makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset[cols-1], rmx_pin_length[cols-1], pin_width,\n                                           package_width[cols-1],\n                                           singlecol_packwidth / 2 + singlecol_packoffset,\n                                           singlecol_packwidth / 2 + singlecol_packoffset, dual_pad_smd,\n                                           True, [], \"Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                           [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n                if cols == 1:\n                    makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset[cols-1], rmx_pin_length[cols-1], pin_width,\n                                           package_width[cols-1],\n                                           singlecol_packwidth / 2 + singlecol_packoffset,\n                                           singlecol_packwidth / 2 + singlecol_packoffset, single_pad_smd,\n                                           True, [], \"Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                           [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n                    makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset[cols-1], rmx_pin_length[cols-1], pin_width,\n                                           package_width[cols-1],\n                                           singlecol_packwidth / 2 + singlecol_packoffset,\n                                           singlecol_packwidth / 2 + singlecol_packoffset, single_pad_smd,\n                                           False, [], \"Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                           [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n    #single row THT Straight headers https://gct.co/pdfjs/web/viewer.html?file=/Files/Drawings/BC020.pdf&t=1502019369628\n    #dual row THT Straight headers https://gct.co/files/drawings/bc035.pdf\n    #single row THT Angled headers https://gct.co/pdfjs/web/viewer.html?file=/Files/Drawings/BC030.pdf&t=1502031327147\n    #dual row THT Angled headers https://gct.co/files/drawings/bc045.pdf\n    #single row SMD Straight headers http://www.farnell.com/datasheets/1912818.pdf?_ga=2.101918145.1303212991.1501602361-984110936.1498471838\n    #dual row SMD Straight headers https://gct.co/files/drawings/bc050.pdf\n    rm = 1.0\n    ddrill = 0.5\n    pad = [0.85, 0.85]\n    package_width=[1.27,2.3]\n    singlecol_packwidth = 1.00\n    angled_pack_width=[1.0, 1.2]\n    angled_pack_offset= [0.25, 0.9]\n    angled_pin_length=2.0\n    angled_pin_width=0.3\n    rmx_pad_offset=[0.875, 1.65]\n    rmx_pin_length=[1.25, 2.4]\n    pin_width=0.3\n    single_pad_smd=[1.75,0.6]\n    dual_pad_smd=[2.0,0.5]\n    for cols in [1, 2]:\n        for rows in range(1, 41):\n            makePinHeadStraight(rows, cols, rm, rm, package_width[cols-1],\n                                singlecol_packwidth / 2 ,\n                                singlecol_packwidth / 2 , ddrill, pad, [], \"Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n            makePinHeadAngled(rows, cols, rm, rm, angled_pack_width[cols-1], angled_pack_offset[cols-1], angled_pin_length,\n                              angled_pin_width, ddrill, pad,\n                              [], \"Pin_Headers\", \"Pin_Header\", \"pin header\", [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n            \n            if rows != 1 or cols == 2:\n                if cols == 2:\n                    makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset[cols-1], rmx_pin_length[cols-1], pin_width,\n                                           package_width[cols-1],\n                                           singlecol_packwidth / 2 + singlecol_packoffset,\n                                           singlecol_packwidth / 2 + singlecol_packoffset, dual_pad_smd,\n                                           True, [], \"Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                           [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n                \n                if cols == 1:\n                    makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset[cols-1], rmx_pin_length[cols-1], pin_width,\n                                           package_width[cols-1],\n                                           singlecol_packwidth / 2 + singlecol_packoffset,\n                                           singlecol_packwidth / 2 + singlecol_packoffset, single_pad_smd,\n                                           True, [], \"Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                           [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n                    makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset[cols-1], rmx_pin_length[cols-1], pin_width,\n                                           package_width[cols-1],\n                                           singlecol_packwidth / 2 + singlecol_packoffset,\n                                           singlecol_packwidth / 2 + singlecol_packoffset, single_pad_smd,\n                                           False, [], \"Pin_Headers\", \"Pin_Header\", \"pin header\",\n                                           [0, 0, 0], [1, 1, 1], [0, 0, 0], \"${KISYS3DMOD}\")\n"
  },
  {
    "path": "scripts/pin-headers_socket-strips/make_socket_strips.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"tools\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom footprint_scripts_pin_headers import *  # NOQA\n\n\n\n\nif __name__ == '__main__':\n    # common settings\n    rm=2.54\n    ddrill=1\n    pad=[1.7,1.7]\n    singlecol_packwidth=2.54\n    singlecol_packoffset=0\n    angled_pack_width=8.51\n    angled_pack_offset=1.52\n    angled_pin_width=0.64\n    rmx_pad_offset=1.25\n    rmx_pin_length=2.65\n    pin_width=0.64\n    pad_smd=[3,1]\n\n    for cols in [1,2]:\n        for rows in range(1,41):\n            makePinHeadStraight(rows, cols, rm, rm, cols * singlecol_packwidth + singlecol_packoffset,\n                                singlecol_packwidth / 2 + singlecol_packoffset,\n                                singlecol_packwidth / 2 + singlecol_packoffset, ddrill, pad, [], \"Socket_Strips\", \"Socket_Strip\", \"socket strip\",\n                                [-(cols - 1) * rm / 2 / 25.4, -(rows - 1) * rm / 2 / 25.4, 0], [1, 1, 1],\n                                [0, 0, 270], isSocket=True)\n            makeSocketStripAngled(rows, cols, rm, rm, angled_pack_width, angled_pack_offset, angled_pin_width, ddrill, pad,\n                              [], \"Socket_Strips\",  \"Socket_Strip\", \"socket strip\",[-(cols - 1) * rm / 2 / 25.4, -(rows - 1) * rm / 2 / 25.4, 0], [1, 1, 1],\n                                [0, 0, 270])\n            if cols == 2:\n                makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset, rmx_pin_length, pin_width,\n                                       cols * singlecol_packwidth + singlecol_packoffset,\n                                       singlecol_packwidth / 2 + singlecol_packoffset,\n                                       singlecol_packwidth / 2 + singlecol_packoffset, pad_smd,\n                                       True, [], \"Socket_Strips\", \"Socket_Strip\", \"socket strip\", isSocket=True)\n            \n\n    rm=2.00\n    ddrill=0.8\n    pad=[1.35, 1.35]\n    singlecol_packwidth=2.0\n    singlecol_packoffset=0\n    angled_pack_width=6.35\n    angled_pack_offset=1.27\n    angled_pin_width=0.5\n    rmx_pad_offset=2.125\n    rmx_pin_length=2\n    pin_width=0.5\n    pad_smd=[2.75,1]\n    for cols in [1, 2]:\n        for rows in range(1, 41):\n            makePinHeadStraight(rows, cols, rm, rm, cols * singlecol_packwidth + singlecol_packoffset,\n                                singlecol_packwidth / 2 + singlecol_packoffset,\n                                singlecol_packwidth / 2 + singlecol_packoffset, ddrill, pad, [], \"Socket_Strips\", \"Socket_Strip\", \"socket strip\",\n                                offset3d=[0,0, 0], scale3d=[1, 1, 1],\n                                rotate3d=[0, 0, 0], isSocket=True)\n            makeSocketStripAngled(rows, cols, rm, rm, angled_pack_width, angled_pack_offset,\n                              angled_pin_width, ddrill, pad,\n                              [], \"Socket_Strip\", \"Socket_Strip\", \"socket strip\", [(cols - 1) * rm / 2 / 25.4, -(rows - 1) * rm / 2 / 25.4, 0],\n                              [1, 1, 1],\n                              [0, 0, 90])\n            if cols == 2:\n                makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset, rmx_pin_length, pin_width,\n                                       cols * singlecol_packwidth + singlecol_packoffset,\n                                       singlecol_packwidth / 2 + singlecol_packoffset,\n                                       singlecol_packwidth / 2 + singlecol_packoffset, pad_smd,\n                                       True, [], \"Socket_Strips\", \"Socket_Strip\", \"socket strip\", isSocket=True)\n            \n\n    rm = 1.27\n    ddrill = 0.7\n    pad = [1, 1]\n    package_width=[2.54,3.05]\n    singlecol_packwidth = 1.27\n    angled_pack_width=1\n    angled_pack_offset=3.81-1\n    angled_pin_length=3.81\n    angled_pin_width=0.4\n    rmx_pad_offset=1.95\n    rmx_pin_length=1.92\n    pin_width=0.4\n    pad_smd=[2.1,0.75]\n    for cols in [1, 2]:\n        for rows in range(1, 41):\n            makePinHeadStraight(rows, cols, rm, rm, package_width[cols-1],\n                                singlecol_packwidth / 2 ,\n                                singlecol_packwidth / 2 , ddrill, pad, [], \"Socket_Strips\", \"Socket_Strip\", \"socket strip\",\n                                offset3d=[0, 0, 0], scale3d=[1, 1, 1],\n                                rotate3d=[0, 0, 0], isSocket=True)\n            if cols == 2:\n                makePinHeadStraightSMD(rows, cols, rm, rm, rmx_pad_offset, rmx_pin_length, pin_width,\n                                       cols * singlecol_packwidth + singlecol_packoffset,\n                                       singlecol_packwidth / 2 + singlecol_packoffset,\n                                       singlecol_packwidth / 2 + singlecol_packoffset, pad_smd,\n                                       True, [], \"Socket_Strips\", \"Socket_Strip\", \"socket strip\", isSocket=True)\n\n            "
  },
  {
    "path": "scripts/tools/dict_tools.py",
    "content": "#!/usr/bin/env python\n\nimport collections.abc\nimport copy\n\ndef dictMerge(a, b):\n    \"\"\"Recursively merges the contents of two dict objects\n    \n    This function is similar to the built-in dict.update() method, but instead \n    of clobbering the contents of one dictionary with another, it recursively\n    combines dictionaries. The result is a dictionary containing the combined\n    contents of the arguments. If both dictionaries contain a key with the same\n    name (at the same level), the value in `b` takes precedence.\n    \n    Parameters\n    ----------\n    a : dict\n        Base dictionary used as the merge destination\n    b : dict\n        Dictionary containing values to merge into `a`\n    \n    Returns\n    -------\n    Merged dictionaries (`a` with contents updated from `b`)\n    \n    Examples\n    --------\n    >>> a = {'a': 1, 'b': 2, 'c': {'a': 1, 'b': 2}}\n    >>> b = {'c': {'b': 3}, 'd': 4}\n    >>> dictMerge(a, b)\n    {'a': 1, 'b': 2, 'c': {'a': 1, 'b': 3}, 'd': 4}\n    \"\"\"\n    for (k, v) in b.items():\n        if isinstance(v, collections.abc.Mapping):\n            a[k] = dictMerge(a.get(k, {}), v)\n        else:\n            a[k] = v\n    return a\n\ndef dictInherit(d):\n    \"\"\"Recursively merges dictionaries within a hierarchy using 'inherit' entries\n    \n    The top-level dictionary (`d`) can be thought of as a type of \"namespace\"\n    containing a collection of objects (sub-dictionaries). Objects within the\n    namespace may contain an 'inherit' entry, which stores the key for another\n    object within the namespace.\n    \n    Inheritance is done recursively, so it is possible to have multiple levels\n    of inheritance (object c can inherit b, which itself inherits from a). When\n    this function is executed, it iterates through every entry in `d` and runs\n    dictMerge() until all of the 'inherit' entries have been resolved. The \n    result is applied to `d` in-place.\n    \n    Parameters\n    ----------\n    d : dict\n        Top-level \"namespace\" dictionary containing other dictionaries, each of\n        which may contain an 'inherit' key to be resolved; edited in-place\n    \n    Raises\n    ------\n    RecursionError\n        If two dictionaries attempt to inherit each other\n    KeyError\n        If a dictionary tries to inherit from a key that is not in `d`\n    \n    Notes\n    -----\n    Typical JSON/YAML file structure that can be processed by this function:\n    {\n      \"1\": {\n        \"a\": 1,\n        \"b\": {\"c\": 2, \"d\": 3, ...}\n      },\n      \"2\": {\n        \"inherit\": \"1\",\n        \"b\": {\"c\": 3}\n      },\n      ...\n      \"n\": {\n        \"inherit\": \"2\",\n        \"d\": 4\n      }\n    }\n    \n    The result will look something like this:\n    {\n      \"1\": {\n        \"a\": 1,\n        \"b\": {\"c\": 2, \"d\": 3, ...}\n      },\n      \"2\": {\n        \"a\": 1,\n        \"b\": {\"c\": 3, \"d\": 3, ...}\n      },\n      ...\n      \"n\": {\n        \"a\": 1,\n        \"b\": {\"c\": 3, \"d\": 3, ...},\n        \"d\": 4\n      }\n    }\n    \"\"\"\n    \n    def dictInherit(d, child, parent):\n        if 'inherit' not in parent:\n            del child['inherit']\n            p = copy.deepcopy(parent)\n            return dictMerge(p, child)\n        elif d[parent['inherit']] is child:\n            raise RecursionError\n        else:\n            return dictInherit(d, parent, d[parent['inherit']])\n\n    for (k, v) in d.items():\n        if isinstance(v, collections.abc.Mapping) and 'inherit' in v:\n            d[k] = dictInherit(d, v, d[v['inherit']])\n        else:\n            continue\n"
  },
  {
    "path": "scripts/tools/drawing_tools.py",
    "content": "#!/usr/bin/env python\r\n\r\nimport sys\r\nimport os\r\nimport math\r\nimport time\r\n\r\n# ensure that the kicad-footprint-generator directory is available\r\n# sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\r\n# sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\r\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\", \"kicad_mod\"))  # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0], \"..\", \"..\"))  # load kicad_mod path\r\n\r\nfrom KicadModTree import *  # NOQA\r\nfrom footprint_global_properties import *\r\n\r\n# tool function for generating 3D-scripts\r\ndef script3d_writevariable(file, line, varname, value):\r\n    file.write(\"# {0}\\nApp.ActiveDocument.Spreadsheet.set('A{1}', 'var {0} = '); App.ActiveDocument.Spreadsheet.set('B{1}', '{2}'); App.ActiveDocument.Spreadsheet.setAlias('B{1}', '{0}')\\n\".format(varname, line, value))\r\n\r\n\r\n# round for grid g\r\ndef roundG(x, g):\r\n    if (x > 0):\r\n        return math.ceil(x / g) * g\r\n    else:\r\n        return math.floor(x / g) * g\r\n\r\n# round for grid g\r\ndef sqr(x):\r\n    return x*x\r\n\r\n\r\n# round for courtyard grid\r\ndef roundCrt(x):\r\n    return roundG(x, grid_crt)\r\n\r\n\r\n# float-variant of range()\r\ndef frange(x, y, jump):\r\n    while x < y:\r\n        yield x\r\n        x += jump\r\n\r\n\r\n# inclusice float-variant of range()\r\ndef frangei(x, y, jump):\r\n    while x <= y:\r\n        yield x\r\n        x += jump\r\n\r\n\r\n# returns a list with a single rectangle around x,y with width and height w and h\r\ndef addKeepoutRect(x, y, w, h):\r\n    return [[x - w / 2, x + w / 2, y - h / 2, y + h / 2]]\r\n\r\n\r\n# returns a series of rectangle that lie around the circular pad around (x,y) with radius w=h\r\n# if w!=h, addKeepoutRect() is called\r\ndef addKeepoutRound(x, y, w, h):\r\n    if w != h:\r\n        return addKeepoutRect(x, y, w, h)\r\n    else:\r\n        res = []\r\n        Nrects = 16\r\n        r = max(h, w) / 2\r\n        yysum = 0\r\n        for ya in frange(0, r, r / Nrects):\r\n            a = math.fabs(math.asin(ya / r) / math.pi * 180)\r\n            yy = math.fabs(r * math.sin(a / 180.0 * math.pi))\r\n            xx = math.fabs(r * math.cos(a / 180.0 * math.pi))\r\n            if (xx > 0):\r\n                res.append([x - xx - 0.015, x + xx + 0.015, y - yy - r / Nrects - 0.015, y - yy + .015])\r\n                res.append([x - xx - 0.015, x + xx + 0.015, y + yy - 0.015, y + yy + r / Nrects + 0.015])\r\n            yysum = yysum + yy\r\n        return res\r\n\r\n# internal method for keepout-processing\r\ndef applyKeepouts(lines_in, y, xi, yi, keepouts):\r\n    # print(\"  applyKeepouts(\\n  lines_in=\", lines_in, \"  \\n  y=\", y, \"   \\n  xi=\", xi, \"   yi=\", yi, \"   \\n  keepouts=\", keepouts, \")\")\r\n    lines = lines_in\r\n    changes = True\r\n    while (changes):\r\n        changes = False\r\n        for ko in keepouts:\r\n            ko = [min(ko[0], ko[1]), max(ko[0], ko[1]), min(ko[2], ko[3]), max(ko[2], ko[3])]\r\n            if (ko[yi + 0] <= y) and (y <= ko[yi + 1]):\r\n                # print(\"    INY: koy=\", [ko[yi + 0], ko[yi + 1]], \"  y=\", y, \"):             kox=\", [ko[xi + 0], ko[xi + 1]])\r\n                for li in reversed(range(0, len(lines))):\r\n                    l = lines[li]\r\n                    if (l[0] >= ko[xi + 0]) and (l[0] <= ko[xi + 1]) and (l[1] >= ko[xi + 0]) and (\r\n                                l[1] <= ko[xi + 1]):  # Line completely inside -> remove\r\n                        lines.pop(li)\r\n                        # print(\"      H1: ko=\", [ko[xi+0],ko[xi+1]], \"  li=\", li, \"   l=\", l, \")\")\r\n                        changes = True\r\n                    elif (l[0] >= ko[xi + 0]) and (l[0] <= ko[xi + 1]) and (\r\n                                l[1] > ko[\r\n                                    xi + 1]):  # Line starts inside, but ends outside -> remove and add shortened\r\n                        lines.pop(li)\r\n                        lines.append([ko[xi + 1], l[1]])\r\n                        # print(\"      H2: ko=\", [ko[xi+0],ko[xi+1]], \"  li=\", li, \"   l=\", l, \"): \", [ko[xi+1], l[1]])\r\n                        changes = True\r\n                    elif (l[0] < ko[xi + 0]) and (l[1] <= ko[xi + 1]) and (\r\n                                l[1] >= ko[\r\n                                    xi + 0]):  # Line starts outside, but ends inside -> remove and add shortened\r\n                        lines.pop(li)\r\n                        lines.append([l[0], ko[xi + 0]])\r\n                        # print(\"      H3: ko=\", [ko[xi+0],ko[xi+1]], \"  li=\", li, \"   l=\", l, \"): \", [l[0], ko[xi+0]])\r\n                        changes = True\r\n                    elif (l[0] < ko[xi + 0]) and (\r\n                                l[1] > ko[\r\n                                    xi + 1]):  # Line starts outside, and ends outside -> remove and add 2 shortened\r\n                        lines.pop(li)\r\n                        lines.append([l[0], ko[xi + 0]])\r\n                        lines.append([ko[xi + 1], l[1]])\r\n                        # print(\"      H4: ko=\", [ko[xi+0],ko[xi+1]], \"  li=\", li, \"   l=\", l, \"): \", [l[0], ko[xi+0]], [ko[xi+1], l[1]])\r\n                        changes = True\r\n                        # else:\r\n                        # print(\"      USE: ko=\", [ko[xi+0],ko[xi+1]], \"  li=\", li, \"   l=\", l, \"): \")\r\n        if changes:\r\n            break\r\n\r\n    return lines\r\n\r\n# gives True if the given point (x,y) is contained in any keepout\r\ndef containedInAnyKeepout(x,y, keepouts):\r\n    for ko in keepouts:\r\n        ko = [min(ko[0], ko[1]), max(ko[0], ko[1]), min(ko[2], ko[3]), max(ko[2], ko[3])]\r\n        if x>=ko[0] and x<=ko[1] and y>=ko[2] and y<=ko[3]:\r\n            #print(\"HIT!\")\r\n            return True\r\n    #print(\"NO HIT \",x,y)\r\n    return False\r\n\r\n# draws the keepouts\r\ndef debug_draw_keepouts(kicad_modg, keepouts):\r\n    for ko in keepouts:\r\n        kicad_modg.append(RectLine(start=[ko[0],ko[2]],\r\n                                  end=[ko[1],ko[3]],\r\n                                  layer='F.Mask', width=0.01))\r\n\r\n# split a horizontal line so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\r\ndef addHLineWithKeepout(kicad_mod, x0, x1, y, layer, width, keepouts=[], roun=0.001, dashed=False):\r\n    if dashed:\r\n        addHDLineWithKeepout(kicad_mod, x0, x1, y, layer, width, keepouts, roun)\r\n    else:\r\n        # print(\"addHLineWithKeepout\",y)\r\n        linesout = applyKeepouts([[min(x0, x1), max(x0, x1)]], y, 0, 2, keepouts)\r\n        for l in linesout:\r\n            kicad_mod.append(\r\n                Line(start=[roundG(l[0], roun), roundG(y, roun)], end=[roundG(l[1], roun), roundG(y, roun)], layer=layer,width=width))\r\n\r\n# draw a circle minding the keepouts\r\ndef addCircleWithKeepout(kicad_mod, x, y, radius, layer, width, keepouts=[], roun=0.001):\r\n    dalpha = 2 * 3.1415 / (360)\r\n    a = 0\r\n    start=0\r\n    startx=x + radius * math.sin(0)\r\n    starty=y + radius * math.cos(0)\r\n    hasToDraw=False\r\n    noneUsed=True\r\n    while a < 2 * 3.1415:\r\n        x1 = x + radius * math.sin(a)\r\n        y1 = y + radius * math.cos(a)\r\n\r\n        if containedInAnyKeepout(x1,y1, keepouts):\r\n            if hasToDraw and math.fabs(a-start)>0:\r\n                kicad_mod.append( Arc(center=[roundG(x, roun), roundG(y, roun)], start=[roundG(startx, roun), roundG(starty, roun)], angle=-1*(a - start)/3.1415*180, layer=layer, width=width))\r\n            hasToDraw = False\r\n            startx=x1; starty=y1; start=a\r\n            noneUsed = False\r\n        else:\r\n            hasToDraw = True\r\n\r\n        a = a + dalpha\r\n    if noneUsed:\r\n        kicad_mod.append(\r\n            Circle(center=[roundG(x, roun), roundG(y, roun)], radius=radius, layer=layer, width=width))\r\n    elif hasToDraw and math.fabs(a - start) > 0:\r\n        kicad_mod.append( Arc(center=[roundG(x, roun), roundG(y, roun)], start=[roundG(startx, roun), roundG(starty, roun)], angle=-1*(a - start)/3.1415*180, layer=layer, width=width))\r\n\r\n# draw an arc\r\ndef addArcByAngles(kicad_mod, x, y, radius, angle_start, angle_end, layer, width, roun=0.001):\r\n    startx = x + radius * math.sin(angle_start/180*3.1415)\r\n    starty = y + radius * math.cos(angle_start/180*3.1415)\r\n    kicad_mod.append( Arc(center=[roundG(x, roun), roundG(y, roun)], start=[roundG(startx, roun), roundG(starty, roun)], angle=-(angle_end-angle_start), layer=layer, width=width))\r\n\r\n# draw an arc minding the keepouts\r\ndef addArcByAnglesWithKeepout(kicad_mod, x, y, radius, angle_start, angle_end, layer, width, keepouts=[], roun=0.001):\r\n    startx = x + radius * math.sin(angle_start/180*3.1415)\r\n    starty = y + radius * math.cos(angle_start/180*3.1415)\r\n    addArcWithKeepout(kicad_mod, x, y, startx, starty, -(angle_end-angle_start), layer, width, keepouts, roun)\r\n\r\n# draw an arc minding the keepouts\r\ndef addArcWithKeepout(kicad_mod, x, y, startx, starty, angle, layer, width, keepouts=[], roun=0.001):\r\n    dalpha = angle/180*3.1415 / (360)\r\n    radius=math.sqrt(sqr(x-startx)+sqr(y-starty));\r\n    a = math.asin((startx-x)/radius)\r\n    if starty<0:\r\n        a=a+3.1415/2\r\n    astart=a;\r\n    aend=astart+angle/180*3.1415\r\n    start=astart\r\n    #print(radius, astart/3.1415*180, aend/3.1415*180)\r\n    istartx=x + radius * math.sin(a)\r\n    istarty=y + radius * math.cos(a)\r\n    hasToDraw=False\r\n    noneUsed=True\r\n    while a < aend:\r\n        x1 = x + radius * math.sin(a)\r\n        y1 = y + radius * math.cos(a)\r\n\r\n        if containedInAnyKeepout(x1,y1, keepouts):\r\n            if hasToDraw and math.fabs(a-start)>0:\r\n                #print('DRAW ',x1,y1)\r\n                kicad_mod.append( Arc(center=[roundG(x, roun), roundG(y, roun)], start=[roundG(istartx, roun), roundG(istarty, roun)], angle=-1*(a - start)/3.1415*180, layer=layer, width=width))\r\n            hasToDraw = False\r\n            istartx=x1; istarty=y1; start=a\r\n            noneUsed = False\r\n        else:\r\n            hasToDraw = True\r\n        #print(a, dalpha, hasToDraw, noneUsed)\r\n        a = a + dalpha\r\n    if noneUsed:\r\n        kicad_mod.append(\r\n            Arc(center=[roundG(x, roun), roundG(y, roun)], start=[roundG(startx, roun), roundG(starty, roun)], angle=angle, layer=layer, width=width))\r\n    elif hasToDraw and math.fabs(a - start) > 0:\r\n        kicad_mod.append( Arc(center=[roundG(x, roun), roundG(y, roun)], start=[roundG(istartx, roun), roundG(istarty, roun)], angle=-1*(a - start)/3.1415*180, layer=layer, width=width))\r\n\r\n# draw an ellipse with one axis along x-axis and one axis along y-axis and given width/height\r\ndef addEllipse(kicad_mod, x, y, w, h, layer, width, roun=0.001):\r\n    factor=h/w\r\n    alpha=math.atan(h/w)*2\r\n    radius=w/2/math.sin(alpha)\r\n    addArcByAngles(kicad_mod=kicad_mod, x=x, y=y+radius*math.cos(alpha), radius=radius, angle_start=180-alpha/3.1415*180, angle_end=180+alpha/3.1415*180, layer=layer, width=width, roun=roun);\r\n    addArcByAngles(kicad_mod=kicad_mod, x=x, y=y-radius*math.cos(alpha), radius=radius, angle_start=alpha/3.1415*180, angle_end=-alpha/3.1415*180, layer=layer, width=width, roun=roun);\r\n\r\n# draw an ellipse with one axis along x-axis and one axis along y-axis and given width/height\r\ndef addEllipseWithKeepout(kicad_mod, x, y, w, h, layer, width, keepouts=[], roun=0.001):\r\n    factor=h/w\r\n    alpha=math.atan(h/w)*2\r\n    radius=w/2/math.sin(alpha)\r\n    addArcByAnglesWithKeepout(kicad_mod=kicad_mod, x=x, y=y+radius*math.cos(alpha), radius=radius, angle_start=180-alpha/3.1415*180, angle_end=180+alpha/3.1415*180, keepouts=keepouts, layer=layer, width=width, roun=roun);\r\n    addArcByAnglesWithKeepout(kicad_mod=kicad_mod, x=x, y=y-radius*math.cos(alpha), radius=radius, angle_start=alpha/3.1415*180, angle_end=-alpha/3.1415*180, keepouts=keepouts, layer=layer, width=width, roun=roun);\r\n\r\n# split a circle so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\r\ndef addDCircleWithKeepout(kicad_mod, x, y, radius, layer, width, keepouts=[], roun=0.001):\r\n    dalpha = 2 * 3.1415 / (2 * 3.1415 * radius / (6 * width))\r\n    a = 0\r\n    while a < 2 * 3.1415:\r\n        x1 = x + radius * math.sin(a)\r\n        y1 = y + radius * math.cos(a)\r\n        x2 = x + radius * math.sin(a + dalpha / 2)\r\n        y2 = y + radius * math.cos(a + dalpha / 2)\r\n        ok=True\r\n        aa=a\r\n        while aa<a+dalpha and ok:\r\n            xx = x + radius * math.sin(aa)\r\n            yy = y + radius * math.cos(aa)\r\n            if containedInAnyKeepout(xx, yy, keepouts):\r\n                ok=False\r\n            aa=aa+dalpha/20\r\n        if ok: kicad_mod.append(Arc(center=[roundG(x, roun), roundG(y, roun)], start=[roundG(x1, roun), roundG(y1, roun)],\r\n                             angle=-1*dalpha / 2 / 3.1415 * 180, layer=layer, width=width))\r\n        a = a + dalpha\r\n\r\n# split an arbitrary line so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\r\ndef addLineWithKeepout(kicad_mod, x1, y1, x2,y2, layer, width, keepouts=[], roun=0.001):\r\n    dx=(x2-x1)/200\r\n    dy=(y2-y1)/200\r\n    x=x1; y=y1\r\n    xs=x1; ys=y1;\r\n    hasToDraw=not containedInAnyKeepout(x, y, keepouts)\r\n    didDrawAny=False\r\n    for n in range(0,200):\r\n        if containedInAnyKeepout(x+dx, y+dy, keepouts):\r\n            if hasToDraw:\r\n                didDrawAny=True\r\n                kicad_mod.append(Line(start=[roundG(xs, roun), roundG(ys, roun)], end=[roundG(x, roun), roundG(y, roun)], layer=layer, width=width))\r\n            xs=x+2*dx; ys=y+2*dy; hasToDraw=False\r\n        else:\r\n            hasToDraw = True\r\n\r\n        x=x+dx; y=y+dy\r\n    if hasToDraw and ((xs!=x2 or ys!=y2) or (not didDrawAny)):\r\n        kicad_mod.append(Line(start=[roundG(xs, roun), roundG(ys, roun)], end=[roundG(x2, roun), roundG(y2, roun)], layer=layer, width=width))\r\n\r\n\r\n# split an arbitrary line so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\r\ndef addPolyLineWithKeepout(kicad_mod, poly, layer, width, keepouts=[], roun=0.001):\r\n    if len(poly)>1:\r\n        for p in range(0, len(poly)-1):\r\n            addLineWithKeepout(kicad_mod, poly[p][0], poly[p][1], poly[p+1][0], poly[p+1][1], layer, width, keepouts, roun)\r\n\r\n\r\n\r\n# add a dashed circle\r\ndef addDCircle(kicad_mod, x, y, radius, layer, width, roun=0.001):\r\n    dalpha = 2 * 3.1415 / (2 * 3.1415 * radius / (6 * width))\r\n    a = 0\r\n    while a < 2 * 3.1415:\r\n        x1 = x + radius * math.sin(a)\r\n        y1 = y + radius * math.cos(a)\r\n        x2 = x + radius * math.sin(a + dalpha / 2)\r\n        y2 = y + radius * math.cos(a + dalpha / 2)\r\n        kicad_mod.append(Arc(center=[roundG(x, roun), roundG(y, roun)], start=[roundG(x1, roun), roundG(y1, roun)],\r\n                             angle=dalpha / 2 / 3.1415 + 180, layer=layer, width=width))\r\n        a = a + dalpha\r\n\r\n# draw a circle with a screw slit under 45 degrees\r\ndef addSlitScrew(kicad_mod, x, y, radius, layer, width, roun=0.001):\r\n    kicad_mod.append(Circle(center=[roundG(x, roun), roundG(y, roun)], radius=radius, layer=layer, width=width))\r\n    da = 5\r\n    dx1 = 0.99 * radius * math.sin((135 - da) / 180 * 3.1415)\r\n    dy1 = 0.99 * radius * math.cos((135 - da) / 180 * 3.1415)\r\n    dx2 = 0.99 * radius * math.sin((135 + da) / 180 * 3.1415)\r\n    dy2 = 0.99 * radius * math.cos((135 + da) / 180 * 3.1415)\r\n    dx3 = 0.99 * radius * math.sin((315 - da) / 180 * 3.1415)\r\n    dy3 = 0.99 * radius * math.cos((315 - da) / 180 * 3.1415)\r\n    dx4 = 0.99 * radius * math.sin((315 + da) / 180 * 3.1415)\r\n    dy4 = 0.99 * radius * math.cos((315 + da) / 180 * 3.1415)\r\n    # print(x,y,dx1,dy1,dx4,dy4)\r\n    kicad_mod.append(Line(start=[roundG(x + dx1, roun), roundG(y + dy1, roun)],\r\n                          end=[roundG(x + dx4, roun), roundG(y + dy4, roun)], layer=layer, width=width))\r\n    kicad_mod.append(Line(start=[roundG(x + dx2, roun), roundG(y + dy2, roun)],\r\n                          end=[roundG(x + dx3, roun), roundG(y + dy3, roun)], layer=layer, width=width))\r\n\r\n# draw a circle with a screw slit under 45 degrees\r\ndef addSlitScrewWithKeepouts(kicad_mod, x, y, radius, layer, width, keepouts, roun=0.001):\r\n    addCircleWithKeepout(kicad_mod, x, y, radius, layer, width, keepouts, roun)\r\n    da = 5\r\n    dx1 = 0.99 * radius * math.sin((135 - da) / 180 * 3.1415)\r\n    dy1 = 0.99 * radius * math.cos((135 - da) / 180 * 3.1415)\r\n    dx2 = 0.99 * radius * math.sin((135 + da) / 180 * 3.1415)\r\n    dy2 = 0.99 * radius * math.cos((135 + da) / 180 * 3.1415)\r\n    dx3 = 0.99 * radius * math.sin((315 - da) / 180 * 3.1415)\r\n    dy3 = 0.99 * radius * math.cos((315 - da) / 180 * 3.1415)\r\n    dx4 = 0.99 * radius * math.sin((315 + da) / 180 * 3.1415)\r\n    dy4 = 0.99 * radius * math.cos((315 + da) / 180 * 3.1415)\r\n    # print(x,y,dx1,dy1,dx4,dy4)\r\n    addLineWithKeepout(kicad_mod,x + dx1, y + dy1, x + dx4, y + dy4, layer, width, keepouts)\r\n    addLineWithKeepout(kicad_mod, x + dx2, y + dy2, x + dx3, y + dy3, layer, width, keepouts)\r\n\r\n\r\n# draw a circle with a cross-screw under 45 deg\r\ndef addCrossScrew(kicad_mod, x, y, radius, layer, width, roun=0.001):\r\n    kicad_mod.append(Circle(center=[roundG(x, roun), roundG(y, roun)], radius=radius, layer=layer, width=width))\r\n\r\n    kkt = Translation(x, y)\r\n    kicad_mod.append(kkt)\r\n    dd = radius * 0.1 / 2\r\n    dw = 0.8 * radius\r\n    kkt.append(PolygoneLine(polygone=[[roundG(-dw, roun), roundG(-dd, roun)],\r\n                                      [roundG(-dd, roun), roundG(-dd, roun)],\r\n                                      [roundG(-dd, roun), roundG(-dw, roun)],\r\n                                      [roundG(+dd, roun), roundG(-dw, roun)],\r\n                                      [roundG(+dd, roun), roundG(-dd, roun)],\r\n                                      [roundG(+dw, roun), roundG(-dd, roun)],\r\n                                      [roundG(+dw, roun), roundG(+dd, roun)],\r\n                                      [roundG(+dd, roun), roundG(+dd, roun)],\r\n                                      [roundG(+dd, roun), roundG(+dw, roun)],\r\n                                      [roundG(-dd, roun), roundG(+dw, roun)],\r\n                                      [roundG(-dd, roun), roundG(+dd, roun)],\r\n                                      [roundG(-dw, roun), roundG(+dd, roun)],\r\n                                      [roundG(-dw, roun), roundG(-dd, roun)]], layer=layer, width=width))\r\n\r\n\r\n# draw a circle with a cross-screw under 45 deg\r\ndef addCrossScrewWithKeepouts(kicad_mod, x, y, radius, layer, width, keepouts=[], roun=0.001):\r\n    addCircleWithKeepout(kicad_mod, x, y, radius, layer, width, keepouts, roun)\r\n\r\n    kkt = Translation(x, y)\r\n    kicad_mod.append(kkt)\r\n    dd = radius * 0.1 / 2\r\n    dw = 0.8 * radius\r\n    polygone = [[roundG(-dw, roun), roundG(-dd, roun)],\r\n                [roundG(-dd, roun), roundG(-dd, roun)],\r\n                [roundG(-dd, roun), roundG(-dw, roun)],\r\n                [roundG(+dd, roun), roundG(-dw, roun)],\r\n                [roundG(+dd, roun), roundG(-dd, roun)],\r\n                [roundG(+dw, roun), roundG(-dd, roun)],\r\n                [roundG(+dw, roun), roundG(+dd, roun)],\r\n                [roundG(+dd, roun), roundG(+dd, roun)],\r\n                [roundG(+dd, roun), roundG(+dw, roun)],\r\n                [roundG(-dd, roun), roundG(+dw, roun)],\r\n                [roundG(-dd, roun), roundG(+dd, roun)],\r\n                [roundG(-dw, roun), roundG(+dd, roun)],\r\n                [roundG(-dw, roun), roundG(-dd, roun)]];\r\n    addPolyLineWithKeepout(kicad_mod, polygone, layer, width, keepouts)\r\n\r\n\r\n# split a vertical line so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\r\ndef addVLineWithKeepout(kicad_mod, x, y0, y1, layer, width, keepouts=[], roun=0.001, dashed=False):\r\n    if dashed:\r\n        addVDLineWithKeepout(kicad_mod, x, y0, y1, layer, width, keepouts, roun)\r\n    else:\r\n        # print(\"addVLineWithKeepout\",x)\r\n        linesout = applyKeepouts([[min(y0, y1), max(y0, y1)]], x, 2, 0, keepouts)\r\n        for l in linesout:\r\n            kicad_mod.append(\r\n                Line(start=[roundG(x, roun), roundG(l[0], roun)], end=[roundG(x, roun), roundG(l[1], roun)], layer=layer,\r\n                     width=width))\r\n\r\n# split a dashed horizontal line so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\r\ndef addHDLineWithKeepout(kicad_mod, x0, x1, y, layer, width, keepouts=[], roun=0.001):\r\n    dx=3*width\r\n    x=min(x0,x1)\r\n    while x<max(x0,x1):\r\n        addHLineWithKeepout(kicad_mod, x,min(x+dx,x1), y, layer, width, keepouts, roun)\r\n        x=x+dx*2\r\n\r\n# split a dashed vertical line so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\r\ndef addVDLineWithKeepout(kicad_mod, x, y0, y1, layer, width, keepouts=[], roun=0.001):\r\n    dy = 3 * width\r\n    y = min(y0, y1)\r\n    while y < max(y0, y1):\r\n        addVLineWithKeepout(kicad_mod, x, y, min(y1,y+dy), layer, width, keepouts, roun)\r\n        y = y + dy * 2\r\n\r\n\r\n\r\n# split a rectangle\r\ndef addRectWith(kicad_mod, x, y, w, h, layer, width, roun=0.001):\r\n\tkicad_mod.append(RectLine(start=[roundG(x, roun),roundG(y, roun)], end=[roundG(x+w, roun),roundG(y+h, roun)], layer=layer, width=width))\r\n\r\n\r\n# split a rectangle so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\r\ndef addRectWithKeepout(kicad_mod, x, y, w, h, layer, width, keepouts=[], roun=0.001):\r\n    addHLineWithKeepout(kicad_mod, x, x+w, y, layer,width,keepouts,roun)\r\n    addHLineWithKeepout(kicad_mod, x, x + w, y+h, layer, width, keepouts, roun)\r\n    addVLineWithKeepout(kicad_mod, x, y, y+h, layer, width, keepouts, roun)\r\n    addVLineWithKeepout(kicad_mod, x+w, y, y + h, layer, width, keepouts, roun)\r\n\r\n# split a rectangle so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\r\ndef addRectAndTLMarkWithKeepout(kicad_mod, x, y, w, h, mark_len, layer, width, keepouts=[], roun=0.001):\r\n    addHLineWithKeepout(kicad_mod, x, x+w, y, layer,width,keepouts,roun)\r\n    addHLineWithKeepout(kicad_mod, x, x + w, y+h, layer, width, keepouts, roun)\r\n    addVLineWithKeepout(kicad_mod, x, y, y+h, layer, width, keepouts, roun)\r\n    addVLineWithKeepout(kicad_mod, x+w, y, y + h, layer, width, keepouts, roun)\r\n    addHLineWithKeepout(kicad_mod, x-2*width, x+mark_len, y-2*width, layer,width,keepouts,roun)\r\n    addVLineWithKeepout(kicad_mod, x-2*width, y-2*width, y+mark_len, layer,width,keepouts,roun)\r\n\r\n\r\n# split a dashed rectangle so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\r\ndef addDRectWithKeepout(kicad_mod, x, y, w, h, layer, width, keepouts=[], roun=0.001):\r\n    addHDLineWithKeepout(kicad_mod, x, x+w, y, layer,width,keepouts,roun)\r\n    addHDLineWithKeepout(kicad_mod, x, x + w, y+h, layer, width, keepouts, roun)\r\n    addVDLineWithKeepout(kicad_mod, x, y, y+h, layer, width, keepouts, roun)\r\n    addVDLineWithKeepout(kicad_mod, x+w, y, y + h, layer, width, keepouts, roun)\r\n\r\n# split a plus sign so it does not interfere with keepout areas defined as [[x0,x1,y0,y1], ...]\r\ndef addPlusWithKeepout(km, x, y, w, h, layer, width, keepouts=[], roun=0.001):\r\n    addHLineWithKeepout(km, x, x+w, y+h/2, layer,width,keepouts,roun)\r\n    addVLineWithKeepout(km, x+w/2, y, y+h, layer, width, keepouts, roun)\r\n\r\n# draw a rectangle with bevel on all sides (e.g. for crystals), or a simple rectangle if bevel_size0=0)\r\n#\r\n#   /----\\\r\n#  /      \\\r\n# |        |\r\n# |        |\r\n# |        |\r\n# |        |\r\n# |        |\r\n#  \\      /\r\n#   \\----/\r\ndef allBevelRect(model, x, size, layer, width, bevel_size=0.2):\r\n    if bevel_size <= 0:\r\n        model.append(RectLine(start=x, end=[x[0] + size[0], x[1] + size[1]], layer=layer, width=width))\r\n    else:\r\n        model.append(PolygoneLine(polygone=[[x[0] + bevel_size, x[1]],\r\n                                            [x[0] + size[0] - bevel_size, x[1]],\r\n                                            [x[0] + size[0], x[1] + bevel_size],\r\n                                            [x[0] + size[0], x[1] + size[1] - bevel_size],\r\n                                            [x[0] + size[0] - bevel_size, x[1] + size[1]],\r\n                                            [x[0] + bevel_size, x[1] + size[1]],\r\n                                            [x[0], x[1] + size[1] - bevel_size],\r\n                                            [x[0], x[1] + bevel_size],\r\n                                            [x[0] + bevel_size, x[1]]], layer=layer, width=width))\r\n\r\n# draw a trapezoid with a given angle of the vertical lines\r\n#\r\n# angle<0\r\n#      /---------------------\\     ^\r\n#     /                       \\    |\r\n#    /                         \\  size[1]\r\n#   /                           \\  |\r\n#  /-----------------------------\\ v\r\n#  <------------size[0]---------->\r\ndef allTrapezoid(model, x, size, angle, layer, width):\r\n    dx=size[1]*math.tan(math.fabs(angle)/180*math.pi)\r\n    if angle == 0:\r\n        model.append(RectLine(start=x, end=[x[0] + size[0], x[1] + size[1]], layer=layer, width=width))\r\n    elif angle<0:\r\n        model.append(PolygoneLine(polygone=[[x[0] + dx, x[1]],\r\n                                            [x[0] + size[0] - dx, x[1]],\r\n                                            [x[0] + size[0], x[1] + size[1]],\r\n                                            [x[0], x[1] + size[1] ],\r\n                                            [x[0] + dx, x[1]]], layer=layer, width=width))\r\n    elif angle>0:\r\n        model.append(PolygoneLine(polygone=[[x[0], x[1]],\r\n                                            [x[0] + size[0], x[1]],\r\n                                            [x[0] + size[0]-dx, x[1] + size[1]],\r\n                                            [x[0] + dx, x[1] + size[1] ],\r\n                                            [x[0] , x[1]]], layer=layer, width=width))\r\n\r\n# draw a downward equal-sided triangle\r\ndef allEqualSidedDownTriangle(model, xcenter, side_length, layer, width):\r\n    h=sqrt(3)/6*side_length\r\n    model.append(PolygoneLine(polygone=[[xcenter[0]-side_length/2, xcenter[1]-h],\r\n                                        [xcenter[0]+side_length/2, xcenter[1]-h],\r\n                                        [xcenter[0], xcenter[1]+2*h],\r\n                                        [xcenter[0]-side_length/2, xcenter[1]-h],\r\n                                       ], layer=layer, width=width))\r\n\r\n# draw a trapezoid with a given angle of the vertical lines and rounded corners\r\n#\r\n# angle<0\r\n#      /---------------------\\     ^\r\n#     /                       \\    |\r\n#    /                         \\  size[1]\r\n#   /                           \\  |\r\n#  /-----------------------------\\ v\r\n#  <------------size[0]---------->\r\ndef allRoundedBevelRect(model, x, size, angle, corner_radius, layer, width):\r\n    if corner_radius<=0:\r\n        allTrapezoid(model,x,size,angle,layer,width)\r\n    else:\r\n        dx=size[1]*math.tan(math.fabs(angle)/180*math.pi)\r\n        dx2=corner_radius*math.tan((90-math.fabs(angle))/2/180*math.pi)\r\n        dx3=corner_radius/math.tan((90-math.fabs(angle))/2/180*math.pi)\r\n        ds2=corner_radius*math.sin(math.fabs(angle)/180*math.pi)\r\n        dc2=corner_radius*math.cos(math.fabs(angle)/180*math.pi)\r\n\r\n        if angle == 0:\r\n            addRoundedRect(model, x, size, corner_radius, layer, width=0.2)\r\n        elif angle<0:\r\n            ctl=[x[0] +dx+dx2, x[1]+corner_radius]\r\n            ctr=[x[0] + size[0]-dx-dx2, x[1]+corner_radius]\r\n            cbl=[x[0] +dx3, x[1]+size[1]-corner_radius]\r\n            cbr=[x[0] + size[0]-dx3, x[1]+size[1]-corner_radius]\r\n            model.append(Arc(center=ctl, start=[ctl[0], x[1]], angle=-(90-math.fabs(angle)),layer=layer, width=width))\r\n            model.append(Arc(center=ctr, start=[ctr[0], x[1]], angle=(90-math.fabs(angle)),layer=layer, width=width))\r\n            model.append(Arc(center=cbl, start=[cbl[0], x[1]+size[1]], angle=(90+math.fabs(angle)),layer=layer, width=width))\r\n            model.append(Arc(center=cbr, start=[cbr[0], x[1]+size[1]], angle=-(90+math.fabs(angle)),layer=layer, width=width))\r\n            model.append(Line(start=[ctl[0], x[1]], end=[ctr[0], x[1]], layer=layer, width=width))\r\n            model.append(Line(start=[cbl[0], x[1]+size[1]], end=[cbr[0], x[1]+size[1]], layer=layer, width=width))\r\n            model.append(Line(start=[ctr[0]+dc2,ctr[1]-ds2], end=[cbr[0]+dc2,cbr[1]-ds2], layer=layer, width=width))\r\n            model.append(Line(start=[ctl[0]-dc2,ctl[1]-ds2], end=[cbl[0]-dc2,cbl[1]-ds2], layer=layer, width=width))\r\n        elif angle>0:\r\n            cbl=[x[0] +dx+dx2, x[1]+size[1]-corner_radius]\r\n            cbr=[x[0] + size[0]-dx-dx2, x[1]+size[1]-corner_radius]\r\n            ctl=[x[0] +dx3, x[1]+corner_radius]\r\n            ctr=[x[0] + size[0]-dx3, x[1]+corner_radius]\r\n            model.append(Arc(center=ctl, start=[ctl[0], x[1]], angle=-(90+math.fabs(angle)),layer=layer, width=width))\r\n            model.append(Arc(center=ctr, start=[ctr[0], x[1]], angle=(90+math.fabs(angle)),layer=layer, width=width))\r\n            model.append(Arc(center=cbl, start=[cbl[0], x[1]+size[1]], angle=(90-math.fabs(angle)),layer=layer, width=width))\r\n            model.append(Arc(center=cbr, start=[cbr[0], x[1]+size[1]], angle=-(90-math.fabs(angle)),layer=layer, width=width))\r\n            model.append(Line(start=[ctl[0], x[1]], end=[ctr[0], x[1]], layer=layer, width=width))\r\n            model.append(Line(start=[cbl[0], x[1]+size[1]], end=[cbr[0], x[1]+size[1]], layer=layer, width=width))\r\n            model.append(Line(start=[ctr[0]+dc2,ctr[1]+ds2], end=[cbr[0]+dc2,cbr[1]+ds2], layer=layer, width=width))\r\n            model.append(Line(start=[ctl[0]-dc2,ctl[1]+ds2], end=[cbl[0]-dc2,cbl[1]+ds2], layer=layer, width=width))\r\n\r\n\r\n# draw a rectangle with rounded corners on all sides (e.g. for crystals), or a simple rectangle if bevel_size0=0)\r\n#\r\n#   /----\\\r\n#  /      \\\r\n# |        |\r\n# |        |\r\n# |        |\r\n# |        |\r\n# |        |\r\n#  \\      /\r\n#   \\----/\r\ndef addRoundedRect(model, x, size, corner_radius, layer, width=0.2):\r\n    if corner_radius <= 0:\r\n        model.append(RectLine(start=x, end=[x[0] + size[0], x[1] + size[1]], layer=layer, width=width))\r\n    else:\r\n        model.append(Line(start=[x[0] + corner_radius, x[1]], end=[x[0] + size[0] - corner_radius, x[1]], layer=layer, width=width))\r\n        model.append(Line(start=[x[0] + size[0], x[1] + corner_radius], end=[x[0] + size[0], x[1] + size[1] - corner_radius], layer=layer, width=width))\r\n        model.append(Line(start=[x[0] + size[0] - corner_radius, x[1] + size[1]], end=[x[0] + corner_radius, x[1] + size[1]], layer=layer, width=width))\r\n        model.append(Line(start=[x[0], x[1] + size[1] - corner_radius], end=[x[0], x[1] + corner_radius], layer=layer, width=width))\r\n        model.append(Arc(center=[x[0]+corner_radius, x[1] +corner_radius], start=[x[0], x[1] +corner_radius], angle=90, layer=layer, width=width))\r\n        model.append(Arc(center=[x[0]+ size[0]-corner_radius, x[1] +corner_radius], start=[x[0]+ size[0]-corner_radius, x[1]], angle=90, layer=layer, width=width))\r\n        model.append(Arc(center=[x[0]+corner_radius, x[1] +size[1]-corner_radius], start=[x[0], x[1] +size[1]-corner_radius], angle=-90, layer=layer, width=width))\r\n        model.append(Arc(center=[x[0]+ size[0]-corner_radius, x[1] +size[1]-corner_radius], start=[x[0]+ size[0], x[1] +size[1]-corner_radius], angle=90, layer=layer, width=width))\r\n\r\n\r\n\r\n# draws a filled circle consisting of concentric circles of varying widths (e.g. for glue dots!)\r\ndef fillCircle(model, center, radius, layer, width):\r\n    model.append(Circle(center=center, radius=radius, layer=layer, width=width))\r\n    r = radius\r\n    w = radius / 3\r\n    r = radius - w / 2\r\n    while r > w / 2:\r\n        if r - 0.9 * w <= w / 2:\r\n            model.append(Circle(center=center, radius=r, layer=layer, width=r * 2))\r\n        else:\r\n            model.append(Circle(center=center, radius=r, layer=layer, width=w))\r\n        r = r - 0.9 * w\r\n\r\n\r\n\r\n#     +------+\r\n#    /       |\r\n#   /        |\r\n#   |        |\r\n#   |        |\r\n#   |        |\r\n#   |        |\r\n#   +--------+\r\n#\r\n#\r\ndef bevelRectTL(model, x, size, layer, width, bevel_size=1):\r\n    model.append(PolygoneLine(\r\n        polygone=[[x[0] + bevel_size, x[1]], [x[0] + size[0], x[1]], [x[0] + size[0], x[1] + size[1]],\r\n                  [x[0], x[1] + size[1]], [x[0], x[1] + bevel_size], [x[0] + bevel_size, x[1]]], layer=layer,\r\n        width=width))\r\n\r\n\r\n#   +--------+\r\n#   |        |\r\n#   |        |\r\n#   |        |\r\n#   |        |\r\n#   \\        |\r\n#    \\       |\r\n#     +------+\r\n#\r\n#\r\ndef bevelRectBL(model, x, size, layer, width, bevel_size=1):\r\n    model.append(PolygoneLine(polygone=[[x[0], x[1]], [x[0] + size[0], x[1]], [x[0] + size[0], x[1] + size[1]],\r\n                                        [x[0] + bevel_size, x[1] + size[1]], [x[0], x[1] + size[1] - bevel_size],\r\n                                        [x[0], x[1]]], layer=layer, width=width))\r\n\r\n# draws a DIP-package with half-circle at the top\r\n#\r\n# +----------+\r\n# |   \\  /   |\r\n# |    ~~    |\r\n# |          |\r\n# |          |\r\n# |          |\r\n# |          |\r\n# +----------+\r\ndef DIPRectT(model, x, size, layer, width, marker_size=2):\r\n    model.append(PolygoneLine(\r\n        polygone=[[x[0] + size[0] / 2 - marker_size / 2, x[1]], [x[0], x[1]], [x[0], x[1] + size[1]],\r\n                  [x[0] + size[0], x[1] + size[1]], [x[0] + size[0], x[1]],\r\n                  [x[0] + size[0] / 2 + marker_size / 2, x[1]]], layer=layer, width=width))\r\n    model.append(Arc(center=[x[0] + size[0] / 2, x[1]], start=[x[0] + size[0] / 2 - marker_size / 2, x[1]], angle=-180,\r\n                     layer=layer, width=width))\r\n\r\n\r\n# draws a DIP-package with half-circle at the left\r\n#\r\n# +---------------+\r\n# |-\\             |\r\n# |  |            |\r\n# |-/             |\r\n# +---------------+\r\ndef DIPRectL(model, x, size, layer, width, marker_size=2):\r\n    model.append(PolygoneLine(polygone=[[x[0], x[1] + size[1] / 2 - marker_size / 2],\r\n                                        [x[0], x[1]],\r\n                                        [x[0] + size[0], x[1]],\r\n                                        [x[0] + size[0], x[1] + size[1]],\r\n                                        [x[0], x[1] + size[1]],\r\n                                        [x[0], x[1] + size[1] / 2 + marker_size / 2]], layer=layer, width=width))\r\n    model.append(Arc(center=[x[0], x[1] + size[1] / 2], start=[x[0], x[1] + size[1] / 2 - marker_size / 2], angle=180,\r\n                     layer=layer, width=width))\r\n\r\n\r\n# draws the left part of a DIP-package with half-circle at the left\r\n#\r\n# +--------\r\n# |-\\\r\n# |  |\r\n# |-/\r\n# +--------\r\ndef DIPRectL_LeftOnly(model, x, size, layer, width, marker_size=2):\r\n    model.append(Line(start=[x[0], x[1] + size[1] / 2 - marker_size / 2], end=[x[0], x[1]], layer=layer, width=width))\r\n    model.append(\r\n        Line(start=[x[0], x[1] + size[1]], end=[x[0], x[1] + size[1] / 2 + marker_size / 2], layer=layer, width=width))\r\n    if size[0] > 0:\r\n        model.append(Line(start=[x[0], x[1]], end=[x[0] + size[0], x[1]], layer=layer, width=width))\r\n        model.append(Line(start=[x[0], x[1] + size[1]], end=[x[0] + size[0], x[1] + size[1]], layer=layer, width=width))\r\n\r\n    model.append(Arc(center=[x[0], x[1] + size[1] / 2], start=[x[0], x[1] + size[1] / 2 - marker_size / 2], angle=180,\r\n                     layer=layer, width=width))\r\n\r\n\r\n# draws a THT quartz footprint (HC49) with a rect around it\r\n#  +-------------------------+\r\n#  |                         |\r\n#  |   +----------------+    |\r\n#  |  /                  \\   |\r\n#  |  \\                  /   |\r\n#  |   +----------------+    |\r\n#  |                         |\r\n#  +-------------------------+\r\ndef THTQuartzRect(model, x, size, inner_size, layer, width):\r\n    model.append(RectLine(start=x, end=[x[0] + size[0], x[1] + size[1]], layer=layer, width=width))\r\n    THTQuartz(model, [x[0] + (size[0] - inner_size[0]) / 2, x[1] + (size[1] - inner_size[1]) / 2], inner_size, layer,\r\n              width)\r\n\r\n\r\n# draws a THT quartz footprint (HC49)\r\n#     +----------------+\r\n#    /                  \\\r\n#    \\                  /\r\n#     +----------------+\r\ndef THTQuartz(model, x, size, layer, width):\r\n    THTQuartzIncomplete(model, x, size, 180, layer, width)\r\n\r\n\r\n# draws a THT quartz footprint (HC49)\r\n#     +----------------+\r\n#    /                  \\\r\n#    \\                  /\r\n#     +----------------+\r\ndef THTQuartzIncomplete(model, x, size, angle, layer, width):\r\n    inner_size = size\r\n    r = inner_size[1] / 2\r\n    xtl = [x[0] + size[0] / 2 - (inner_size[0] / 2 - r), x[1] + size[1] / 2 - inner_size[1] / 2]\r\n    xtr = [x[0] + size[0] / 2 + (inner_size[0] / 2 - r), x[1] + size[1] / 2 - inner_size[1] / 2]\r\n    xbl = [x[0] + size[0] / 2 - (inner_size[0] / 2 - r), x[1] + size[1] / 2 + inner_size[1] / 2]\r\n    xbr = [x[0] + size[0] / 2 + (inner_size[0] / 2 - r), x[1] + size[1] / 2 + inner_size[1] / 2]\r\n    cl = [x[0] + size[0] / 2 - (inner_size[0] / 2 - r), x[1] + size[1] / 2]\r\n    cr = [x[0] + size[0] / 2 + (inner_size[0] / 2 - r), x[1] + size[1] / 2]\r\n    model.append(Line(start=xtl, end=xtr, layer=layer, width=width))\r\n    model.append(Line(start=xbl, end=xbr, layer=layer, width=width))\r\n    if angle >= 180:\r\n        model.append(Arc(center=cl, start=xtl, angle=-angle, layer=layer, width=width))\r\n        model.append(Arc(center=cr, start=xtr, angle=angle, layer=layer, width=width))\r\n    else:\r\n        model.append(Arc(center=cl, start=xtl, angle=-angle, layer=layer, width=width))\r\n        model.append(Arc(center=cr, start=xtr, angle=angle, layer=layer, width=width))\r\n        model.append(Arc(center=cl, start=xbl, angle=angle, layer=layer, width=width))\r\n        model.append(Arc(center=cr, start=xbr, angle=-angle, layer=layer, width=width))\r\n\r\n#\r\n# This is an alternative to using silk keepout areas for simple cases.\r\n# It calculates a new endpoint for a horizontal or vertical line such that\r\n# the silk line has the correct minimal clearance. If the line is to short\r\n# given the default clearance, the clearance is reduced and new points are\r\n# calculated.\r\n#\r\n# Parameters:\r\n#   - pad_size, pad_position, and pad_radius are the dimensions of the reference pad.\r\n#     (pad that is expected to be intersected by the line)\r\n#   - fixed_point: The fixed reference point\r\n#   - moving_point: The point that will be moved (toward the fixed point)\r\n#     if the line intersects the pads clearance area.\r\n#   - silk_pad_offset: offset between edge of the pad and silk line center.\r\n#   - min_lenght: minimum silk line length\r\n#\r\n# Returns a new point along the line or None if no valid point could be found\r\n#\r\ndef nearestSilkPointOnOrthogonalLineSmallClerance(pad_size, pad_position, pad_radius, fixed_point, moving_point,\r\n        silk_pad_offset_default, silk_pad_offset_reduced, min_lenght):\r\n    if silk_pad_offset_reduced < silk_pad_offset_default:\r\n        offset = (silk_pad_offset_default, silk_pad_offset_reduced)\r\n    else:\r\n        offset = (silk_pad_offset_default)\r\n\r\n    for silk_pad_offset in (silk_pad_offset_default, silk_pad_offset_reduced):\r\n        point = nearestSilkPointOnOrthogonalLine(\r\n                pad_size, pad_position, pad_radius, fixed_point, moving_point,\r\n                silk_pad_offset, min_lenght)\r\n        if point is not None:\r\n            return point\r\n    return None\r\n\r\n#\r\n# This is an alternative to using silk keepout areas for simple cases.\r\n# It calculates a new endpoint for a horizontal or vertical line such that\r\n# the silk line has the correct minimal clearance.\r\n#\r\n# Parameters:\r\n#   - pad_size, pad_position, and pad_radius are the dimensions of the reference pad.\r\n#     (pad that is expected to be intersected by the line)\r\n#   - fixed_point: The fixed reference point\r\n#   - moving_point: The point that will be moved (toward the fixed point)\r\n#     if the line intersects the pads clearance area.\r\n#   - silk_pad_offset: offset between edge of the pad and silk line center.\r\n#   - min_lenght: minimum silk line length\r\n#\r\n# Returns a new point along the line or None if no valid point could be found\r\n#\r\ndef nearestSilkPointOnOrthogonalLine(pad_size, pad_position, pad_radius, fixed_point, moving_point,\r\n        silk_pad_offset, min_lenght):\r\n    if fixed_point[0] == moving_point[0]:\r\n        normal_dir_idx = 0\r\n    elif fixed_point[1] == moving_point[1]:\r\n        normal_dir_idx = 1\r\n    else:\r\n        raise ValueError(\"nearestSilkPointOnOrthogonalLine only works for horizontal or vertical lines. \\n\"\r\n                        \"(Either x or y coordinate of the two reference points must be equal)\")\r\n\r\n    inline_dir_idx = (normal_dir_idx+1)%2\r\n\r\n    line_pad_offset = fixed_point[normal_dir_idx] - pad_position[normal_dir_idx]\r\n\r\n    rc_normal_dir = pad_size[normal_dir_idx]/2-pad_radius\r\n\r\n    sign = 1 if pad_position[inline_dir_idx] - fixed_point[inline_dir_idx] > 0 else -1\r\n    ep_new = Vector2D(moving_point)\r\n\r\n    if rc_normal_dir < line_pad_offset:\r\n        # the silk outline is in the area where the radius of the pad is.\r\n\r\n        dr_normal_dir = line_pad_offset - rc_normal_dir\r\n\r\n        r = pad_radius + silk_pad_offset\r\n\r\n        # rounding to avoid floating point errors\r\n        if round(dr_normal_dir, 6) >= round(r, 6):\r\n            return moving_point\r\n\r\n        dr_inline = sqrt(r**2 - dr_normal_dir**2)\r\n\r\n        ep_new[inline_dir_idx] =  pad_position[inline_dir_idx] -\\\r\n            sign*(pad_size[inline_dir_idx]/2 - (pad_radius-dr_inline))\r\n    else:\r\n        ep_new[inline_dir_idx] =  pad_position[inline_dir_idx] -\\\r\n            sign*(pad_size[inline_dir_idx]/2 + silk_pad_offset)\r\n\r\n    if sign*(ep_new[inline_dir_idx] - fixed_point[inline_dir_idx]) <  min_lenght:\r\n        return None\r\n\r\n    if abs(ep_new[inline_dir_idx] - fixed_point[inline_dir_idx]) > math.fabs(moving_point[inline_dir_idx] - fixed_point[inline_dir_idx]):\r\n        return moving_point\r\n\r\n    return ep_new\r\n"
  },
  {
    "path": "scripts/tools/footprint_global_properties.py",
    "content": "#!/usr/bin/env python\r\n\r\nimport sys\r\nimport os\r\nimport math\r\n\r\n# ensure that the kicad-footprint-generator directory is available\r\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\r\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\r\n\r\nfrom KicadModTree import *  # NOQA\r\nfrom drawing_tools import *\r\n\r\ncrt_offset = 0.25\r\nlw_fab = 0.1\r\nlw_crt = 0.05\r\nlw_slk = 0.12\r\nslk_offset = lw_slk/2\r\nslk_pad_offset = lw_slk/2+0.2\r\ntxt_offset = 1\r\ngrid_crt=0.01\r\nmin_pad_distance=0.2\r\nfab_text_size_min=0.25\r\nfab_text_size_max=2.00\r\n"
  },
  {
    "path": "scripts/tools/footprint_keepout_area.py",
    "content": "# Kicad currently does not support adding keepout zones directly to footprints\n# For this reason the library maintainance team decided to communicate keepouts as follows:\n#  - A polygone outlining the keepout area (on layer Dwgs.User)\n#  - Hatching of this area on the same layer\n#  - Text on Cmts.User: KEEPOUT (with additional information if necessary)\n\nimport sys, os\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nfrom KicadModTree import *  # NOQA\nfrom math import sqrt\n\nKEEPOUT_DEFAULT_CONFIG={\n    'graphical_layer':'Dwgs.User',\n    'line_width': 0.1,\n    'hatching_spacing': 2,\n    'text':{\n        'size':[1,1],\n        'fontwidth':0.15,\n        'position':'center',\n        'layer':'Cmts.User'\n    }\n}\ndef addRectangularKeepout(kicad_mod, center, size, text='KEEPOUT', config=KEEPOUT_DEFAULT_CONFIG):\n    keepout_edges={\n        'left': center[0] - (size[0] / 2),\n        'top': center[1] - (size[1] / 2)\n    }\n    keepout_edges['right'] = keepout_edges['left'] + size[0]\n    keepout_edges['bottom'] = keepout_edges['top'] + size[1]\n    kicad_mod.append(RectLine(\n        start=[keepout_edges['left'], keepout_edges['top']],\n        end=[keepout_edges['right'], keepout_edges['bottom']],\n        layer=config['graphical_layer'], width=config['line_width']))\n\n    if size[0] >= size[1]:\n        rot = 0\n        longer_size = size[0]\n    else:\n        longer_size = size[1]\n        rot = 90\n\n    fs = round(longer_size/len(text), 2)\n    if fs > config['text']['size'][0]:\n        size = config['text']['size']\n        thickness = config['text']['fontwidth']\n    else:\n        size = [fs, fs]\n        thickness = config['text']['fontwidth'] * fs\n\n\n    kicad_mod.append(Text(type='user', text=text,\n        at=center, rotation=rot,\n        layer=config['text']['layer'], size=size,\n        thickness=thickness))\n\n\n    p1 = {'x':keepout_edges['left'], 'y':keepout_edges['top']}\n    p2 = {'x':keepout_edges['left'], 'y':keepout_edges['top']}\n    # 45° hatching\n    step = config['hatching_spacing']\n    step_x = step/sqrt(2)\n    step_y = step_x\n\n    p1_direction = 'move_right'\n    p2_direction = 'move_down'\n\n    while (1):\n        if p1_direction == 'move_right':\n            p1['x'] += step_x\n            if p1['x'] > keepout_edges['right']:\n                p1_direction = 'move_down'\n                dx = keepout_edges['right'] - (p1['x'] - step_x)\n                dy = step_y - dx\n                p1['x'] = keepout_edges['right']\n                p1['y'] += dy\n        else:\n            p1['y'] += step_y\n\n\n        if p2_direction == 'move_down':\n            p2['y'] += step_y\n            if p2['y'] > keepout_edges['bottom']:\n                p2_direction = 'move_right'\n                dy = keepout_edges['bottom'] - (p2['y'] - step_y)\n                dx = step_x - dy\n                p2['x'] += dx\n                p2['y'] = keepout_edges['bottom']\n        else:\n            p2['x'] += step_x\n\n        if p1['y'] > keepout_edges['bottom']:\n            return\n\n        kicad_mod.append(Line(start=p1, end=p2,\n            layer=config['graphical_layer'], width=config['line_width']))\n"
  },
  {
    "path": "scripts/tools/footprint_scripts_DIP.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom drawing_tools import *  # NOQA\n\n\n#    overlen_top                           overlen_bottom\n#  <--->                                 <------>\n#       O          O          O          O                             ^\n#       |          |          |          |                             |\n#  +--------------------------------------------+    ^                 |\n#  |                                            |    |                 |\n#  +--+                                         |    |                 |\n#     |                                         | package_width        |\n#  +--+                                         |    |           pinrow_distance\n#  |                                            |    |                 |\n#  +--------------------------------------------+    v                 |\n#       |          |          |          |                             |\n#       O          O          O          O                             v\n#\n#       <----RM---->\ndef makeDIP(pins, rm, pinrow_distance_in, package_width, overlen_top, overlen_bottom, ddrill, pad, smd_pads=False,\n            socket_width=0, socket_height=0, socket_pinrow_distance_offset=0, tags_additional=[],\n            lib_name=\"Package_DIP\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0], DIPName='DIP', DIPDescription='though-hole mounted DIP', DIPTags='THT DIP DIL PDIP', \n            prefix_name = \"\", skip_pin = [], skip_count = False, right_cnt_start = -1):\n\n    pinrow_distance = pinrow_distance_in + socket_pinrow_distance_offset\n    h_fab = (pins / 2 - 1) * rm + overlen_top + overlen_bottom\n    w_fab = package_width\n    l_fab = (pinrow_distance - w_fab) / 2\n    t_fab = -overlen_top\n    \n    hasSocket = False\n    if (socket_height > 0 and socket_width > 0):\n        hasSocket = True\n        h_fabs = socket_height\n        w_fabs = socket_width\n        l_fabs = (w_fabs - pinrow_distance) / 2\n        t_fabs = (h_fabs - (pins / 2 - 1) * rm) / 2\n    \n    h_slk = h_fab + 2 * slk_offset\n    w_slk = min(w_fab + 2 * slk_offset, pinrow_distance - pad[0] - 12 * slk_offset)\n    l_slk = (pinrow_distance - w_slk) / 2\n    t_slk = -overlen_top - slk_offset\n    w_crt = max(package_width, pinrow_distance + pad[0]) + 2 * crt_offset\n    h_crt = max(h_fab, (pins / 2 - 1) * rm + pad[1]) + 2 * crt_offset\n    \n    hasSocket = False\n    if (socket_height > 0 and socket_width > 0):\n        hasSocket = True\n        h_fabs = max(socket_height,h_slk)\n        w_fabs = socket_width\n        l_fabs = (pinrow_distance - w_fabs) / 2\n        t_fabs = ((pins / 2 - 1) * rm - h_fabs) / 2\n        h_slks = h_fabs + 2 * slk_offset\n        w_slks = max(w_fabs, pinrow_distance + pad[0] + 6 * slk_offset) + 2 * slk_offset\n        l_slks = (pinrow_distance - w_slks) / 2\n        t_slks = ((pins / 2 - 1) * rm - h_slks) / 2\n        w_crt = max(w_crt, w_fabs + 2 * crt_offset)\n        h_crt = max(h_crt, h_fabs + 2 * crt_offset)\n    \n    l_crt = pinrow_distance / 2 - w_crt / 2\n    t_crt = (pins / 2 - 1) * rm / 2 - h_crt / 2\n    \n    footprint_name = DIPName+\"-{0}_W{1}mm\".format(pins, round(pinrow_distance, 2))\n    if len(prefix_name) > 0:\n        footprint_name = DIPName+'-'+prefix_name+\"-{0}_W{1}mm\".format(pins, round(pinrow_distance, 2))\n    description = \"{0}-lead {3} package, row spacing {1} mm ({2} mils)\".format(pins, round(pinrow_distance, 2),\n                                                                               int(pinrow_distance / 2.54 * 100),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   DIPDescription)\n    tags = DIPTags+\" {0}mm {1}mm {2}mil\".format(rm, pinrow_distance, int(pinrow_distance / 2.54 * 100))\n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n    \n    print(footprint_name)\n    \n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n    \n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    offset = [0, 0]\n    if (smd_pads):\n        offset = [-pinrow_distance / 2, -(pins / 2 - 1) * rm / 2]\n        kicad_modg = Translation(offset[0], offset[1])\n        kicad_mod.append(kicad_modg)\n        kicad_mod.setAttribute('smd')\n    else:\n        kicad_modg = kicad_mod\n    \n    # set general values\n    kicad_modg.append(\n        Text(type='reference', text='REF**', at=[pinrow_distance / 2, t_slk - txt_offset], layer='F.SilkS'))\n    kicad_modg.append(\n        Text(type='user', text='%R', at=[pinrow_distance/2, t_fab + h_fab / 2], layer='F.Fab'))\n    kicad_modg.append(\n        Text(type='value', text=footprint_name, at=[pinrow_distance / 2, t_slk + h_slk + txt_offset], layer='F.Fab'))\n    \n    # create FAB-layer\n    bevelRectTL(kicad_modg, [l_fab, t_fab], [w_fab, h_fab], 'F.Fab', lw_fab)\n    if hasSocket:\n        kicad_modg.append(\n            RectLine(start=[l_fabs, t_fabs], end=[l_fabs + w_fabs, t_fabs + h_fabs], layer='F.Fab', width=lw_fab))\n    \n    # create SILKSCREEN-layer\n    DIPRectT(kicad_modg, [l_slk, t_slk], [w_slk, h_slk], 'F.SilkS', lw_slk)\n    if hasSocket:\n        # if smd_pads:\n        #    kicad_modg.append(Line(start=[l_slks, t_slks], end=[l_slks + w_slks, t_slks], layer='F.SilkS',width=lw_slk))\n        #    kicad_modg.append(Line(start=[l_slks, t_slks+h_slks], end=[l_slks + w_slks, t_slks+h_slks], layer='F.SilkS',width=lw_slk))\n        # else:\n        #    kicad_modg.append(RectLine(start=[l_slks, t_slks], end=[l_slks+w_slks, t_slks+h_slks], layer='F.SilkS', width=lw_slk))\n        kicad_modg.append(\n            RectLine(start=[l_slks, t_slks], end=[l_slks + w_slks, t_slks + h_slks], layer='F.SilkS', width=lw_slk))\n    \n    # create courtyard\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\n                              end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\n                              layer='F.CrtYd', width=lw_crt))\n    \n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0\n    p2 = int(pins / 2 + 1)\n    if right_cnt_start >= 0:\n        # The pins on the right side shall start with a specific value\n        p2 = right_cnt_start\n\n    x2 = pinrow_distance\n    y2 = (pins / 2 - 1) * rm\n    \n    if smd_pads:\n        pad_type = Pad.TYPE_SMT\n        pad_shape1 = Pad.SHAPE_RECT\n        pad_shapeother = Pad.SHAPE_RECT\n        pad_layers = ['F.Cu', 'F.Mask', 'F.Paste']\n    else:\n        pad_type = Pad.TYPE_THT\n        pad_shape1 = Pad.SHAPE_RECT\n        pad_shapeother = Pad.SHAPE_OVAL\n        pad_layers = ['*.Cu', '*.Mask']\n    \n    for p in range(1, int(pins / 2 + 1)):\n        \n        addpinL = True\n        for sp in skip_pin:\n            if sp == p:\n                # The pin number is among those who should not be added\n                addpinL = False\n\n        if addpinL:\n            if p == 1:\n                kicad_modg.append(Pad(number=p1, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=ddrill,\n                                      layers=pad_layers))\n            else:\n                kicad_modg.append(Pad(number=p1, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=ddrill,\n                                      layers=pad_layers))\n\n        addpinR = True\n        for sp in skip_pin:\n            if sp == p + int(pins / 2):\n                # The pin number is among those who should not be added\n                addpinR = False\n\n        if addpinR:\n            kicad_modg.append(Pad(number=p2, type=pad_type, shape=pad_shapeother, at=[x2, y2], size=pad, drill=ddrill,\n                              layers=pad_layers))\n\n        # Do not increase the pin number if it should be skipped\n        if not (skip_count and not addpinL):\n            p1 = p1 + 1\n\n        # Do not increase the pin number if it should be skipped\n        if not (skip_count and not addpinR):\n            p2 = p2 + 1\n\n        y1 = y1 + rm\n        y2 = y2 - rm\n\n    # add model\n    kicad_modg.append(\n        Model(filename=\"${KISYS3DMOD}/\" + lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=offset3d, scale=scale3d, rotate=rotate3d))\n    \n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n    \n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(footprint_name + '.kicad_mod')\n\n\n#    overlen_top                           overlen_bottom\n#  <--->                                 <------>\n#       O          O          O          O                             ^\n#       |          |          |          |                             |\n#  +--------------------------------------------+    ^                 |\n#  |  +---+  ^                                  |    |                 |\n#  |  |   |  |                                  |    |                 |\n#  |  +---+  switch_width                       | package_width        |\n#  |  |   |  |                                  |    |           pinrow_distance\n#  |  +---+  v                                  |    |                 |\n#  +--------------------------------------------+    v                 |\n#       |          |          |          |                             |\n#       O          O          O          O                             v\n#     <--->switch_height\n#       <----RM---->\n#\n#  mode=Piano/Slide\n#\ndef makeDIPSwitch(pins, rm, pinrow_distance, package_width, overlen_top, overlen_bottom, ddrill, pad, switch_width,\n                  switch_height, mode='Piano', smd_pads=False, tags_additional=[],\n                  lib_name=\"Button_Switch_THT\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 90],\n                  specialFPName=\"\", SOICStyleSilk=False, cornerPads=[], cornerPadOffsetX=0, cornerPadOffsetY=0, webpage=\"\", device_name=\"\", switchtype=\"SPST\"):\n    switches = int(pins / 2)\n    \n    h_fab = (pins / 2 - 1) * rm + overlen_top + overlen_bottom\n    w_fab = package_width\n    l_fab = (pinrow_distance - w_fab) / 2\n    t_fab = -overlen_top\n    \n    h_slk = h_fab + 2 * slk_offset\n    w_slk = w_fab + 2 * slk_offset\n    #if (package_width > pinrow_distance):\n    #    w_slk = max(w_fab + 2 * slk_offset, pinrow_distance + pad[0] + 2 * slk_offset)\n    #else:\n    #    w_slk = min(w_fab + 2 * slk_offset, pinrow_distance - pad[0] - 4 * slk_offset)\n    l_slk = (pinrow_distance - w_slk) / 2\n    t_slk = -overlen_top - slk_offset\n    \n    if len(cornerPads) == 2:\n        t_slk = t_fab + cornerPadOffsetY - cornerPads[1] / 2 - slk_offset\n        h_slk = t_fab + h_fab - cornerPadOffsetY + cornerPads[1] / 2 + slk_offset - t_slk\n    \n    w_crt = max(package_width, pinrow_distance + pad[0]) + 2 * crt_offset\n    h_crt = max(h_fab, (pins / 2 - 1) * rm + pad[1], h_slk) + 2 * crt_offset\n    l_crt = pinrow_distance / 2 - w_crt / 2\n    t_crt = min(t_slk - crt_offset, (pins / 2 - 1) * rm / 2 - h_crt / 2)\n    \n    if (mode == 'Piano'):\n        l_crt = l_crt - switch_width\n        w_crt = w_crt + switch_width\n    \n    smdtext=''\n    smddescription=''\n    if smd_pads:\n        #smdtext='_SMD';\n        smddescription='SMD '\n    \n    add_type=\"\"\n    bodysize=\"{0}x{1}mm\".format(round(package_width,2), round(overlen_top+overlen_bottom+(pins/2-1)*rm,2))\n    if len(device_name)>0:\n        add_type=\"_\"+device_name\n        bodysize=\"\"\n    \n    bodysizefp=\"\";\n    if len(bodysize)>0:\n        bodysizefp=bodysize+\"_\"\n    \n    footprint_name = \"SW_DIP_{6}x{0:02}_{4}{5}_{7}W{1}mm_P{2}mm{3}\".format(switches, round(pinrow_distance, 2), round(rm, 2), smdtext, mode,add_type,switchtype,bodysizefp)\n    description = \"{4}{0}x-dip-switch {6} {5}, {3}, row spacing {1} mm ({2} mils), body size {7}\".format(switches, round(pinrow_distance, 2),\n                                                                               int(pinrow_distance / 2.54 * 100), mode,smddescription,device_name,switchtype,bodysize)\n\n    if len(webpage)>0:\n      description=description+\" (see \"+webpage+\")\"\n    tags = \"{3}DIP Switch {4} {0} {1}mm {2}mil\".format(mode, pinrow_distance, int(pinrow_distance / 2.54 * 100),smddescription,switchtype)\n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            if t != \"SMD\":  # suppress \"SMD\" in file name since this is already part of folder name\n                footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n    \n    if len(specialFPName) > 0:\n        footprint_name = specialFPName\n    \n    print(footprint_name)\n    \n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n    \n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    offset = [0, 0]\n    if (smd_pads):\n        offset = [-pinrow_distance / 2, -(pins / 2 - 1) * rm / 2]\n        kicad_modg = Translation(offset[0], offset[1])\n        kicad_mod.append(kicad_modg)\n        kicad_mod.setAttribute('smd')\n    else:\n        kicad_modg = kicad_mod\n    \n    # add texts\n    if pins == 2:\n        fab_ref_size = [0.6, 0.6]\n    else:\n        ss=max(0.25, min((package_width-switch_width)*0.35, 0.8))\n        fab_ref_size = [ss, ss]\n        \n    kicad_modg.append(Text(type='reference', text='REF**', at=[pinrow_distance / 2, t_slk - txt_offset], layer='F.SilkS'))\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[pinrow_distance / 2, t_slk + h_slk + txt_offset], layer='F.Fab'))\n    if (mode == 'Piano'):\n        kicad_modg.append(Text(type='user', text='%R', at=[pinrow_distance/2, t_fab + h_fab /2], size=fab_ref_size, layer='F.Fab', thickness=fab_ref_size[0]*0.15))\n    else:\n        kicad_modg.append(Text(type='user', text='%R', at=[pinrow_distance/2 + (package_width+switch_width)/4, t_fab + h_fab /2], rotation=90, size=fab_ref_size, layer='F.Fab', thickness=fab_ref_size[0]*0.15))\n        kicad_modg.append(Text(type='user', text='on', at=[pinrow_distance/2 + (package_width+switch_width)/4-pinrow_distance/4, t_fab + (overlen_top-switch_height/2)/2], rotation=0, size=fab_ref_size, layer='F.Fab', thickness=fab_ref_size[0]*0.15))\n        \n    \n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0\n    p2 = int(pins / 2 + 1)\n    x2 = pinrow_distance\n    y2 = (pins / 2 - 1) * rm\n    keepouts=[];\n    \n    if smd_pads:\n        pad_type = Pad.TYPE_SMT\n        pad_shape1 = Pad.SHAPE_RECT\n        pad_shapeother = Pad.SHAPE_RECT\n        pad_layers = ['F.Cu', 'F.Mask', 'F.Paste']\n    else:\n        pad_type = Pad.TYPE_THT\n        pad_shape1 = Pad.SHAPE_RECT\n        pad_shapeother = Pad.SHAPE_OVAL\n        pad_layers = ['*.Cu', '*.Mask']\n    \n    keepout_addsize=4*max(slk_offset, lw_slk)\n    for p in range(1, int(pins / 2 + 1)):\n        if p == 1:\n            kicad_modg.append(Pad(number=p1, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=ddrill, layers=pad_layers))\n            keepouts=keepouts+addKeepoutRect(x1, y1, pad[0]+keepout_addsize, pad[1]+keepout_addsize)\n        else:\n            kicad_modg.append(Pad(number=p1, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=ddrill, layers=pad_layers))\n            keepouts=keepouts+addKeepoutRound(x1, y1, pad[0]+keepout_addsize, pad[1]+keepout_addsize)\n        \n        kicad_modg.append(Pad(number=p2, type=pad_type, shape=pad_shapeother, at=[x2, y2], size=pad, drill=ddrill, layers=pad_layers))\n        keepouts=keepouts+addKeepoutRound(x2, y2, pad[0]+keepout_addsize, pad[1]+keepout_addsize)\n        \n        p1 = p1 + 1\n        p2 = p2 + 1\n        y1 = y1 + rm\n        y2 = y2 - rm\n    \n    if len(cornerPads) == 2:\n        kicad_modg.append(Pad(number=pins + 1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                              at=[l_fab + cornerPadOffsetX, t_fab + cornerPadOffsetY], size=cornerPads, drill=0,\n                              layers=pad_layers))\n        keepouts=keepouts+addKeepoutRect(l_fab + cornerPadOffsetX, t_fab + cornerPadOffsetY, cornerPads[0]+keepout_addsize, cornerPads[1]+keepout_addsize)                              \n        kicad_modg.append(Pad(number=pins + 1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                              at=[l_fab + w_fab - cornerPadOffsetX, t_fab + cornerPadOffsetY], size=cornerPads, drill=0,\n                              layers=pad_layers))\n        keepouts=keepouts+addKeepoutRect(l_fab + w_fab - cornerPadOffsetX, t_fab + cornerPadOffsetY, cornerPads[0]+keepout_addsize, cornerPads[1]+keepout_addsize)                              \n        kicad_modg.append(Pad(number=pins + 1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                              at=[l_fab + cornerPadOffsetX, t_fab + h_fab - cornerPadOffsetY], size=cornerPads, drill=0,\n                              layers=pad_layers))\n        keepouts=keepouts+addKeepoutRect(l_fab + cornerPadOffsetX, t_fab + h_fab - cornerPadOffsetY, cornerPads[0]+keepout_addsize, cornerPads[1]+keepout_addsize)                              \n        kicad_modg.append(Pad(number=pins + 1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT,\n                              at=[l_fab + w_fab - cornerPadOffsetX, t_fab + h_fab - cornerPadOffsetY], size=cornerPads,\n                              drill=0, layers=pad_layers))        \n        keepouts=keepouts+addKeepoutRect(l_fab + w_fab - cornerPadOffsetX, t_fab + h_fab - cornerPadOffsetY, cornerPads[0]+keepout_addsize, cornerPads[1]+keepout_addsize)                              \n        \n        \n\n    # create FAB-layer\n    bevelRectTL(kicad_modg, [l_fab, t_fab], [w_fab, h_fab], 'F.Fab', lw_fab)\n    for sw in range(0, switches):\n        x = pinrow_distance / 2\n        y = sw * rm\n        if (mode == 'Piano'):\n            kicad_modg.append(\n                RectLine(start=[l_fab, y - switch_height / 2], end=[l_fab - switch_width, y + switch_height / 2],\n                         layer='F.Fab', width=lw_fab))\n        else:\n            kicad_modg.append(RectLine(start=[x - switch_width / 2, y - switch_height / 2],\n                                       end=[x + switch_width / 2, y + switch_height / 2], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(RectFill(start=[x - switch_width / 2, y - switch_height / 2], end=[x - switch_width / 6, y + switch_height / 2], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[x - switch_width / 6, y - switch_height / 2], end=[x - switch_width / 6, y + switch_height / 2], layer='F.Fab', width=lw_fab))\n    \n    # create SILKSCREEN-layer\n    if SOICStyleSilk and smd_pads:\n        addHLineWithKeepout(kicad_modg, l_fab-slk_offset, l_fab + w_fab+slk_offset, t_slk + h_slk, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n        if (overlen_top>0.5):\n            addHLineWithKeepout(kicad_modg,-pad[0] / 2, l_fab-slk_offset, -pad[1] / 2-lw_slk-3*slk_offset, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n            addVLineWithKeepout(kicad_modg, l_fab-slk_offset, t_slk, -pad[1] / 2-lw_slk-3*slk_offset, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n            addHLineWithKeepout(kicad_modg, l_fab-slk_offset, l_fab + w_fab+slk_offset, t_slk, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n            addVLineWithKeepout(kicad_modg, l_fab + w_fab+slk_offset, t_slk, t_slk+overlen_top, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n        else:\n            addHLineWithKeepout(kicad_modg, -pad[0] / 2, l_fab + w_fab+slk_offset, t_slk, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n            \n        if overlen_bottom>0.5:\n            addVLineWithKeepout(kicad_modg, l_fab -slk_offset, t_slk+h_slk, t_slk+h_slk-overlen_bottom, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n            addVLineWithKeepout(kicad_modg, l_fab + w_fab+slk_offset, t_slk+h_slk, t_slk+h_slk-overlen_bottom, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n    else:\n        addRectAndTLMarkWithKeepout(kicad_modg, l_slk, t_slk, w_slk, h_slk, min(max(0.5, pad[0]), rm*0.45), layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n        \n        for sw in range(0, switches):\n            x = pinrow_distance / 2\n            y = sw * rm\n            if (mode == 'Piano'):\n                addRectWithKeepout(kicad_modg, l_slk - switch_width - slk_offset, y - switch_height / 2 - slk_offset, switch_width + slk_offset, switch_height+2*slk_offset, layer='F.SilkS', width=lw_slk)\n            else:\n                kicad_modg.append(RectLine(start=[x - switch_width / 2, y - switch_height / 2],\n                                           end=[x + switch_width / 2, y + switch_height / 2], layer='F.SilkS',\n                                           width=lw_slk))\n                kicad_modg.append(\n                    RectFill(start=[x - switch_width / 2, y - switch_height / 2], end=[x - switch_width / 6, y + switch_height / 2], layer='F.SilkS',\n                         width=lw_slk))\n                kicad_modg.append(\n                    Line(start=[x - switch_width / 6, y - switch_height / 2], end=[x - switch_width / 6, y + switch_height / 2], layer='F.SilkS',\n                         width=lw_slk))\n    \n    # create courtyard\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\n                              end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\n                              layer='F.CrtYd', width=lw_crt))\n\n    \n    # add model\n    kicad_modg.append(\n        Model(filename=\"${KISYS3DMOD}/\" + lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=offset3d, scale=scale3d, rotate=rotate3d))\n\n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n    \n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(footprint_name + '.kicad_mod')\n"
  },
  {
    "path": "scripts/tools/footprint_scripts_LEDs.py",
    "content": "#!/usr/bin/env python\r\n\r\nimport sys\r\nimport os\r\nimport math\r\n\r\n# ensure that the kicad-footprint-generator directory is available\r\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\r\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\r\n\r\nfrom KicadModTree import *  # NOQA\r\nfrom drawing_tools import *\r\nfrom footprint_global_properties import *\r\n\r\n\r\n# LED footprints\r\n#   style options:\r\n#     1. type=\"box\"\r\n#           +----------------+ ^\r\n#           |                | |\r\n#           |  OO        OO  | h\r\n#           |                | |\r\n#           +----------------+ v\r\n#               <---rm--->\r\n#           <-------w-------->\r\n#     2. type=\"round\"\r\n#              /----------\\   ^\r\n#             |            \\  |\r\n#             |  OO    OO   | h\r\n#             |            /  |\r\n#              \\__________/   v\r\n#                 <-rm->\r\n#           <-------w-------->\r\n#     3. type=\"roundedbox\"\r\n#           +--------------\\   ^\r\n#           |               \\  |\r\n#           |  OO        OO  | h\r\n#           |               /  |\r\n#           +--------------/   v\r\n#               <---rm--->\r\n#           <-------w-------->\r\n#     4. type=\"oval\"\r\n#           +----------------+ ^\r\n#           |                | |\r\n#           |  OO        OO  | h\r\n#           |                | |\r\n#           +----------------+ v\r\n#               <---rm--->\r\n#           <-------w-------->\r\n#     2. type=\"round_simple\"\r\n#              /----------\\   ^\r\n#             /            \\  |\r\n#            |   OO    OO   | h\r\n#             \\            /  |\r\n#              \\__________/   v\r\n#                 <-rm->\r\n#           <-------w-------->\r\n# in the center a second circle is drawn if rin>0\r\ndef makeLEDRadial(rm, w, h, ddrill, win=0, rin=0, pins=2, type=\"round\", x_3d=[0, 0, 0],\r\n                  s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=[], add_description=\"\",\r\n                  classname=\"LED\", lib_name=\"LEDs\", name_additions=[], script3d=\"\", height3d=8, height3d_bottom=1):\r\n    padx = 2 * ddrill\r\n    pady = padx\r\n    if padx + min_pad_distance > rm:\r\n        padx = (rm - min_pad_distance)\r\n    txtoffset = txt_offset\r\n    \r\n    pad1style = Pad.SHAPE_RECT\r\n    \r\n    padpos = []\r\n    offset = [0, 0]\r\n    overpad_width = (pins - 1) * rm\r\n    xpad = -overpad_width / 2\r\n    offset = [-xpad, 0]\r\n    for p in range(1, pins + 1):\r\n        padpos.append([p, xpad, 0, ddrill, padx, pady])\r\n        xpad = xpad + rm\r\n    \r\n    l_fab = -w / 2\r\n    t_fab = -h / 2\r\n    w_fab = w\r\n    h_fab = h\r\n    d_fab = max(w, h)\r\n    d2_fab = rin\r\n    h_slk = h_fab + 2 * slk_offset\r\n    w_slk = w_fab + 2 * slk_offset\r\n    l_slk = l_fab - slk_offset\r\n    t_slk = t_fab - slk_offset\r\n    d_slk = d_fab + lw_slk + slk_offset\r\n    w_crt = max(w_slk, overpad_width + padx) + 2 * crt_offset\r\n    h_crt = max(h_slk, pady) + 2 * crt_offset\r\n    l_crt = -w_crt / 2\r\n    t_crt = -h_crt / 2\r\n    \r\n    snfp = \"\"\r\n    sn = \"\"\r\n    snt = \"\"\r\n    \r\n    fnsize = \"\"\r\n    sizetag = \"\"\r\n    if type == \"round\" or type == \"round_simple\":\r\n        fnsize = \"_D{0:0.1f}mm\".format(rin)\r\n        sizetag = \"diameter {0:0.1f}mm\".format(rin)\r\n    else:\r\n        if type == \"oval\":\r\n            sizetag = \" Oval\"\r\n        if type == \"box\":\r\n            sizetag = \" Rectangular\"\r\n        wsize = w\r\n        if type == \"box\" and win > 0:\r\n            wsize = win\r\n        fnsize = fnsize + \"_W{0:0.1f}mm_H{1:0.1f}mm\".format(wsize, h)\r\n        sizetag = sizetag + \" size {0:0.1f}x{1:0.1f}mm^2\".format(wsize, h)\r\n        if rin > 0:\r\n            fnsize = \"_D{0:0.1f}mm\".format(rin) + fnsize\r\n            sizetag = sizetag + \" diameter {0:0.1f}mm\".format(rin)\r\n    \r\n    fnpincnt = \"\"\r\n    pincnttag = \"{0:d} pins\".format(pins)\r\n    if pins > 2:\r\n        fnpincnt = \"-{0:d}\".format(pins)\r\n        if type == \"box\":\r\n            fnpincnt = fnpincnt + \"pins\"\r\n    \r\n    footprint_name = classname + fnsize + fnpincnt\r\n    \r\n    description = classname\r\n    tags = classname\r\n    \r\n    addedtags = specialtags\r\n    if len(sizetag) > 0:\r\n        addedtags.append(sizetag)\r\n    if len(pincnttag) > 0:\r\n        addedtags.append(pincnttag)\r\n    \r\n    for t in addedtags:\r\n        description = description + \", \" + t\r\n        tags = tags + \" \" + t\r\n    if (specialfpname != \"\"):\r\n        footprint_name = specialfpname;\r\n    \r\n    if len(add_description) > 0:\r\n        description = description + \", \" + add_description\r\n    \r\n    for n in name_additions:\r\n        if len(n) > 0:\r\n            footprint_name = footprint_name + \"_\" + n\r\n    \r\n    print(footprint_name)\r\n    \r\n    if script3d != \"\":\r\n        with open(script3d, \"a\") as myfile:\r\n            myfile.write(\"\\n\\n # {0}\\n\".format(footprint_name))\r\n            myfile.write(\"import FreeCAD\\n\")\r\n            myfile.write(\"import os\\n\")\r\n            myfile.write(\"import os.path\\n\\n\")\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B4', '0.02')\\n\")\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"# rin\\nApp.ActiveDocument.Spreadsheet.set('B1', '{0}')\\n\".format(rin))\r\n            myfile.write(\"# w\\nApp.ActiveDocument.Spreadsheet.set('B2', '{0}')\\n\".format(w))\r\n            myfile.write(\"# h\\nApp.ActiveDocument.Spreadsheet.set('C2', '{0}')\\n\".format(h))\r\n            myfile.write(\"# RM\\nApp.ActiveDocument.Spreadsheet.set('B3', '{0}')\\n\".format(rm))\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B4', '{0}')\\n\".format(ddrill - 0.3))\r\n            myfile.write(\"# H\\nApp.ActiveDocument.Spreadsheet.set('B5', '{0}')\\n\".format(height3d))\r\n            myfile.write(\"# H_bottom\\nApp.ActiveDocument.Spreadsheet.set('B6', '{0}')\\n\".format(height3d_bottom))\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"doc = FreeCAD.activeDocument()\\n\")\r\n            myfile.write(\"__objs__=[]\\n\")\r\n            myfile.write(\"for obj in doc.Objects:\t\\n\")\r\n            myfile.write(\"    if obj.ViewObject.Visibility:\\n\")\r\n            myfile.write(\"        __objs__.append(obj)\\n\")\r\n            myfile.write(\"\\nFreeCADGui.export(__objs__,os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.wrl\\\")\\n\".format(\r\n                footprint_name))\r\n            myfile.write(\"doc.saveCopy(os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.FCStd\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"print(\\\"created {0}\\\")\\n\".format(footprint_name))\r\n    \r\n    # init kicad footprint\r\n    kicad_mod = Footprint(footprint_name)\r\n    kicad_mod.setDescription(description)\r\n    kicad_mod.setTags(tags)\r\n    \r\n    kicad_modg = Translation(offset[0], offset[1])\r\n    kicad_mod.append(kicad_modg)\r\n    \r\n    # set general values\r\n    kicad_modg.append(Text(type='reference', text='REF**', at=[0, t_slk - txtoffset], layer='F.SilkS'))\r\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[0, t_slk + h_slk + txtoffset], layer='F.Fab'))\r\n    \r\n    # create FAB-layer\r\n    if type == \"round\":\r\n        kicad_modg.append(Circle(center=[0, 0], radius=d2_fab / 2, layer='F.Fab', width=lw_fab))\r\n        xmark = d2_fab / 2\r\n        ymark = math.sqrt(d_fab * d_fab / 4 - xmark * xmark)\r\n        alpha = 360 - 2 * math.atan(ymark / xmark) / 3.1415 * 180\r\n        kicad_modg.append(Arc(center=[0, 0], start=[-xmark, -ymark], angle=alpha, layer='F.Fab', width=lw_fab))\r\n        kicad_modg.append(Line(start=[-xmark, -ymark], end=[-xmark, ymark], angle=alpha, layer='F.Fab', width=lw_fab))\r\n    if type == \"round_simple\":\r\n        kicad_modg.append(Circle(center=[0, 0], radius=d2_fab / 2, layer='F.Fab', width=lw_fab))\r\n        kicad_modg.append(Circle(center=[0, 0], radius=d_fab / 2, layer='F.Fab', width=lw_fab))\r\n    elif type == \"box\":\r\n        kicad_modg.append(\r\n            RectLine(start=[l_fab, t_fab], end=[l_fab + w_fab, t_fab + h_fab], layer='F.Fab', width=lw_fab))\r\n        if d2_fab > 0:\r\n            kicad_modg.append(Circle(center=[0, 0], radius=d2_fab / 2, layer='F.Fab', width=lw_fab))\r\n        if win > 0:\r\n            kicad_modg.append(\r\n                RectLine(start=[-win / 2, t_fab], end=[win / 2, t_fab + h_fab], layer='F.Fab', width=lw_fab))\r\n    elif type == \"oval\":\r\n        r = w / 2\r\n        ystart = 0\r\n        xstart = math.sqrt(r * r - ystart * ystart)\r\n        ycenter = h / 2 - r\r\n        alpha = 180 - 2 * math.atan(math.fabs(ycenter) / xstart) / 3.1415 * 180\r\n        kicad_modg.append(Arc(center=[0, -ycenter], start=[-xstart, ystart], angle=alpha, layer='F.Fab', width=lw_fab))\r\n        kicad_modg.append(Arc(center=[0, ycenter], start=[-xstart, -ystart], angle=-alpha, layer='F.Fab', width=lw_fab))\r\n    \r\n    # build keepeout for SilkScreen\r\n    keepouts = []\r\n    for p in padpos:\r\n        if p[0] == 1:\r\n            keepouts = keepouts + addKeepoutRect(p[1], p[2], p[4] + 2 * lw_slk + 2 * slk_offset,\r\n                                                 p[5] + 2 * lw_slk + 2 * slk_offset)\r\n        else:\r\n            keepouts = keepouts + addKeepoutRound(p[1], p[2], p[4] + 2 * lw_slk + 2 * slk_offset,\r\n                                                  p[5] + 2 * lw_slk + 2 * slk_offset)\r\n    \r\n    # create SILKSCREEN-layer\r\n    if type == \"box\":\r\n        addRectWithKeepout(kicad_modg, l_slk, t_slk, w_slk, h_slk, 'F.SilkS', lw_slk, keepouts)\r\n        if pins == 3:\r\n            addVLineWithKeepout(kicad_modg, -offset[0] + rm / 2, t_slk, t_slk + h_slk, 'F.SilkS', lw_slk, keepouts)\r\n        else:\r\n            addVLineWithKeepout(kicad_modg, l_slk + lw_slk, t_slk, t_slk + h_slk, 'F.SilkS', lw_slk, keepouts)\r\n            addVLineWithKeepout(kicad_modg, l_slk + 2 * lw_slk, t_slk, t_slk + h_slk, 'F.SilkS', lw_slk, keepouts)\r\n    elif type == \"round\":\r\n        xmark = d2_fab / 2 + slk_offset\r\n        ymark = math.sqrt(d_slk * d_slk / 4 - xmark * xmark)\r\n        ypad = pady / 2 + slk_offset + lw_slk\r\n        xpad = math.sqrt(d_slk * d_slk / 4 - ypad * ypad)\r\n        alphamark = math.atan(ymark / xmark) / 3.1415 * 180\r\n        alphapad = math.atan(ypad / xpad) / 3.1415 * 180\r\n        alpha = 180 - alphamark\r\n        if containedInAnyKeepout(xmark, 0.1, keepouts) or containedInAnyKeepout(d_fab / 2, 0.1, keepouts):\r\n            alpha = alpha - alphapad\r\n        kicad_modg.append(Arc(center=[0, 0], start=[-xmark, -ymark], angle=alpha, layer='F.SilkS', width=lw_slk))\r\n        kicad_modg.append(Arc(center=[0, 0], start=[-xmark, ymark], angle=-alpha, layer='F.SilkS', width=lw_slk))\r\n        addVLineWithKeepout(kicad_modg, -xmark, -ymark, ymark, 'F.SilkS', lw_slk, keepouts)\r\n        \r\n        ypad = pady / 2 + slk_offset + lw_slk\r\n        xpad = math.sqrt(d2_fab * d2_fab / 4 - ypad * ypad)\r\n        alphapad = math.atan(ypad / xpad) / 3.1415 * 180\r\n        \r\n        alpha = 180\r\n        if containedInAnyKeepout(d2_fab / 2, 0.1, keepouts) or containedInAnyKeepout(-d2_fab / 2, 0.1, keepouts):\r\n            alpha = alpha - 2 * alphapad\r\n        if alpha == 180:\r\n            kicad_modg.append(Circle(center=[0, 0], radius=d2_fab / 2, layer='F.SilkS', width=lw_slk))\r\n        else:\r\n            kicad_modg.append(Arc(center=[0, 0], start=[-xpad, -ypad], angle=alpha, layer='F.SilkS', width=lw_slk))\r\n            kicad_modg.append(Arc(center=[0, 0], start=[-xpad, ypad], angle=-alpha, layer='F.SilkS', width=lw_slk))\r\n    elif type == \"round_simple\":\r\n        rs = [d2_fab, d_slk]\r\n        xpads = []\r\n        ypads = []\r\n        fullCircle = False\r\n        for r in rs:\r\n            ypad = pady / 2 + slk_offset + lw_slk\r\n            xpad = math.sqrt(r * r / 4 - ypad * ypad)\r\n            xpads.append(xpad)\r\n            ypads.append(ypad)\r\n            alphapad = math.atan(ypad / xpad) / 3.1415 * 180\r\n            \r\n            alpha = 180\r\n            if containedInAnyKeepout(r / 2, 0.1, keepouts) or containedInAnyKeepout(-r / 2, 0.1, keepouts):\r\n                alpha = alpha - 2 * alphapad\r\n            if alpha == 180:\r\n                kicad_modg.append(Circle(center=[0, 0], radius=r / 2, layer='F.SilkS', width=lw_slk))\r\n                fullCircle = True\r\n            else:\r\n                kicad_modg.append(Arc(center=[0, 0], start=[-xpad, -ypad], angle=alpha, layer='F.SilkS', width=lw_slk))\r\n                kicad_modg.append(Arc(center=[0, 0], start=[-xpad, ypad], angle=-alpha, layer='F.SilkS', width=lw_slk))\r\n        if fullCircle:\r\n            x = -d_slk / 2 + lw_slk * 2\r\n            y = math.sqrt(d_slk * d_slk / 4 - x * x)\r\n            kicad_modg.append(Line(start=[x, -y], end=[x, y], layer='F.SilkS', width=lw_slk))\r\n        else:\r\n            kicad_modg.append(\r\n                Line(start=[-xpads[0], ypads[0]], end=[-xpads[1], ypads[0]], layer='F.SilkS', width=lw_slk))\r\n            kicad_modg.append(\r\n                Line(start=[-xpads[0], -ypads[0]], end=[-xpads[1], -ypads[0]], layer='F.SilkS', width=lw_slk))\r\n    elif type == \"oval\":\r\n        r = w_slk / 2\r\n        ystart = 0\r\n        xstart = math.sqrt(r * r - ystart * ystart)\r\n        ycenter = h_slk / 2 - r\r\n        alpha = 180 - 2 * math.atan(math.fabs(ycenter) / xstart) / 3.1415 * 180\r\n        kicad_modg.append(\r\n            Arc(center=[0, -ycenter], start=[-xstart, ystart], angle=alpha, layer='F.SilkS', width=lw_slk))\r\n        kicad_modg.append(\r\n            Arc(center=[0, ycenter], start=[-xstart, -ystart], angle=-alpha, layer='F.SilkS', width=lw_slk))\r\n        xmark = -xstart + 2 * lw_slk\r\n        ymark = ycenter + math.sqrt(r * r - xmark * xmark)\r\n        print(ymark, ycenter, ymark + ycenter)\r\n        addVLineWithKeepout(kicad_modg, xmark, -ymark, ymark, 'F.SilkS', lw_slk, keepouts)\r\n    \r\n    # create courtyard\r\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\r\n                              end=[roundCrt(l_crt + w_crt + offset[0]), roundCrt(t_crt + h_crt + offset[1])],\r\n                              layer='F.CrtYd', width=lw_crt))\r\n\r\n    # debug_draw_keepouts(kicad_modg, keepouts)\r\n    \r\n    # create pads\r\n    pn = 1\r\n    for p in padpos:\r\n        ps = Pad.SHAPE_CIRCLE\r\n        if (p[4] != p[5]):\r\n            ps = Pad.SHAPE_OVAL\r\n        if p[0] == 1:\r\n            ps = pad1style\r\n        kicad_modg.append(Pad(number=p[0], type=Pad.TYPE_THT, shape=ps, at=[p[1], p[2]], size=[p[4], p[5]], drill=p[3],\r\n                              layers=['*.Cu', '*.Mask']))\r\n    \r\n    # add model\r\n    if (has3d != 0):\r\n        kicad_modg.append(\r\n            Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=[0, 0, 0]))\r\n    \r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n    \r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(footprint_name + '.kicad_mod')\r\n\r\n\r\n# LED footprints for horizontally mounted LEDs\r\n#   style options:\r\n#     1. type=\"simple\"\r\n#                    +------\\    ^\r\n#     ^       OO     |       \\   |\r\n#     rm             |        |  dled\r\n#     v       OO     |       /   |\r\n#                    +------/    v\r\n#             <------>offsetled\r\n#                    <--wled->\r\n#\r\n#  type=\"round\"/\"rect\"\r\ndef makeLEDHorizontal(pins=2,rm=2.544,dled=5,dledout=5.8,offsetled=2.54,wled=8.6, ddrill=0.8, wledback=1, type=\"round\", x_3d=[0, 0, 0],\r\n                  s_3d=[1 / 2.54, 1 / 2.54, 1 / 2.54], has3d=1, specialfpname=\"\", specialtags=[], add_description=\"\",\r\n                  classname=\"LED\", lib_name=\"LEDs\", name_additions=[], script3d=\"\", height3d=5, ledypos=0):\r\n    padx = 2 * ddrill\r\n    pady = padx\r\n    if padx + min_pad_distance > rm:\r\n        padx = (rm - min_pad_distance)\r\n    txtoffset = txt_offset\r\n    \r\n    pad1style = Pad.SHAPE_RECT\r\n    \r\n    padpos = []\r\n    offset = [0, 0]\r\n    overpad_width = (pins - 1) * rm\r\n    xpad = -overpad_width / 2\r\n    offset = [-xpad, 0]\r\n    for p in range(1, pins + 1):\r\n        padpos.append([p, xpad, 0, ddrill, padx, pady])\r\n        xpad = xpad + rm\r\n    \r\n    l_fab = -max(dledout ,overpad_width+padx)/2\r\n    t_fab = -pady / 2\r\n    w_fab = max(dledout,overpad_width+padx)\r\n    h_fab = pady/2+offsetled+wled\r\n    h_slk = h_fab + 2 * slk_offset\r\n    w_slk = w_fab + 2 * slk_offset\r\n    l_slk = l_fab - slk_offset\r\n    t_slk = t_fab - slk_offset\r\n    w_crt = max(w_slk, overpad_width + padx) + 2 * crt_offset\r\n    h_crt = h_slk + 2 * crt_offset\r\n    l_crt = l_slk-crt_offset\r\n    t_crt = t_slk-crt_offset\r\n    \r\n    snfp = \"\"\r\n    sn = \"\"\r\n    snt = \"\"\r\n    \r\n    fnsize = \"\"\r\n    sizetag = \"\"\r\n    if type == \"round\":\r\n        fnsize = \"_D{0:0.1f}mm\".format(dled)\r\n        sizetag = \"diameter {0:0.1f}mm\".format(dled)\r\n    else:\r\n        if dled!=dledout:\r\n            fnsize = fnsize + \"_D{0:0.1f}mm\".format(dled)\r\n            sizetag = sizetag + \" diameter {0:0.1f}mm\".format(dled)\r\n        else:\r\n            sizetag = \" Rectangular\"\r\n        fnsize = fnsize + \"_W{0:0.1f}mm_H{1:0.1f}mm\".format(dled, height3d)\r\n        sizetag = sizetag + \" size {0:0.1f}x{1:0.1f}mm^2\".format(dled, height3d)\r\n    \r\n    fnypos=\"\"\r\n    if ledypos>0:\r\n        fnypos = \"_Z{0:0.1f}mm\".format(ledypos)\r\n        sizetag = sizetag+ \" z-position of LED center {0:0.1f}mm\".format(ledypos)\r\n    else:\r\n        ledypos=math.ceil(dled/2+0.5)\r\n    \r\n    fnpincnt = \"\"\r\n    pincnttag = \"{0:d} pins\".format(pins)\r\n    if pins > 2:\r\n        fnpincnt = \"-{0:d}pins\".format(pins)\r\n    \r\n    footprint_name = classname + fnsize + fnpincnt\r\n    \r\n    description = classname\r\n    tags = classname\r\n    \r\n    addedtags = specialtags\r\n    if len(sizetag) > 0:\r\n        addedtags.append(sizetag)\r\n    if len(pincnttag) > 0:\r\n        addedtags.append(pincnttag)\r\n    \r\n    for t in addedtags:\r\n        description = description + \", \" + t\r\n        tags = tags + \" \" + t\r\n    if (specialfpname != \"\"):\r\n        footprint_name = specialfpname;\r\n    \r\n    if len(add_description) > 0:\r\n        description = description + \", \" + add_description\r\n    \r\n    for n in name_additions:\r\n        if len(n) > 0:\r\n            footprint_name = footprint_name + \"_\" + n\r\n\r\n    footprint_name=footprint_name+\"_Horizontal_O{0:1.2f}mm{1}\".format(offsetled,fnypos)\r\n    \r\n    print(footprint_name)\r\n    \r\n    if script3d != \"\":\r\n        with open(script3d, \"a\") as myfile:\r\n            myfile.write(\"\\n\\n # {0}\\n\".format(footprint_name))\r\n            myfile.write(\"import FreeCAD\\n\")\r\n            myfile.write(\"import os\\n\")\r\n            myfile.write(\"import os.path\\n\\n\")\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B4', '0.02')\\n\")\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"# dled\\nApp.ActiveDocument.Spreadsheet.set('B1', '{0}')\\n\".format(dled))\r\n            myfile.write(\"# dledout\\nApp.ActiveDocument.Spreadsheet.set('B2', '{0}')\\n\".format(dledout))\r\n            myfile.write(\"# offsetled\\nApp.ActiveDocument.Spreadsheet.set('B3', '{0}')\\n\".format(offsetled))\r\n            myfile.write(\"# RM\\nApp.ActiveDocument.Spreadsheet.set('B4', '{0}')\\n\".format(rm))\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B5', '{0}')\\n\".format(ddrill - 0.3))\r\n            myfile.write(\"# H\\nApp.ActiveDocument.Spreadsheet.set('B6', '{0}')\\n\".format(height3d))\r\n            myfile.write(\"# wled\\nApp.ActiveDocument.Spreadsheet.set('B7', '{0}')\\n\".format(wled))\r\n            myfile.write(\"# ledypos\\nApp.ActiveDocument.Spreadsheet.set('B8', '{0}')\\n\".format(ledypos))\r\n            myfile.write(\"# wledback\\nApp.ActiveDocument.Spreadsheet.set('B9', '{0}')\\n\".format(wledback))\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"doc = FreeCAD.activeDocument()\\n\")\r\n            myfile.write(\"__objs__=[]\\n\")\r\n            myfile.write(\"for obj in doc.Objects:\t\\n\")\r\n            myfile.write(\"    if obj.ViewObject.Visibility:\\n\")\r\n            myfile.write(\"        __objs__.append(obj)\\n\")\r\n            myfile.write(\"\\nFreeCADGui.export(__objs__,os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.wrl\\\")\\n\".format(\r\n                footprint_name))\r\n            myfile.write(\"doc.saveCopy(os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.FCStd\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"print(\\\"created {0}\\\")\\n\".format(footprint_name))\r\n    \r\n    # init kicad footprint\r\n    kicad_mod = Footprint(footprint_name)\r\n    kicad_mod.setDescription(description)\r\n    kicad_mod.setTags(tags)\r\n    \r\n    kicad_modg = Translation(offset[0], offset[1])\r\n    kicad_mod.append(kicad_modg)\r\n    \r\n    # set general values\r\n    kicad_modg.append(Text(type='reference', text='REF**', at=[0, t_slk - txtoffset], layer='F.SilkS'))\r\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[0, t_slk + h_slk + txtoffset], layer='F.Fab'))\r\n    \r\n    # create FAB-layer\r\n    if type == \"round\":\r\n        \r\n        kicad_modg.append(Arc(center=[0,offsetled+wled-dled/2], start=[-dled/2,offsetled+wled-dled/2], angle=-180 , layer='F.Fab', width=lw_fab))\r\n        kicad_modg.append(Line(start=[ -dled/2,offsetled], end=[-dled / 2,offsetled+wled-dled/2], layer='F.Fab', width=lw_fab))\r\n        kicad_modg.append(Line(start=[dled / 2, offsetled], end=[dled / 2, offsetled + wled - dled / 2], layer='F.Fab', width=lw_fab))\r\n        kicad_modg.append(Line(start=[ -dled/2,offsetled], end=[dled / 2,offsetled], layer='F.Fab',width=lw_fab))\r\n        kicad_modg.append(RectLine(start=[ dledout/2,offsetled], end=[dled / 2,offsetled+wledback], layer='F.Fab',width=lw_fab))\r\n    elif type == \"box\":\r\n        if wledback<=0:\r\n            kicad_modg.append(\r\n                RectLine(start=[-dledout / 2, offsetled], end=[dledout / 2, offsetled + wled], layer='F.Fab',width=lw_fab))\r\n        else:\r\n            kicad_modg.append(RectLine(start=[-dledout / 2,offsetled], end=[dledout / 2,offsetled+wledback], layer='F.Fab',width=lw_fab))\r\n        if dled != dledout:\r\n            kicad_modg.append(\r\n                RectLine(start=[-dled / 2, offsetled+wledback], end=[dled / 2, offsetled + wled], layer='F.Fab',width=lw_fab))\r\n\r\n    for p in padpos:\r\n        kicad_modg.append(\r\n            RectLine(start=[p[1],p[2]], end=[p[1],offsetled], layer='F.Fab', width=lw_fab))\r\n    \r\n    # build keepeout for SilkScreen\r\n    keepouts = []\r\n    for p in padpos:\r\n        if p[0] == 1:\r\n            keepouts = keepouts + addKeepoutRect(p[1], p[2], p[4] + 2 * lw_slk + 2 * slk_offset,\r\n                                                 p[5] + 2 * lw_slk + 2 * slk_offset)\r\n        else:\r\n            keepouts = keepouts + addKeepoutRound(p[1], p[2], p[4] + 2 * lw_slk + 2 * slk_offset,\r\n                                                  p[5] + 2 * lw_slk + 2 * slk_offset)\r\n    \r\n    # create SILKSCREEN-layer\r\n    if type == \"round\":\r\n        kicad_modg.append(Arc(center=[0, offsetled + wled - dled/2], start=[-dled / 2-slk_offset, offsetled + wled - dled/2], angle=-180,layer='F.SilkS', width=lw_slk))\r\n        kicad_modg.append(Line(start=[-dled / 2-slk_offset, offsetled-slk_offset], end=[-dled / 2-slk_offset, offsetled + wled - dled / 2],  layer='F.SilkS',width=lw_slk))\r\n        kicad_modg.append(Line(start=[dled / 2+slk_offset, offsetled-slk_offset], end=[dled / 2+slk_offset, offsetled + wled - dled / 2],  layer='F.SilkS',width=lw_slk))\r\n        kicad_modg.append(Line(start=[-dled / 2-slk_offset, offsetled-slk_offset], end=[dled / 2+slk_offset, offsetled-slk_offset],  layer='F.SilkS', width=lw_slk))\r\n        kicad_modg.append(RectLine(start=[dledout / 2+slk_offset, offsetled-slk_offset], end=[dled / 2+slk_offset, offsetled + wledback+slk_offset],  layer='F.SilkS',width=lw_slk))\r\n    elif type == \"box\":\r\n        if wledback<=0:\r\n            kicad_modg.append(RectLine(start=[-dledout / 2-slk_offset, offsetled-slk_offset], end=[dledout / 2+slk_offset, offsetled + wled+slk_offset], layer='F.SilkS',width=lw_slk))\r\n            kicad_modg.append(Line(start=[-dledout / 2 - slk_offset+lw_slk, offsetled - slk_offset],end=[-dledout / 2+lw_slk -slk_offset, offsetled + wled + slk_offset], layer='F.SilkS',width=lw_slk))\r\n            kicad_modg.append(Line(start=[-dledout / 2 - slk_offset+lw_slk*2, offsetled - slk_offset],end=[-dledout / 2+lw_slk*2 -slk_offset, offsetled + wled + slk_offset], layer='F.SilkS',width=lw_slk))\r\n        else:\r\n            kicad_modg.append(RectLine(start=[-dledout / 2-slk_offset,offsetled-slk_offset], end=[dledout / 2+slk_offset,offsetled+wledback+slk_offset], layer='F.SilkS',width=lw_slk))\r\n            kicad_modg.append(Line(start=[-dledout / 2 - slk_offset+lw_slk, offsetled - slk_offset],end=[-dledout / 2 + lw_slk - slk_offset, offsetled + wledback + slk_offset],layer='F.SilkS', width=lw_slk))\r\n            kicad_modg.append(Line(start=[-dledout / 2 - slk_offset+lw_slk*2, offsetled - slk_offset],end=[-dledout / 2 + lw_slk*2 - slk_offset, offsetled + wledback + slk_offset],layer='F.SilkS', width=lw_slk))\r\n        if dled != dledout:\r\n            kicad_modg.append(\r\n                RectLine(start=[-dled / 2-slk_offset, offsetled+wledback+slk_offset], end=[dled / 2+slk_offset, offsetled + wled+slk_offset], layer='F.SilkS',width=lw_slk))\r\n        \r\n        \r\n        \r\n\r\n    for p in padpos:\r\n        if pady/2+slk_offset+lw_slk<offsetled-slk_offset:\r\n            kicad_modg.append(RectLine(start=[p[1], pady/2+slk_offset+lw_slk], end=[p[1], offsetled-slk_offset],  layer='F.SilkS', width=lw_slk))\r\n    \r\n    \r\n    \r\n    # create courtyard\r\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\r\n                              end=[roundCrt(l_crt + w_crt + offset[0]), roundCrt(t_crt + h_crt + offset[1])],\r\n                              layer='F.CrtYd', width=lw_crt))\r\n\r\n    # debug_draw_keepouts(kicad_modg, keepouts)\r\n    \r\n    # create pads\r\n    pn = 1\r\n    for p in padpos:\r\n        ps = Pad.SHAPE_CIRCLE\r\n        if (p[4] != p[5]):\r\n            ps = Pad.SHAPE_OVAL\r\n        if p[0] == 1:\r\n            ps = pad1style\r\n        kicad_modg.append(Pad(number=p[0], type=Pad.TYPE_THT, shape=ps, at=[p[1], p[2]], size=[p[4], p[5]], drill=p[3],\r\n                              layers=['*.Cu', '*.Mask']))\r\n    \r\n    # add model\r\n    if (has3d != 0):\r\n        kicad_modg.append(\r\n            Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=[0, 0, 0]))\r\n    \r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n    \r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(footprint_name + '.kicad_mod')\r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "scripts/tools/footprint_scripts_crystals.py",
    "content": "#!/usr/bin/env python\r\n\r\nimport sys\r\nimport os\r\nimport math\r\n\r\n# ensure that the kicad-footprint-generator directory is available\r\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\r\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\r\n\r\nfrom KicadModTree import *  # NOQA\r\nfrom drawing_tools import *\r\n\r\n\r\ndef makeSMDCrystalAndHand(footprint_name, addSizeFootprintName, pins, pad_sep_x, pad_sep_y, pad, pack_width,\r\n                          pack_height, pack_bevel, hasAdhesive=False, adhesivePos=[0, 0], adhesiveSize=1, style=\"rect\",\r\n                          description=\"Crystal SMD SMT\", tags=[], lib_name=\"Crystals\", offset3d=[0, 0, 0],\r\n                          scale3d=[1, 1, 1], rotate3d=[0, 0, 0]):\r\n    makeSMDCrystal(footprint_name, addSizeFootprintName, pins, pad_sep_x, pad_sep_y, pad, pack_width,\r\n                   pack_height, pack_bevel, hasAdhesive, adhesivePos, adhesiveSize, style,\r\n                   description, tags, lib_name, offset3d, scale3d, rotate3d)\r\n    hsfactorx = 1.75\r\n    hsfactory = 1\r\n    if (pins == 2 and pack_width > pad_sep_x + pad[0]):\r\n        hsfactorx = 1\r\n        hsfactory = 1.75\r\n    elif (pins == 4 and pack_width < pad_sep_x + pad[0] and pack_height < pad_sep_y + pad[1]):\r\n        hsfactorx = 1.5\r\n        hsfactory = 1.5\r\n    elif (pins == 4 and pack_width > pad_sep_x + pad[0] and pack_height < pad_sep_y + pad[1]):\r\n        hsfactorx = 1.1\r\n        hsfactory = 1.5\r\n    elif (pins == 4 and pack_width < pad_sep_x + pad[0] and pack_height > pad_sep_y + pad[1]):\r\n        hsfactorx = 1.5\r\n        hsfactory = 1.1\r\n    \r\n    makeSMDCrystal(footprint_name, addSizeFootprintName, pins, pad_sep_x + pad[0] * (hsfactorx - 1),\r\n                   pad_sep_y + pad[1] * (hsfactory - 1), [pad[0] * hsfactorx, pad[1] * hsfactory], pack_width,\r\n                   pack_height, pack_bevel, hasAdhesive, adhesivePos, adhesiveSize, style,\r\n                   description + \", hand-soldering\", tags + \" hand-soldering\", lib_name, offset3d, scale3d, rotate3d,\r\n                   name_addition=\"_HandSoldering\")\r\n\r\n\r\n#\r\n#          <----------pad_sep_x------------->\r\n#        <----------pack_width-------------->\r\n#  #=============#                   #=============#\r\n#  |   4         |                   |         3   |\r\n#  |     +----------------------------------+      |    ^            ^\r\n#  |     |       |                   |      |      |    |            |\r\n#  #=============#                   #=============#    |            |\r\n#        |                                  |           |            |\r\n#        |                                  |           pack_height  |\r\n#        |                                  |           |            pad_sep_y\r\n#        |                                  |           |            |\r\n#  #=============#                   #=============#    |  ^         |\r\n#  |     |       |                   |      |      |    |  |         |\r\n#  |     +----------------------------------+      |    v  |         v\r\n#  |   1         |                   |         2   |       pad[1]\r\n#  #=============#                   #=============#       v\r\n#                                    <---pad[0]---->\r\n#\r\n#\r\n# pins=2,4\r\n# style=\"rect\"/\"hc49\"/\"dip\"\r\ndef makeSMDCrystal(footprint_name, addSizeFootprintName, pins, pad_sep_x, pad_sep_y, pad, pack_width, pack_height,\r\n                   pack_bevel, hasAdhesive=False, adhesivePos=[0, 0], adhesiveSize=1, style=\"rect\",\r\n                   description=\"Crystal SMD SMT\", tags=[], lib_name=\"Crystals\", offset3d=[0, 0, 0], scale3d=[1, 1, 1],\r\n                   rotate3d=[0, 0, 0], name_addition=\"\"):\r\n    fpname = footprint_name\r\n    if addSizeFootprintName:\r\n        fpname += \"-{2}pin_{0:2.1f}x{1:2.1f}mm\".format(pack_width, pack_height, pins)\r\n    fpname = fpname + name_addition\r\n    \r\n    overpad_height = pad_sep_y + pad[1]\r\n    overpad_width = pad_sep_x + pad[0]\r\n    if pins == 3:\r\n        overpad_height = pad_sep_y * 2 + pad[1]\r\n        overpad_width = pad_sep_x * 2 + pad[0]\r\n    \r\n    betweenpads_x_slk = pad_sep_x - pad[0] - 2 * slk_offset\r\n    betweenpads_y_slk = pad_sep_y - pad[1] - 2 * slk_offset\r\n    overpads_x_slk = pad_sep_x + pad[0] + 2 * slk_offset\r\n    overpads_y_slk = pad_sep_y + pad[1] + 2 * slk_offset\r\n    if pins == 3:\r\n        overpads_x_slk = pad_sep_x * 2 + pad[0] + 2 * slk_offset\r\n        overpads_y_slk = pad_sep_y * 2 + pad[1] + 2 * slk_offset\r\n    elif pins == 6:\r\n        overpads_x_slk = pad_sep_x * 2 + pad[0] + 2 * slk_offset\r\n\r\n    dip_size = 1\r\n    \r\n    mark_size = max(1.5*pack_bevel,1)\r\n    upright_mark = False\r\n    while pack_height < 2 * mark_size or pack_width < 2 * mark_size:\r\n        mark_size = mark_size / 2\r\n    \r\n    if pack_bevel > 0 and math.fabs(mark_size / pack_bevel) > 0.7 and math.fabs(mark_size / pack_bevel) < 1.3:\r\n        upright_mark = True\r\n    \r\n    h_fab = pack_height\r\n    w_fab = pack_width\r\n    l_fab = -w_fab / 2\r\n    t_fab = -h_fab / 2\r\n    r_fab = pack_width / 10\r\n    \r\n    h_slk = h_fab + 2 * slk_offset\r\n    w_slk = w_fab + 2 * slk_offset\r\n    l_slk = l_fab - slk_offset\r\n    t_slk = t_fab - slk_offset\r\n    dip_size_slk = dip_size\r\n    \r\n    mark_l_slk = -overpads_x_slk / 2\r\n    if math.fabs(l_slk - mark_l_slk) < 2 * lw_slk:\r\n        mark_l_slk = l_slk - 2 * lw_slk\r\n    mark_b_slk = overpads_y_slk / 2\r\n    if math.fabs(t_slk + h_slk - mark_b_slk) < 2 * lw_slk:\r\n        mark_b_slk = t_slk + h_slk + 2 * lw_slk\r\n    \r\n    w_crt = max(overpad_width, pack_width) + 2 * crt_offset\r\n    h_crt = max(overpad_height, pack_height) + 2 * crt_offset\r\n    l_crt = -w_crt / 2\r\n    t_crt = -h_crt / 2\r\n    \r\n    print(fpname)\r\n    \r\n    desc = description + \", {0:2.1f}x{1:2.1f}mm^2 package\".format(pack_width, pack_height)\r\n    tag_s = tags + \" {0:2.1f}x{1:2.1f}mm^2 package\".format(pack_width, pack_height)\r\n    \r\n    # init kicad footprint\r\n    kicad_mod = Footprint(fpname)\r\n    kicad_mod.setDescription(desc)\r\n    kicad_mod.setTags(tags)\r\n    \r\n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\r\n    kicad_mod.setAttribute('smd')\r\n    offset = [0, 0]\r\n    kicad_modg = kicad_mod\r\n    \r\n    # set general values\r\n    kicad_modg.append(\r\n        Text(type='reference', text='REF**', at=[0, min(t_slk, -overpad_height / 2, -pack_height / 2) - txt_offset],\r\n             layer='F.SilkS'))\r\n    # kicad_modg.append(Text(type='user', text='%R', at=[0, min(t_slk,-overpad_height/2,-pack_height/2)-txt_offset], layer='F.Fab'))\r\n    kicad_modg.append(\r\n        Text(type='value', text=fpname, at=[0, max(t_slk + h_slk, overpad_height / 2, pack_height / 2) + txt_offset],\r\n             layer='F.Fab'))\r\n    \r\n    # create FAB-layer\r\n    if style == 'hc49':\r\n        THTQuartzRect(kicad_modg, [l_fab, t_fab], [w_fab, h_fab], [w_fab * 0.9, h_fab * 0.9], 'F.Fab', lw_fab)\r\n    elif style == 'dip':\r\n        DIPRectL(kicad_modg, [l_fab, t_fab], [w_fab, h_fab], 'F.Fab', lw_fab, dip_size)\r\n    elif style == 'rect1bevel':\r\n        bevelRectBL(kicad_modg, [l_fab, t_fab], [w_fab, h_fab], 'F.Fab', lw_fab, dip_size)\r\n    else:\r\n        allBevelRect(kicad_modg, [l_fab, t_fab], [w_fab, h_fab], 'F.Fab', lw_fab, pack_bevel)\r\n        if upright_mark:\r\n            kicad_modg.append(Line(start=[l_fab + max(mark_size, pack_bevel), t_fab],\r\n                                   end=[l_fab + max(mark_size, pack_bevel), t_fab + h_fab], layer='F.Fab',\r\n                                   width=lw_fab))\r\n        else:\r\n            kicad_modg.append(\r\n                Line(start=[l_fab, t_fab + h_fab - mark_size], end=[l_fab + mark_size, t_fab + h_fab], layer='F.Fab',\r\n                     width=lw_fab))\r\n    \r\n    # create SILKSCREEN-layer\r\n    if pins == 2:\r\n        if pack_height < pad[1]:\r\n            kicad_modg.append(\r\n                Line(start=[-betweenpads_x_slk / 2, t_slk], end=[betweenpads_x_slk / 2, t_slk], layer='F.SilkS',\r\n                     width=lw_slk))\r\n            kicad_modg.append(\r\n                Line(start=[-betweenpads_x_slk / 2, t_slk + h_slk], end=[betweenpads_x_slk / 2, t_slk + h_slk],\r\n                     layer='F.SilkS', width=lw_slk))\r\n            # pin1 mark\r\n            kicad_modg.append(Line(start=[min(l_slk, -overpads_x_slk / 2), -pad[1] / 2],\r\n                                   end=[min(l_slk, -overpads_x_slk / 2), pad[1] / 2], layer='F.SilkS', width=lw_slk))\r\n        else:\r\n            kicad_modg.append(PolygoneLine(polygone=[[l_slk + w_slk, t_slk],\r\n                                                     [-overpads_x_slk / 2, t_slk],\r\n                                                     [-overpads_x_slk / 2, t_slk + h_slk],\r\n                                                     [l_slk + w_slk, t_slk + h_slk], ], layer='F.SilkS', width=lw_slk))\r\n    elif pins == 3:\r\n        if (pack_height < overpad_height and pack_width > overpad_width):\r\n            kicad_modg.append(PolygoneLine(polygone=[[overpads_x_slk / 2, t_slk],\r\n                                                     [l_slk + w_slk, t_slk],\r\n                                                     [l_slk + w_slk, t_slk + h_slk],\r\n                                                     [overpads_x_slk / 2, t_slk + h_slk]], layer='F.SilkS',\r\n                                           width=lw_slk))\r\n            kicad_modg.append(Line(start=[l_slk - 2 * lw_slk, t_slk],\r\n                                   end=[l_slk - 2 * lw_slk, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\r\n            \r\n            kicad_modg.append(PolygoneLine(polygone=[[-overpads_x_slk / 2, mark_b_slk],\r\n                                                     [-overpads_x_slk / 2, t_slk + h_slk],\r\n                                                     [l_slk, t_slk + h_slk],\r\n                                                     [l_slk, t_slk],\r\n                                                     [-overpads_x_slk / 2, t_slk]], layer='F.SilkS',\r\n                                           width=lw_slk))\r\n        \r\n        else:\r\n            kicad_modg.append(PolygoneLine(polygone=[[-overpads_x_slk / 2, -overpads_y_slk / 2],\r\n                                                     [-overpads_x_slk / 2, overpads_y_slk / 2],\r\n                                                     [overpads_x_slk / 2, overpads_y_slk / 2]], layer='F.SilkS',\r\n                                           width=lw_slk))\r\n    elif pins >= 4:\r\n        if (betweenpads_y_slk < 5 * lw_slk or betweenpads_x_slk < 5 * lw_slk) and (pack_height < overpad_height and pack_width < overpad_width):\r\n            kicad_modg.append(PolygoneLine(polygone=[[-overpads_x_slk / 2, -overpads_y_slk / 2],\r\n                                                     [-overpads_x_slk / 2, overpads_y_slk / 2],\r\n                                                     [overpads_x_slk / 2, overpads_y_slk / 2]], layer='F.SilkS',\r\n                                           width=lw_slk))\r\n        else:\r\n            if (pack_height < overpad_height and pack_width < overpad_width):\r\n                \r\n                kicad_modg.append(PolygoneLine(polygone=[[mark_l_slk, betweenpads_y_slk / 2],\r\n                                                         [l_slk, betweenpads_y_slk / 2],\r\n                                                         [l_slk, -betweenpads_y_slk / 2]], layer='F.SilkS',\r\n                                               width=lw_slk))\r\n                kicad_modg.append(PolygoneLine(polygone=[[l_slk + w_slk, -betweenpads_y_slk / 2],\r\n                                                         [l_slk + w_slk, betweenpads_y_slk / 2]], layer='F.SilkS',\r\n                                               width=lw_slk))\r\n                if pins == 4:\r\n                    kicad_modg.append(PolygoneLine(polygone=[[-betweenpads_x_slk / 2, t_slk],\r\n                                                         [betweenpads_x_slk / 2, t_slk]], layer='F.SilkS',\r\n                                               width=lw_slk))\r\n                    kicad_modg.append(PolygoneLine(polygone=[[betweenpads_x_slk / 2, t_slk + h_slk],\r\n                                                         [-betweenpads_x_slk / 2, t_slk + h_slk],\r\n                                                         [-betweenpads_x_slk / 2, mark_b_slk]], layer='F.SilkS',\r\n                                               width=lw_slk))\r\n            elif (pack_height < overpad_height and pack_width > overpad_width):\r\n                kicad_modg.append(PolygoneLine(polygone=[[overpads_x_slk / 2, t_slk],\r\n                                                         [l_slk + w_slk, t_slk],\r\n                                                         [l_slk + w_slk, t_slk + h_slk],\r\n                                                         [overpads_x_slk / 2, t_slk + h_slk]], layer='F.SilkS',\r\n                                               width=lw_slk))\r\n                if pins == 4:\r\n                    kicad_modg.append(PolygoneLine(polygone=[[-betweenpads_x_slk / 2, t_slk],\r\n                                                         [betweenpads_x_slk / 2, t_slk]], layer='F.SilkS',\r\n                                               width=lw_slk))\r\n                if style == 'dip':\r\n                    DIPRectL_LeftOnly(kicad_modg, [l_slk, t_slk], [(w_slk - overpads_x_slk) / 2, h_slk], 'F.SilkS',\r\n                                      lw_slk, dip_size_slk)\r\n                    kicad_modg.append(\r\n                        Line(start=[betweenpads_x_slk / 2, t_slk + h_slk], end=[-betweenpads_x_slk / 2, t_slk + h_slk],\r\n                             layer='F.SilkS',\r\n                             width=lw_slk))\r\n                else:\r\n                    kicad_modg.append(PolygoneLine(polygone=[[-overpads_x_slk / 2, mark_b_slk],\r\n                                                             [-overpads_x_slk / 2, t_slk + h_slk],\r\n                                                             [l_slk, t_slk + h_slk],\r\n                                                             [l_slk, t_slk],\r\n                                                             [-overpads_x_slk / 2, t_slk]], layer='F.SilkS',\r\n                                                   width=lw_slk))\r\n                    if pins==4:\r\n                        kicad_modg.append(PolygoneLine(polygone=[[betweenpads_x_slk / 2, t_slk + h_slk],\r\n                                                             [-betweenpads_x_slk / 2, t_slk + h_slk],\r\n                                                             [-betweenpads_x_slk / 2, mark_b_slk]], layer='F.SilkS',\r\n                                                   width=lw_slk))\r\n            \r\n            elif (pack_height > overpad_height and pack_width < overpad_width):\r\n                kicad_modg.append(PolygoneLine(polygone=[[l_slk, -overpads_y_slk / 2],\r\n                                                         [l_slk, t_slk],\r\n                                                         [l_slk + w_slk, t_slk],\r\n                                                         [l_slk + w_slk, -overpads_y_slk / 2]], layer='F.SilkS',\r\n                                               width=lw_slk))\r\n                kicad_modg.append(PolygoneLine(polygone=[[mark_l_slk, overpads_y_slk / 2],\r\n                                                         [l_slk, overpads_y_slk / 2],\r\n                                                         [l_slk, t_slk + h_slk],\r\n                                                         [l_slk + w_slk, t_slk + h_slk],\r\n                                                         [l_slk + w_slk, overpads_y_slk / 2]], layer='F.SilkS',\r\n                                               width=lw_slk))\r\n                if pins == 4:\r\n                    kicad_modg.append(PolygoneLine(polygone=[[mark_l_slk, betweenpads_y_slk / 2],\r\n                                                             [l_slk, betweenpads_y_slk / 2],\r\n                                                             [l_slk, -betweenpads_y_slk / 2]], layer='F.SilkS',\r\n                                                   width=lw_slk))\r\n                    kicad_modg.append(PolygoneLine(polygone=[[l_slk + w_slk, -betweenpads_y_slk / 2],\r\n                                                             [l_slk + w_slk, betweenpads_y_slk / 2]], layer='F.SilkS',\r\n                                                   width=lw_slk))\r\n    \r\n    # create courtyard\r\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\r\n                              end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\r\n                              layer='F.CrtYd', width=lw_crt))\r\n    \r\n    # create pads\r\n    pad_type = Pad.TYPE_SMT\r\n    pad_shape1 = Pad.SHAPE_RECT\r\n    pad_layers = 'F'\r\n    ddrill = 0\r\n    \r\n    if (pins == 2):\r\n        kicad_modg.append(Pad(number=1, type=pad_type, shape=pad_shape1, at=[-pad_sep_x / 2, 0], size=pad, drill=ddrill,\r\n                              layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n        kicad_modg.append(Pad(number=2, type=pad_type, shape=pad_shape1, at=[pad_sep_x / 2, 0], size=pad, drill=ddrill,\r\n                              layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n    elif (pins == 3):\r\n        kicad_modg.append(Pad(number=1, type=pad_type, shape=pad_shape1, at=[-pad_sep_x, 0], size=pad, drill=ddrill,\r\n                              layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n        kicad_modg.append(Pad(number=2, type=pad_type, shape=pad_shape1, at=[0, 0], size=pad, drill=ddrill,\r\n                              layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n        kicad_modg.append(Pad(number=3, type=pad_type, shape=pad_shape1, at=[pad_sep_x, 0], size=pad, drill=ddrill,\r\n                              layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n    elif (pins == 4):\r\n        kicad_modg.append(\r\n            Pad(number=1, type=pad_type, shape=pad_shape1, at=[-pad_sep_x / 2, pad_sep_y / 2], size=pad, drill=ddrill,\r\n                layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n        kicad_modg.append(\r\n            Pad(number=2, type=pad_type, shape=pad_shape1, at=[pad_sep_x / 2, pad_sep_y / 2], size=pad, drill=ddrill,\r\n                layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n        kicad_modg.append(\r\n            Pad(number=3, type=pad_type, shape=pad_shape1, at=[pad_sep_x / 2, -pad_sep_y / 2], size=pad, drill=ddrill,\r\n                layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n        kicad_modg.append(\r\n            Pad(number=4, type=pad_type, shape=pad_shape1, at=[-pad_sep_x / 2, -pad_sep_y / 2], size=pad, drill=ddrill,\r\n                layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n\r\n    elif (pins == 6):\r\n        kicad_modg.append(\r\n            Pad(number=1, type=pad_type, shape=pad_shape1, at=[-pad_sep_x , pad_sep_y / 2], size=pad, drill=ddrill,\r\n                layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n        kicad_modg.append(\r\n            Pad(number=2, type=pad_type, shape=pad_shape1, at=[0, pad_sep_y / 2], size=pad, drill=ddrill,\r\n                layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n        kicad_modg.append(\r\n            Pad(number=3, type=pad_type, shape=pad_shape1, at=[pad_sep_x , pad_sep_y / 2], size=pad, drill=ddrill,\r\n                layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n        kicad_modg.append(\r\n            Pad(number=4, type=pad_type, shape=pad_shape1, at=[pad_sep_x , -pad_sep_y / 2], size=pad, drill=ddrill,\r\n                layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n        kicad_modg.append(\r\n            Pad(number=5, type=pad_type, shape=pad_shape1, at=[0, -pad_sep_y / 2], size=pad, drill=ddrill,\r\n                layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n        kicad_modg.append(\r\n            Pad(number=6, type=pad_type, shape=pad_shape1, at=[-pad_sep_x, -pad_sep_y / 2], size=pad, drill=ddrill,\r\n                layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n\r\n    if hasAdhesive:\r\n        fillCircle(kicad_modg, center=adhesivePos, radius=adhesiveSize / 2, width=0.1, layer='F.Adhes')\r\n    \r\n    # add model\r\n    kicad_modg.append(\r\n        Model(filename=lib_name + \".3dshapes/\" + fpname + \".wrl\", at=offset3d, scale=scale3d, rotate=rotate3d))\r\n    \r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n    \r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(fpname + '.kicad_mod')\r\n\r\n\r\ndef makeCrystalAll(footprint_name, rm, pad_size, ddrill, pack_width, pack_height, pack_offset, pack_rm, style=\"flat\",\r\n                   package_pad=False, package_pad_add_holes=False, package_pad_offset=0, package_pad_size=[0, 0],\r\n                   package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8, description=\"Crystal THT\",\r\n                   lib_name=\"Crystals\", tags=\"\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0],\r\n                   name_addition=\"\", pad_style=\"tht\", script3d=\"\", height3d=4.65, iheight3d=4):\r\n    makeCrystal(footprint_name, rm, pad_size, ddrill, pack_width, pack_height, pack_offset, pack_rm, style,\r\n                False, False, package_pad_offset, package_pad_size,\r\n                package_pad_drill_size, package_pad_ddrill, description,\r\n                lib_name, tags, offset3d, scale3d, rotate3d,\r\n                name_addition, pad_style, script3d, height3d, iheight3d)\r\n    if package_pad:\r\n        makeCrystal(footprint_name, rm, pad_size, ddrill, pack_width, pack_height, pack_offset, pack_rm, style,\r\n                    True, False, package_pad_offset, package_pad_size,\r\n                    package_pad_drill_size, package_pad_ddrill, description,\r\n                    lib_name, tags, offset3d, scale3d, rotate3d,\r\n                    name_addition + \"_1EP_style1\", pad_style, script3d, height3d, iheight3d)\r\n    if package_pad_add_holes and package_pad:\r\n        makeCrystal(footprint_name, rm, pad_size, ddrill, pack_width, pack_height, pack_offset, pack_rm, style,\r\n                    True, True, package_pad_offset, package_pad_size,\r\n                    package_pad_drill_size, package_pad_ddrill, description,\r\n                    lib_name, tags, offset3d, scale3d, rotate3d,\r\n                    name_addition + \"_1EP_style2\", pad_style, script3d, height3d, iheight3d)\r\n\r\n\r\n#                    +---------------------------------------------------------------+   ^\r\n#   OOOOO            |                                                               |   |\r\n#   OO1OO----^---    |                                                               |   |\r\n#   OOOOO    |   ----+ ^                                                             |   |\r\n#            |       | |                                                             |   |\r\n#           rm       | pack_rm                                                       |   pack_height\r\n#            |       | |                                                             |   |\r\n#   OOOOO    |   ----+ v                                                             |   |\r\n#   OO2OO ---v---    |                                                               |   |\r\n#   OOOOO            |                                                               |   |\r\n#                    +---------------------------------------------------------------+   v\r\n#                    <-----------------pack_width------------------------------------>\r\n#     <------------->pack_offset\r\n#\r\n#\r\n# pins=2,3\r\n# style=\"flat\"/\"hc49\"\r\n# pad_style=tht/smd for pin 1/2\r\ndef makeCrystal(footprint_name, rm, pad_size, ddrill, pack_width, pack_height, pack_offset, pack_rm, style=\"flat\",\r\n                package_pad=False, package_pad_add_holes=False, package_pad_offset=0, package_pad_size=[0, 0],\r\n                package_pad_drill_size=[1.2, 1.2], package_pad_ddrill=0.8, description=\"Crystal THT\",\r\n                lib_name=\"Crystals\", tags=\"\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0],\r\n                name_addition=\"\", pad_style=\"tht\", script3d=\"\", height3d=4.65, iheight3d=4):\r\n    fpname = footprint_name\r\n    fpname = fpname + name_addition\r\n    \r\n    if type(pad_size) is list:\r\n        pad=[pad_size[1],pad_size[0]]\r\n    else:\r\n        pad = [pad_size, pad_size]\r\n    \r\n    pad3pos = [rm / 2, package_pad_offset + package_pad_size[0] / 2]\r\n    pad3dril_xoffset = package_pad_size[1] / 2 + package_pad_ddrill / 2\r\n    \r\n    \r\n    h_fab = pack_width\r\n    w_fab = pack_height\r\n    l_fab = -(w_fab - rm) / 2\r\n    t_fab = pack_offset\r\n    \r\n    h_slk = h_fab + 2 * slk_offset\r\n    w_slk = w_fab + 2 * slk_offset\r\n    l_slk = l_fab - slk_offset\r\n    t_slk = t_fab - slk_offset\r\n    \r\n    bev = 0\r\n    if style == \"hc49\":\r\n        bev = min(0.35, max(2 * lw_slk, w_slk / 7))\r\n    \r\n    slk_u_line=False\r\n    if package_pad:\r\n        if (package_pad_size[1] < pack_width / 2):\r\n            h_slk=math.fabs((pad3pos[1]-package_pad_size[0]/2-slk_offset)-t_slk)\r\n            slk_u_line = True\r\n        else:\r\n            h_slk = max(t_slk + h_slk, pad3pos[1] + package_pad_size[0] / 2 + slk_offset) - t_slk\r\n        l_slk = min(l_slk, rm / 2 - package_pad_size[1] / 2 - slk_offset)\r\n        w_slk = max(l_slk+w_slk, rm / 2 + package_pad_size[1] / 2 + slk_offset)-l_slk\r\n        if package_pad_add_holes:\r\n            l_crt = pad3pos[0] - pad3dril_xoffset - package_pad_drill_size[0] / 2 - crt_offset\r\n            \r\n    \r\n    \r\n    extra_textoffset = 0\r\n    if (l_slk>-(pad[0]/2+slk_offset+lw_slk)):\r\n        extra_textoffset=pad[0]/2+slk_offset+lw_slk-0.5\r\n    \r\n    t_crt = -pad[1] / 2 - crt_offset\r\n    w_crt = max(pack_height + 2 * bev + 4 * crt_offset, pad[0] + rm, w_slk) + 2 * crt_offset\r\n    h_crt = max(t_slk + h_slk - t_crt, pad3pos[1] + package_pad_size[0] / 2-t_crt-crt_offset,pack_width + pack_offset+pad[1]/2) + 2 * crt_offset\r\n    l_crt = rm / 2 - w_crt / 2\r\n    \r\n    if package_pad and package_pad_add_holes and (pad[1]<pack_width/2):\r\n        l_crt = min(l_crt, pad3pos[0] - pad3dril_xoffset - package_pad_drill_size[0] / 2 - crt_offset)\r\n        w_crt = max(w_crt, pad3pos[0] + pad3dril_xoffset + package_pad_drill_size[0] / 2 + crt_offset - l_crt)\r\n    \r\n    print(fpname)\r\n    \r\n    \r\n\r\n    if script3d!=\"\":\r\n        with open(script3d, \"a\") as myfile:\r\n            myfile.write(\"\\n\\n # {0}\\n\".format(footprint_name))\r\n            myfile.write(\"import FreeCAD\\n\")\r\n            myfile.write(\"import os\\n\")\r\n            myfile.write(\"import os.path\\n\\n\")\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B5', '0.02')\\n\")\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"# W\\nApp.ActiveDocument.Spreadsheet.set('B1', '{0}')\\n\".format(pack_width) )\r\n            myfile.write(\"# Wi\\nApp.ActiveDocument.Spreadsheet.set('C1', '{0}')\\n\".format(int(pack_width*0.96)) )\r\n            myfile.write(\"# H\\nApp.ActiveDocument.Spreadsheet.set('B2', '{0}')\\n\".format(pack_height))\r\n            myfile.write(\"# Hi\\nApp.ActiveDocument.Spreadsheet.set('C2', '{0}')\\n\".format(int(pack_height*0.96)))\r\n            myfile.write(\"# height3d\\nApp.ActiveDocument.Spreadsheet.set('B3', '{0}')\\n\".format(height3d))\r\n            myfile.write(\"# iheight3d\\nApp.ActiveDocument.Spreadsheet.set('C3', '{0}')\\n\".format(iheight3d))\r\n            myfile.write(\"# RM\\nApp.ActiveDocument.Spreadsheet.set('B4', '{0}')\\n\".format(rm))\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B5', '{0}')\\n\".format(ddrill-0.3))\r\n            myfile.write(\"# pack_offset\\nApp.ActiveDocument.Spreadsheet.set('B6', '{0}')\\n\".format(pack_offset))\r\n            myfile.write(\"# pack_rm\\nApp.ActiveDocument.Spreadsheet.set('B7', '{0}')\\n\".format(pack_rm))\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"doc = FreeCAD.activeDocument()\\n\")\r\n            myfile.write(\"__objs__=[]\\n\")\r\n            myfile.write(\"for obj in doc.Objects:\t\\n\")\r\n            myfile.write(\"    if obj.ViewObject.Visibility:\\n\")\r\n            myfile.write(\"        __objs__.append(obj)\\n\")\r\n            myfile.write(\"\\nFreeCADGui.export(__objs__,os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.wrl\\\")\\n\".format(fpname))\r\n            myfile.write(\"doc.saveCopy(os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.FCStd\\\")\\n\".format(fpname))\r\n            myfile.write(\"print(\\\"created {0}\\\")\\n\".format(fpname))\r\n    \r\n    desc = description\r\n    tag_s = tags\r\n    \r\n    # init kicad footprint\r\n    kicad_mod = Footprint(fpname)\r\n    kicad_mod.setDescription(desc)\r\n    kicad_mod.setTags(tags)\r\n    \r\n    offset = [0, 0]\r\n    if pad_style == \"smd\":\r\n        offset = [-rm / 2, -pad3pos[1]/2];\r\n        kicad_mod.setAttribute('smd')\r\n        kicad_modg = Translation(offset[0], offset[1])\r\n        kicad_mod.append(kicad_modg)\r\n    else:\r\n        kicad_modg = kicad_mod\r\n    \r\n    # set general values\r\n    kicad_modg.append(\r\n        Text(type='reference', text='REF**', at=[l_slk - bev / 2 - txt_offset-extra_textoffset, t_crt + h_crt / 4], layer='F.SilkS',\r\n             rotation=90))\r\n    kicad_modg.append(\r\n        Text(type='value', text=fpname, at=[l_slk + w_slk + txt_offset+extra_textoffset + bev / 2, t_crt + h_crt / 4], layer='F.Fab',\r\n             rotation=90))\r\n    \r\n    # create FAB-layer\r\n    kicad_modg.append(RectLine(start=[l_fab, t_fab],\r\n                                   end=[l_fab + w_fab, t_fab + h_fab], layer='F.Fab', width=lw_fab))\r\n    kicad_modg.append(PolygoneLine(polygone=[[l_fab + w_fab / 2 - pack_rm / 2, t_fab],\r\n                                             [0, t_fab/2],\r\n                                             [0, 0]], layer='F.Fab', width=lw_fab))\r\n    kicad_modg.append(PolygoneLine(polygone=[[l_fab + w_fab / 2 + pack_rm / 2, t_fab],\r\n                                             [rm, t_fab/2],\r\n                                             [rm, 0]], layer='F.Fab', width=lw_fab))\r\n    if package_pad and package_pad_add_holes:\r\n        kicad_modg.append(\r\n            Line(start=[pad3pos[0] - pad3dril_xoffset, pad3pos[1]], end=[pad3pos[0] + pad3dril_xoffset, pad3pos[1]],\r\n                 layer='F.Fab', width=lw_fab))\r\n    if style == \"hc49\":\r\n        kicad_modg.append(RectLine(start=[l_fab - bev, t_fab], end=[l_fab + w_fab + bev, t_fab - lw_fab], layer='F.Fab',\r\n                                   width=lw_fab))\r\n    # create SILKSCREEN-layer\r\n    if package_pad and package_pad_add_holes:\r\n        kicad_modg.append(PolygoneLine(polygone=[[l_slk, pad3pos[1] - package_pad_drill_size[1] / 2 - slk_offset],\r\n                                                 [l_slk, t_slk],\r\n                                                 [l_slk + w_slk, t_slk],\r\n                                                 [l_slk + w_slk,\r\n                                                  pad3pos[1] - package_pad_drill_size[1] / 2 - slk_offset]],\r\n                                       layer='F.SilkS', width=lw_slk))\r\n    else:\r\n        if slk_u_line:\r\n            kicad_modg.append(PolygoneLine(polygone=[[l_slk, t_slk + h_slk],\r\n                                                     [l_slk, t_slk],\r\n                                                     [l_slk + w_slk, t_slk],\r\n                                                     [l_slk + w_slk, t_slk + h_slk]], layer='F.SilkS', width=lw_slk))\r\n        else:\r\n            kicad_modg.append(\r\n                RectLine(start=[l_slk, t_slk], end=[l_slk + w_slk, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\r\n    kicad_modg.append(PolygoneLine(polygone=[[l_slk + w_slk / 2 - pack_rm / 2, t_slk], [0, max(t_slk/2,pad[1] / 2 + slk_offset)], [0, pad[1] / 2 + slk_offset]], layer='F.SilkS',width=lw_slk))\r\n    kicad_modg.append(PolygoneLine(polygone=[[l_slk + w_slk / 2 + pack_rm / 2, t_slk], [rm, max(t_slk/2,pad[1] / 2 + slk_offset)], [rm, pad[1] / 2 + slk_offset]], layer='F.SilkS',width=lw_slk))\r\n    if style == \"hc49\":\r\n        kicad_modg.append(\r\n            RectLine(start=[l_slk - bev, t_slk], end=[l_slk + w_slk + bev, t_slk - lw_slk], layer='F.SilkS',\r\n                     width=lw_slk))\r\n    \r\n    # create courtyard\r\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\r\n                              end=[roundCrt(l_crt + w_crt + offset[0]), roundCrt(t_crt + h_crt + offset[1])],\r\n                              layer='F.CrtYd', width=lw_crt))\r\n    \r\n    # create pads\r\n    pad_type = Pad.TYPE_THT\r\n    pad_shape1 = Pad.SHAPE_CIRCLE\r\n    pad_layers = '*'\r\n    if pad_style == \"smd\":\r\n        kicad_modg.append(Pad(number=1, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, at=[0, 0], size=pad, drill=0,\r\n                              layers=['F.Cu', 'F.Mask']))\r\n        kicad_modg.append(Pad(number=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, at=[rm, 0], size=pad, drill=0,\r\n                              layers=['F.Cu', 'F.Mask']))\r\n    else:\r\n        kicad_modg.append(Pad(number=1, type=pad_type, shape=pad_shape1, at=[0, 0], size=pad, drill=ddrill,\r\n                              layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n        kicad_modg.append(Pad(number=2, type=pad_type, shape=pad_shape1, at=[rm, 0], size=pad, drill=ddrill,\r\n                              layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n    \r\n    if package_pad:\r\n        kicad_modg.append(Pad(number=3, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, at=pad3pos,\r\n                              size=[package_pad_size[1], package_pad_size[0]], drill=0, layers=['F.Cu', 'F.Mask']))\r\n        if package_pad_add_holes:\r\n            kicad_modg.append(\r\n                Pad(number=3, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=[pad3pos[0] - pad3dril_xoffset, pad3pos[1]],\r\n                    size=package_pad_drill_size, drill=package_pad_ddrill,\r\n                    layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n            kicad_modg.append(\r\n                Pad(number=3, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=[pad3pos[0] + pad3dril_xoffset, pad3pos[1]],\r\n                    size=package_pad_drill_size, drill=package_pad_ddrill,\r\n                    layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n    \r\n    # add model\r\n    kicad_modg.append(\r\n        Model(filename=lib_name + \".3dshapes/\" + fpname + \".wrl\", at=offset3d, scale=scale3d, rotate=rotate3d))\r\n    \r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n    \r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(fpname + '.kicad_mod')\r\n\r\n\r\n#      +----------------------------------------------------+       ^\r\n#    /                                                       \\      |\r\n#   /       OOOOO                              OOOOO          \\     |\r\n#  |        OOOOO                              OOOOO          |     pack_height\r\n#   \\       OOOOO                              OOOOO         /      |\r\n#    \\                                                      /       |\r\n#      +----------------------------------------------------+       v\r\n#  <-------------------------pack_width----------------------->\r\n#              <-------------rm------------------>\r\n#\r\n#\r\n# pins=2,3\r\ndef makeCrystalHC49Vert(footprint_name, pins, rm, pad_size, ddrill, pack_width, pack_height, innerpack_width, innerpack_height,\r\n                description=\"Crystal THT\", lib_name=\"Crystals\", tags=\"\", offset3d=[0, 0, 0], scale3d=[1, 1, 1], rotate3d=[0, 0, 0], addSizeFootprintName=False,\r\n                        script3d=\"\", height3d=10):\r\n    fpname = footprint_name\r\n    desc = description\r\n    tag_s = tags\r\n\r\n    if addSizeFootprintName:\r\n        fpname += \"-{2}pin_w{0:2.1f}mm_h{1:2.1f}mm\".format(pack_width, pack_height, pins)\r\n        desc = description + \", length*width={0:2.1f}x{1:2.1f}mm^2 package, package length={0:2.1f}mm, package width={1:2.1f}mm, {2} pins\".format(pack_width, pack_height,pins)\r\n        tag_s = tags + \" {0:2.1f}x{1:2.1f}mm^2 package length {0:2.1f}mm width {1:2.1f}mm {2} pins\".format(pack_width, pack_height,pins)\r\n    \r\n    if type(pad_size) is list:\r\n        pad = [pad_size[1], pad_size[0]]\r\n    else:\r\n        pad = [pad_size, pad_size]\r\n        \r\n    centerpos=[rm/2,0]\r\n    pin1pos=[0,0]\r\n    pin2pos=[rm,0]\r\n    pin3pos = [rm / 2, 0]\r\n    if (pins==3):\r\n        pin2pos = [rm/2, 0]\r\n        pin3pos = [rm, 0]\r\n        \r\n        \r\n\r\n    w_fab = pack_width\r\n    h_fab = pack_height\r\n    l_fab = -(w_fab - rm) / 2\r\n    t_fab = -h_fab/2\r\n    iw_fab = innerpack_width\r\n    ih_fab = innerpack_height\r\n    il_fab = -(iw_fab - rm) / 2\r\n    it_fab = -ih_fab/2\r\n\r\n\r\n    incomplete_slk=False\r\n    h_slk = h_fab + 2 * slk_offset\r\n    w_slk = w_fab + 2 * slk_offset\r\n    l_slk = l_fab - slk_offset\r\n    t_slk = t_fab - slk_offset\r\n    \r\n    l_crt=l_slk-crt_offset\r\n    t_crt=t_slk-crt_offset\r\n    w_crt=w_slk+2*crt_offset\r\n    h_crt = h_slk + 2 * crt_offset\r\n    \r\n    if pack_width<rm+pad[0]:\r\n        l_crt = min(-pad[0]/2, l_fab) - crt_offset\r\n        w_crt = max(rm+pad[0], w_fab)+2*slk_offset\r\n        incomplete_slk = True\r\n        angle_slk=math.acos((pad[1]/2+slk_offset)/(h_slk/2))/3.1415*180\r\n    \r\n    print(fpname)\r\n    \r\n\r\n    if script3d!=\"\":\r\n        with open(script3d, \"a\") as myfile:\r\n            myfile.write(\"\\n\\n # {0}\\n\".format(footprint_name))\r\n            myfile.write(\"import FreeCAD\\n\")\r\n            myfile.write(\"import os\\n\")\r\n            myfile.write(\"import os.path\\n\\n\")\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B5', '0.02')\\n\")\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"# W\\nApp.ActiveDocument.Spreadsheet.set('B1', '{0}')\\n\".format(pack_width) )\r\n            myfile.write(\"# Wi\\nApp.ActiveDocument.Spreadsheet.set('C1', '{0}')\\n\".format(innerpack_width) )\r\n            myfile.write(\"# H\\nApp.ActiveDocument.Spreadsheet.set('B2', '{0}')\\n\".format(pack_height))\r\n            myfile.write(\"# Hi\\nApp.ActiveDocument.Spreadsheet.set('C2', '{0}')\\n\".format(innerpack_height))\r\n            myfile.write(\"# height3d\\nApp.ActiveDocument.Spreadsheet.set('B3', '{0}')\\n\".format(height3d))\r\n            myfile.write(\"# RM\\nApp.ActiveDocument.Spreadsheet.set('B4', '{0}')\\n\".format(rm))\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B5', '{0}')\\n\".format(ddrill-0.3))\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"doc = FreeCAD.activeDocument()\\n\")\r\n            myfile.write(\"__objs__=[]\\n\")\r\n            myfile.write(\"for obj in doc.Objects:\t\\n\")\r\n            myfile.write(\"    if obj.ViewObject.Visibility:\\n\")\r\n            myfile.write(\"        __objs__.append(obj)\\n\")\r\n            myfile.write(\"\\nFreeCADGui.export(__objs__,os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.wrl\\\")\\n\".format(fpname))\r\n            myfile.write(\"doc.saveCopy(os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.FCStd\\\")\\n\".format(fpname))\r\n            myfile.write(\"print(\\\"created {0}\\\")\\n\".format(fpname))\r\n\r\n    \r\n    # init kicad footprint\r\n    kicad_mod = Footprint(fpname)\r\n    kicad_mod.setDescription(desc)\r\n    kicad_mod.setTags(tags)\r\n    \r\n    offset = [0, 0]\r\n    kicad_modg = kicad_mod\r\n    \r\n    # set general values\r\n    kicad_modg.append(Text(type='reference', text='REF**', at=[centerpos[0], t_slk-txt_offset], layer='F.SilkS'))\r\n    kicad_modg.append(Text(type='value', text=fpname, at=[centerpos[0], t_slk+h_slk+txt_offset], layer='F.Fab'))\r\n    \r\n    # create FAB-layer\r\n    THTQuartz(kicad_modg, [l_fab,t_fab], [w_fab,h_fab], 'F.Fab', lw_fab)\r\n    THTQuartz(kicad_modg, [il_fab,it_fab], [iw_fab,ih_fab], 'F.Fab', lw_fab)\r\n\r\n\r\n    # create SILKSCREEN-layer\r\n    if incomplete_slk:\r\n        THTQuartzIncomplete(kicad_modg, [l_slk, t_slk], [w_slk, h_slk], angle_slk, 'F.SilkS', lw_slk)\r\n    else:\r\n        THTQuartz(kicad_modg, [l_slk,t_slk], [w_slk,h_slk], 'F.SilkS', lw_slk)\r\n    \r\n    # create courtyard\r\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\r\n                              end=[roundCrt(l_crt + w_crt + offset[0]), roundCrt(t_crt + h_crt + offset[1])],\r\n                              layer='F.CrtYd', width=lw_crt))\r\n    \r\n    # create pads\r\n    pad_type = Pad.TYPE_THT\r\n    pad_shape1 = Pad.SHAPE_CIRCLE\r\n    pad_layers = '*'\r\n\r\n    kicad_modg.append(Pad(number=1, type=pad_type, shape=pad_shape1, at=pin1pos, size=pad, drill=ddrill,\r\n                          layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n    kicad_modg.append(Pad(number=2, type=pad_type, shape=pad_shape1, at=pin2pos, size=pad, drill=ddrill,\r\n                          layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n    if pins==3:\r\n        kicad_modg.append(Pad(number=3, type=pad_type, shape=pad_shape1, at=pin3pos, size=pad, drill=ddrill,\r\n                              layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n    \r\n    # add model\r\n    kicad_modg.append(\r\n        Model(filename=lib_name + \".3dshapes/\" + fpname + \".wrl\", at=offset3d, scale=scale3d, rotate=rotate3d))\r\n    \r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n    \r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(fpname + '.kicad_mod')\r\n\r\n\r\n#       +---------------------------------------+       \r\n#      /                                         \\      \r\n#     /                                           \\      \r\n#    /                                             \\      \r\n#   /       OOOOO                    OOOOO          \\     \r\n#  |        OOOOO                    OOOOO          |     \r\n#   \\       OOOOO                    OOOOO         /      \r\n#    \\                                            /       \r\n#     \\                                          /       \r\n#      \\                                        /       \r\n#       +--------------------------------------+       \r\n#  <-----------------pack_diameter------------------>\r\n#              <-------------rm-------->\r\n#\r\n#\r\n# pins=2,3\r\ndef makeCrystalRoundVert(footprint_name, rm, pad_size, ddrill, pack_diameter,\r\n                         description=\"Crystal THT\", lib_name=\"Crystals\", tags=\"\", offset3d=[0, 0, 0], scale3d=[1, 1, 1],\r\n                         rotate3d=[0, 0, 0]):\r\n    fpname = footprint_name\r\n    \r\n    if type(pad_size) is list:\r\n        pad = [pad_size[1], pad_size[0]]\r\n    else:\r\n        pad = [pad_size, pad_size]\r\n    \r\n    centerpos = [rm / 2, 0]\r\n    pin1pos = [0, 0]\r\n    pin2pos = [rm, 0]\r\n    \r\n    d_fab = pack_diameter\r\n    cl_fab = rm / 2\r\n    ct_fab = 0\r\n    \r\n    d_slk = d_fab + 2 * slk_offset\r\n    cl_slk = cl_fab\r\n    ct_slk = ct_fab\r\n    sl_slk = 0\r\n    if d_fab >= rm + pad[0]:\r\n        st_slk = 0\r\n        sl_slk = min(-(d_fab - rm) / 2, - pad[0] / 2) - slk_offset\r\n        alpha_slk = 180\r\n    elif d_slk * d_slk / 4 >= rm * rm / 4:\r\n        st_slk = -max(math.sqrt(d_slk * d_slk / 4 - rm * rm / 4), pad[1] / 2 + slk_offset)\r\n        alpha_slk = 2 * (\r\n        90 - math.fabs(180 / 3.1415 * math.atan(math.fabs(st_slk - centerpos[1]) / math.fabs(sl_slk - centerpos[0]))))\r\n    else:\r\n        st_slk = -pad[1] / 2 - slk_offset\r\n        alpha_slk = 2 * (\r\n        90 - math.fabs(180 / 3.1415 * math.atan(math.fabs(st_slk - centerpos[1]) / math.fabs(sl_slk - centerpos[0]))))\r\n    \r\n    d_crt = max(rm + pad[0], d_slk) + 2 * crt_offset\r\n    cl_crt = cl_fab\r\n    ct_crt = ct_fab\r\n    \r\n    print(fpname)\r\n    \r\n    desc = description\r\n    tag_s = tags\r\n    \r\n    # init kicad footprint\r\n    kicad_mod = Footprint(fpname)\r\n    kicad_mod.setDescription(desc)\r\n    kicad_mod.setTags(tags)\r\n    \r\n    offset = [0, 0]\r\n    kicad_modg = kicad_mod\r\n    \r\n    # set general values\r\n    kicad_modg.append(\r\n        Text(type='reference', text='REF**', at=[centerpos[0], ct_slk - d_slk / 2 - txt_offset], layer='F.SilkS'))\r\n    kicad_modg.append(\r\n        Text(type='value', text=fpname, at=[centerpos[0], ct_slk + d_slk / 2 + txt_offset], layer='F.Fab'))\r\n    \r\n    # create FAB-layer\r\n    kicad_mod.append(Circle(center=[cl_fab, ct_fab], radius=d_fab / 2, layer='F.Fab', width=lw_fab))\r\n    \r\n    # create SILKSCREEN-layer\r\n    kicad_mod.append(\r\n        Arc(center=[cl_slk, ct_slk], start=[sl_slk, st_slk], angle=alpha_slk, layer='F.SilkS', width=lw_slk))\r\n    kicad_mod.append(\r\n        Arc(center=[cl_slk, ct_slk], start=[sl_slk, -st_slk], angle=-alpha_slk, layer='F.SilkS', width=lw_slk))\r\n    \r\n    # create courtyard\r\n    kicad_mod.append(Circle(center=[cl_crt, ct_crt], radius=d_crt / 2, layer='F.CrtYd', width=lw_crt))\r\n    \r\n    # create pads\r\n    pad_type = Pad.TYPE_THT\r\n    pad_shape1 = Pad.SHAPE_CIRCLE\r\n    pad_layers = '*'\r\n    \r\n    kicad_modg.append(Pad(number=1, type=pad_type, shape=pad_shape1, at=pin1pos, size=pad, drill=ddrill,\r\n                          layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n    kicad_modg.append(Pad(number=2, type=pad_type, shape=pad_shape1, at=pin2pos, size=pad, drill=ddrill,\r\n                          layers=[pad_layers + '.Cu', pad_layers + '.Mask']))\r\n    \r\n    # add model\r\n    kicad_modg.append(\r\n        Model(filename=lib_name + \".3dshapes/\" + fpname + \".wrl\", at=offset3d, scale=scale3d, rotate=rotate3d))\r\n    \r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n    \r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(fpname + '.kicad_mod')\r\n\r\n\r\n"
  },
  {
    "path": "scripts/tools/footprint_scripts_dsub.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom drawing_tools import *  # NOQA\nfrom math import sqrt\n\ncrt_offset = 0.5 # different for connectors\n\n\n\ndef makeDSubStraight(pins, isMale, HighDensity, rmx, rmy, pindrill, pad, mountingdrill, mountingpad, mountingdistance, outline_size, outline_cornerradius, connwidth, connheight, side_angle_degree, conn_cornerradius,\n                        tags_additional=[], lib_name=\"${{KISYS3DMOD}}/Connectors_DSub\", classname=\"DSub\", classname_description=\"D-Sub connector\", webpage=\"\", HighDensityOffsetMidLeft=0):\n                        \n    hasMountingHoles=mountingdrill>0 and mountingdistance>0\n    \n    # rectangular outside of connector outer part on F.Fab\n    w_fab = outline_size[0]\n    h_fab = outline_size[1]\n    l_fab = -w_fab/2\n    t_fab = -h_fab/2\n\n    # rectangular outside of connector inner part on F.Fab\n    wi_fab = connwidth\n    hi_fab = connheight\n    li_fab = -wi_fab/2\n    ti_fab = -hi_fab/2\n\n\n    # rectangular outside of connector outer part on silkscreen\n    h_slk = h_fab + 2 * slk_offset\n    w_slk = w_fab + 2 * slk_offset\n    l_slk = l_fab - slk_offset\n    t_slk = t_fab - slk_offset\n    \n    # rectangular outside of connector inner part on silkscreen\n    hi_slk = hi_fab + 2 * slk_offset\n    wi_slk = wi_fab + 2 * slk_offset\n    li_slk = li_fab - slk_offset\n    ti_slk = ti_fab - slk_offset\n    \n    package_size=[0,0];\n    \n    w_crt = max([w_fab, mountingpad+mountingdistance, mountingpad+mountingdistance])+2*crt_offset\n    h_crt = max([h_fab, mountingpad, mountingdrill])+2*crt_offset\n    l_crt = -w_crt/2\n    t_crt = -h_crt/2\n    \n    \n    text_size = w_fab*0.6\n    fab_text_size_max = 1.0\n    if text_size < fab_text_size_min:\n        text_size = fab_text_size_min\n    elif text_size > fab_text_size_max:\n        text_size = fab_text_size_max\n    text_size = round(text_size, 2)\n    text_size = [text_size,text_size]\n    text_t = text_size[0] * 0.15\n    \n    \n    description = \"{0}-pin {1}, straight/vertical, THT-mount\".format(pins, classname_description)\n    tags = \"{0}-pin {1} straight vertical THT\".format(pins, classname_description)\n    footprint_name=\"{0}-{1}\".format(classname,pins)\n    if HighDensity:\n        footprint_name=footprint_name+\"-HD\"\n    if isMale:\n        description = description+\", male\"\n        tags = tags+\" male\"\n        footprint_name=footprint_name+\"_Male\"\n    else:\n        description = description+\", female\"\n        tags = tags+\" female\"\n        footprint_name=footprint_name+\"_Female\"\n    \n    description = description+\", pitch {0}x{1}mm\".format(rmx,rmy)\n    tags = tags+\" pitch {0}x{1}mm\".format(rmx,rmy)\n    footprint_name=footprint_name+\"_Vertical\"\n    footprint_name=footprint_name+\"_Pitch{0:3.2f}x{1:3.2f}mm\".format(rmx,rmy)\n\n    description = description+\", distance of mounting holes {0}mm\".format(mountingdistance)\n    tags = tags+\" mounting holes distance {0}mm\".format(mountingdistance)\n    #footprint_name=footprint_name+\"_MHDist{0:3.2f}mm\".format(mountingdistance)\n    \n    if hasMountingHoles:\n        footprint_name=footprint_name+\"_MountingHoles\"\n\n    if len(webpage)>0:\n        description = description+\", see {0}\".format(webpage)\n    \n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n    \n    print(footprint_name)\n    \n    pinstop=int((pins + 1)/2)\n    pinsmid=0\n    pinsbot=int((pins - 1)/2)\n    drmy=rmy/2\n    if HighDensity:\n        pinstop=int((pins+1)/3)\n        pinsmid=pinstop\n        pinsbot=pins-pinstop-pinsbot\n        drmy=rmy\n\n    y1=-drmy\n    x10=-(pinstop-1)/2*rmx\n    topoffset=0\n    botoffset=rmx/2\n    if HighDensity:\n        x10=-mountingdistance/2+HighDensityOffsetMidLeft\n        topoffset=rmx/2\n        botoffset=rmx/2\n        \n    \n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n    \n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    if not isMale:\n        offset=[x10+topoffset,drmy]\n    else:\n        offset=[-(topoffset+x10),drmy]\n    kicad_modg = Translation(offset[0], offset[1])\n    kicad_mod.append(kicad_modg)\n    \n    # set general values\n    kicad_modg.append(Text(type='reference', text='REF**', at=[l_fab+w_fab/2, t_slk - txt_offset], layer='F.SilkS'))\n    kicad_modg.append(Text(type='user', text='%R', at=[0,0], layer='F.Fab', size=text_size ,thickness=text_t))\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[l_fab+w_fab/2, t_slk + h_slk + txt_offset], layer='F.Fab'))\n    \n    \n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0 \n     \n    pad_type = Pad.TYPE_THT \n    hole_type = Pad.TYPE_NPTH \n    pad_shape1 = Pad.SHAPE_RECT \n    pad_shapeother = Pad.SHAPE_CIRCLE\n    pad_layers = Pad.LAYERS_THT\n    keepouts=[];\n\n    \n    \n    y1=-drmy\n    x1pos=0\n    if isMale:\n        x1=x10+topoffset\n    else:\n        x1=-x10-topoffset\n            \n    for p in range(1, pinstop+1): \n         \n        if p == 1: \n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=pindrill, layers=pad_layers)) \n            keepouts=keepouts+addKeepoutRect(x1, y1, pad+8*slk_offset, pad+8*slk_offset)\n            x1pos=x1\n        else:\n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=pindrill, layers=pad_layers))\n            keepouts=keepouts+addKeepoutRound(x1, y1, pad+(slk_pad_offset+2*lw_slk), pad+(slk_pad_offset+2*lw_slk))\n        \n        if isMale:\n            x1=x1+rmx\n        else:\n            x1=x1-rmx\n    if HighDensity:\n        if isMale:\n            x1=x10;\n        else:\n            x1=-x10;\n        y1=0\n        for p in range(pinstop+1, pinstop+pinsmid+1): \n             \n            if p == 1: \n                kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=pindrill, layers=pad_layers)) \n                keepouts=keepouts+addKeepoutRect(x1, y1, pad+8*slk_offset, pad+8*slk_offset)\n            else:\n                kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=pindrill, layers=pad_layers))\n                keepouts=keepouts+addKeepoutRound(x1, y1, pad+(slk_pad_offset+2*lw_slk), pad+(slk_pad_offset+2*lw_slk))\n            \n            if isMale:\n                x1=x1+rmx\n            else:\n                x1=x1-rmx\n\n    if isMale:\n        x1=x10+botoffset\n    else:\n        x1=-x10-botoffset\n    y1=drmy\n    for p in range(pinstop+pinsmid+1, pins+1): \n         \n        if p == 1: \n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=pindrill, layers=pad_layers)) \n            keepouts=keepouts+addKeepoutRect(x1, y1, pad+8*slk_offset, pad+8*slk_offset)\n        else:\n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=pindrill, layers=pad_layers))\n            keepouts=keepouts+addKeepoutRound(x1, y1, pad+(slk_pad_offset+2*lw_slk), pad+(slk_pad_offset+2*lw_slk))\n        \n        if isMale:\n            x1=x1+rmx\n        else:\n            x1=x1-rmx\n    \n    \n    if hasMountingHoles and mountingpad>0:\n        kicad_modg.append(Pad(number=0, type=pad_type, shape=pad_shapeother, at=[-mountingdistance/2, 0], size=[mountingpad,mountingpad], drill=mountingdrill, layers=pad_layers))\n        keepouts=keepouts+addKeepoutRound(-mountingdistance/2, 0, mountingpad+(slk_pad_offset+2*lw_slk), mountingpad+(slk_pad_offset+2*lw_slk))\n        kicad_modg.append(Pad(number=0, type=pad_type, shape=pad_shapeother, at=[mountingdistance/2, 0], size=[mountingpad,mountingpad], drill=mountingdrill, layers=pad_layers))\n        keepouts=keepouts+addKeepoutRound(mountingdistance/2, 0, mountingpad+(slk_pad_offset+2*lw_slk), mountingpad+(slk_pad_offset+2*lw_slk))\n    if hasMountingHoles and mountingpad<=0:\n        kicad_modg.append(Pad(number=0, type=hole_type, shape=pad_shapeother, at=[-mountingdistance/2, 0], size=[0,0], drill=mountingdrill, layers=pad_layers))\n        keepouts=keepouts+addKeepoutRound(-mountingdistance/2, 0, mountingpad+(slk_pad_offset+2*lw_slk), mountingpad+(slk_pad_offset+2*lw_slk))\n        kicad_modg.append(Pad(number=0, type=hole_type, shape=pad_shapeother, at=[mountingdistance/2, 0], size=[0,0], drill=mountingdrill, layers=pad_layers))\n        keepouts=keepouts+addKeepoutRound(mountingdistance/2, 0, mountingpad+(slk_pad_offset+2*lw_slk), mountingpad+(slk_pad_offset+2*lw_slk))\n    \n    # outline\n    addRoundedRect(kicad_modg, [l_fab, t_fab], [w_fab, h_fab], outline_cornerradius, layer='F.Fab', width=lw_fab)\n    addRoundedRect(kicad_modg, [l_slk, t_slk], [w_slk, h_slk], outline_cornerradius+slk_offset, layer='F.SilkS', width=lw_slk)\n\n    #pin1 mark\n    allEqualSidedDownTriangle(kicad_modg, xcenter=[x1pos, -h_slk/2-text_size[0]*0.75], side_length=text_size[0]/2, layer='F.SilkS', width=lw_slk)\n    \n    # connector_inside\n    allRoundedBevelRect(kicad_modg, [li_fab, ti_fab], [wi_fab, hi_fab], side_angle_degree, conn_cornerradius, layer='F.Fab', width=lw_fab)\n    allRoundedBevelRect(kicad_modg, [li_slk, ti_slk], [wi_slk, hi_slk], side_angle_degree, conn_cornerradius+slk_offset, layer='F.SilkS', width=lw_slk)\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\n                              end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\n                              layer='F.CrtYd', width=lw_crt))\n    \n    \n    # add model\n    kicad_mod.append(\n        Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=[0,0,0], scale=[1,1,1], rotate=[0,0,0]))\n    \n   \n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(footprint_name + '.kicad_mod')\n    \n    \n    \n\n\n\ndef makeDSubEdge(pins, isMale, rmx, pad, mountingdrill, mountingdistance, shield_width, connwidth, can_height, shieldthickness, backcan_width, backcan_height, smaller_backcan_offset, smaller_backcan_height, soldercup_length, soldercup_diameter,soldercup_pad_edge_offset,\n                        tags_additional=[], lib_name=\"${{KISYS3DMOD}}/Connectors_DSub\", classname=\"DSub\", classname_description=\"D-Sub connector\", webpage=\"\"):\n                        \n    w_slk=int((pins-1)/2)*rmx+pad[0]+(slk_pad_offset+2*lw_slk)\n    h_slk=pad[1]\n    l_slk=-w_slk/2\n    t_slk=-h_slk/2\n                        \n    text_size = w_slk*0.6\n    fab_text_size_max = 1.0\n    if text_size < fab_text_size_min:\n        text_size = fab_text_size_min\n    elif text_size > fab_text_size_max:\n        text_size = fab_text_size_max\n    text_size = round(text_size, 2)\n    text_size = [text_size,text_size]\n    text_t = text_size[0] * 0.15\n    \n    \n    description = \"{0}-pin {1}, solder-cups edge-mounted\".format(pins, classname_description)\n    tags = \"{0}-pin {1} edge mount solder cup\".format(pins, classname_description)\n    footprint_name=\"{0}-{1}\".format(classname,pins)\n    if isMale:\n        description = description+\", male\"\n        tags = tags+\" male\"\n        footprint_name=footprint_name+\"_Male\"\n    else:\n        description = description+\", female\"\n        tags = tags+\" female\"\n        footprint_name=footprint_name+\"_Female\"\n    \n    description = description+\", x-pin-pitch {0}mm\".format(rmx)\n    tags = tags+\" x-pin-pitch {0}mm\".format(rmx)\n    footprint_name=footprint_name+\"_EdgeMount\"\n    footprint_name=footprint_name+\"_Pitch{0:3.2f}mm\".format(rmx)\n\n    description = description+\", distance of mounting holes {0}mm\".format(mountingdistance)\n    tags = tags+\" mounting holes distance {0}mm\".format(mountingdistance)\n    #footprint_name=footprint_name+\"_MHDist{0:3.2f}mm\".format(mountingdistance)\n    \n    if len(webpage)>0:\n        description = description+\", see {0}\".format(webpage)\n    \n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n    \n    print(footprint_name)\n    \n    pinstop=int((pins + 1)/2)\n    pinsbot=int((pins - 1)/2)\n\n    y1=-pad[1]/2\n    x10=-(pinstop-1)/2*rmx\n    topoffset=0\n    botoffset=rmx/2\n        \n    \n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n    kicad_mod.setAttribute('smd')\n    \n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    \n    ypcb_edge=pad[1]/2+soldercup_pad_edge_offset;\n    \n    # set general values\n    kicad_mod.append(Text(type='reference', text='REF**', at=[x10-topoffset-pad[0]/2-text_size[0]*3, 0], layer='F.SilkS'))\n    kicad_mod.append(Text(type='user', text='%R', at=[0,ypcb_edge+smaller_backcan_height/2], layer='F.Fab', size=text_size ,thickness=text_t))\n    kicad_mod.append(Text(type='value', text=footprint_name, at=[0, ypcb_edge+smaller_backcan_height+backcan_height+shieldthickness+can_height+text_size[0]], layer='F.Fab'))\n    \n    \n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0 \n     \n    pad_type = Pad.TYPE_SMT\n    pad_shape1 = Pad.SHAPE_RECT \n    pad_layers_top = ['F.Cu', 'F.Mask', 'F.Paste']\n    pad_layers_bot = ['B.Cu', 'B.Mask', 'B.Paste']\n    slk_layers_top = 'F.SilkS'\n    slk_layers_bot = 'B.SilkS'\n    keepouts=[];\n\n    \n    \n    y1=0\n    if isMale:\n        x1=x10+topoffset\n    else:\n        x1=-x10-topoffset\n    x_pin1=0;\n    leftmost=0\n    rightmost=0\n    for p in range(1, pinstop+1): \n        kicad_mod.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=0, layers=pad_layers_top)) \n        keepouts=keepouts+addKeepoutRect(x1, y1, pad[0]+8*slk_offset, pad[1]+8*slk_offset)\n        kicad_mod.append(RectLine(start=[x1-soldercup_diameter/2, ypcb_edge-soldercup_length], end=[x1+soldercup_diameter/2, ypcb_edge], layer='F.Fab', width=lw_fab))\n        if p==1:\n            x_pin1=x1;\n        leftmost=min(leftmost, x1-pad[0]/2)\n        rightmost=max(rightmost, x1+pad[0]/2)\n        if isMale:\n            x1=x1+rmx\n        else:\n            x1=x1-rmx\n    \n\n    if isMale:\n        x1=x10+botoffset\n    else:\n        x1=-x10-botoffset\n    y1=0\n    for p in range(pinstop+1, pins+1): \n         \n        kicad_mod.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=0, layers=pad_layers_bot)) \n        keepouts=keepouts+addKeepoutRect(x1, y1, pad[0]+8*slk_offset, pad[1]+8*slk_offset)\n        kicad_mod.append(RectLine(start=[x1-soldercup_diameter/2, ypcb_edge-soldercup_length], end=[x1+soldercup_diameter/2, ypcb_edge], layer='B.Fab', width=lw_fab))\n        leftmost=min(leftmost, x1-pad[0]/2)\n        rightmost=max(rightmost, x1+pad[0]/2)\n        if isMale:\n            x1=x1+rmx\n        else:\n            x1=x1-rmx\n\n\n    \n    smaller_backcup_width=backcan_width-2*smaller_backcan_offset\n    #fabrication_layer\n    kicad_mod.append(RectLine(start=[-smaller_backcup_width/2, ypcb_edge], end=[smaller_backcup_width/2, ypcb_edge+smaller_backcan_height], layer='F.Fab', width=lw_fab))\n    kicad_mod.append(RectLine(start=[-backcan_width/2, ypcb_edge+smaller_backcan_height], end=[backcan_width/2, ypcb_edge+smaller_backcan_height+backcan_height], layer='F.Fab', width=lw_fab))\n    kicad_mod.append(RectLine(start=[-shield_width/2, ypcb_edge+smaller_backcan_height+backcan_height], end=[shield_width/2, ypcb_edge+smaller_backcan_height+backcan_height+shieldthickness], layer='F.Fab', width=lw_fab))\n    kicad_mod.append(RectLine(start=[-connwidth/2, ypcb_edge+smaller_backcan_height+backcan_height+shieldthickness], end=[connwidth/2, ypcb_edge+smaller_backcan_height+backcan_height+shieldthickness+can_height], layer='F.Fab', width=lw_fab))\n    \n    # create courtyard\n    kicad_mod.append(PolygoneLine(polygone=[[roundCrt(leftmost-crt_offset), roundCrt(-pad[1]/2-crt_offset)],\n                                            [roundCrt(rightmost + crt_offset), roundCrt(-pad[1]/2-crt_offset)],\n                                            [roundCrt(rightmost + crt_offset), roundCrt(ypcb_edge-crt_offset)],\n                                            [roundCrt(smaller_backcup_width/2 + crt_offset), roundCrt(ypcb_edge-crt_offset)],\n                                            [roundCrt(smaller_backcup_width/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height-crt_offset)],\n                                            [roundCrt(backcan_width/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height-crt_offset)],\n                                            [roundCrt(backcan_width/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height+backcan_height-crt_offset)],\n                                            [roundCrt(shield_width/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height+backcan_height-crt_offset)],\n                                            [roundCrt(shield_width/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height+backcan_height+shieldthickness+crt_offset)],\n                                            [roundCrt(connwidth/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height+backcan_height+shieldthickness+crt_offset)],\n                                            [roundCrt(connwidth/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height+backcan_height+shieldthickness+can_height+crt_offset)],\n                                            [-roundCrt(connwidth/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height+backcan_height+shieldthickness+can_height+crt_offset)],\n                                            [-roundCrt(connwidth/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height+backcan_height+shieldthickness+crt_offset)],\n                                            [-roundCrt(shield_width/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height+backcan_height+shieldthickness+crt_offset)],\n                                            [-roundCrt(shield_width/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height+backcan_height-crt_offset)],\n                                            [-roundCrt(backcan_width/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height+backcan_height-crt_offset)],\n                                            [-roundCrt(backcan_width/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height-crt_offset)],\n                                            [-roundCrt(smaller_backcup_width/2 + crt_offset), roundCrt(ypcb_edge+smaller_backcan_height-crt_offset)],\n                                            [-roundCrt(smaller_backcup_width/2 + crt_offset), roundCrt(ypcb_edge-crt_offset)],\n                                            [-roundCrt(rightmost + crt_offset), roundCrt(ypcb_edge-crt_offset)],\n                                            [-roundCrt(rightmost + crt_offset), roundCrt(-pad[1]/2-crt_offset)]\n                                            ],\n                              layer='F.CrtYd', width=lw_crt))\n    \n    #silkscreen + PDB-edge\n    kicad_mod.append(PolygoneLine(polygone=[[-x10+topoffset+pad[0]/2+slk_pad_offset, y1+pad[1]/2], \n                                            [-x10+topoffset+pad[0]/2+slk_pad_offset, y1-pad[1]/2-slk_pad_offset],\n                                            [x10-topoffset-pad[0]/2-slk_pad_offset, y1-pad[1]/2-slk_pad_offset],\n                                            [x10-topoffset-pad[0]/2-slk_pad_offset, y1+pad[1]/2]], layer=slk_layers_top, width=lw_slk))\n    if isMale:\n        kicad_mod.append(PolygoneLine(polygone=[[x_pin1-topoffset-pad[0]/2-(slk_pad_offset+2*lw_slk), y1], \n                                            [x_pin1-topoffset-pad[0]/2-(slk_pad_offset+2*lw_slk), y1-pad[1]/2-(slk_pad_offset+2*lw_slk)], \n                                            [x_pin1-topoffset+rmx, y1-pad[1]/2-(slk_pad_offset+2*lw_slk)]], layer=slk_layers_top, width=lw_slk))\n    else:\n        kicad_mod.append(PolygoneLine(polygone=[[x_pin1+topoffset+pad[0]/2+(slk_pad_offset+2*lw_slk), y1], \n                                            [x_pin1+topoffset+pad[0]/2+(slk_pad_offset+2*lw_slk), y1-pad[1]/2-(slk_pad_offset+2*lw_slk)], \n                                            [x_pin1+topoffset-rmx, y1-pad[1]/2-(slk_pad_offset+2*lw_slk)]], layer=slk_layers_top, width=lw_slk))\n    \n    kicad_mod.append(Line(start=[-shield_width/2, ypcb_edge], end=[shield_width/2, pad[1]/2+soldercup_pad_edge_offset], layer='Dwgs.User', width=lw_crt))\n    kicad_mod.append(Text(type='user', text='PCB edge', at=[-shield_width/2+5*text_size[0], ypcb_edge-text_size[1]*2/3], layer='Dwgs.User', size=[text_size[0]/2,text_size[1]/2] ,thickness=text_t/2))\n    \n    \n    # add model\n    kicad_mod.append(\n        Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=[0,0,0], scale=[1,1,1], rotate=[0,0,0]))\n    \n   \n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(footprint_name + '.kicad_mod')\n    \n    \n\n\n\ndef makeDSubAngled(pins, isMale, HighDensity, rmx, rmy, pindrill, pad, pin_pcb_distance, mountingdrill, mountingpad, mountingdistance, mounting_pcb_distance, shield_width, shield_thickness, can_width, can_height, backbox_width, backbox_height, nut_diameter, nut_length, backcan_width=0, backcan_height=0,\n                        tags_additional=[], lib_name=\"${{KISYS3DMOD}}/Connectors_DSub\", classname=\"DSub\", classname_description=\"D-Sub connector\", webpage=\"\", HighDensityOffsetMidLeft=0):\n                        \n    hasMountingHoles=mountingdrill>0 and mountingdistance>0\n    hasNoBackBox=backcan_width*backcan_height>0 and backbox_width*backbox_height==0\n\n    text_size = 1\n    text_size = round(text_size, 2)\n    text_size = [text_size,text_size]\n    text_t = text_size[0] * 0.15\n    \n    \n    description = \"{0}-pin {1}, horizontal/angled (90 deg), THT-mount\".format(pins, classname_description)\n    tags = \"{0}-pin {1} horizontal angled 90deg THT\".format(pins, classname_description)\n    footprint_name=\"{0}-{1}\".format(classname,pins)\n    if HighDensity:\n        footprint_name=footprint_name+\"-HD\"\n    if isMale:\n        description = description+\", male\"\n        tags = tags+\" male\"\n        footprint_name=footprint_name+\"_Male\"\n    else:\n        description = description+\", female\"\n        tags = tags+\" female\"\n        footprint_name=footprint_name+\"_Female\"\n\n    rmy_default=2.84\n    description = description+\", pitch {0}x{1}mm, pin-PCB-offset {2}mm\".format(rmx,rmy,pin_pcb_distance)\n    tags = tags+\" pitch {0}x{1}mm pin-PCB-offset {2}mm\".format(rmx,rmy,pin_pcb_distance)\n\n    footprint_name=footprint_name+\"_Horizontal\"\n    footprint_name=footprint_name+\"_Pitch{0:3.2f}x{1:3.2f}mm\".format(rmx,rmy)\n    footprint_name=footprint_name+\"_EdgePinOffset{0:3.2f}mm\".format(pin_pcb_distance)\n    \n    if hasMountingHoles:\n        description = description+\", distance of mounting holes {0}mm, distance of mounting holes to PCB edge {1}mm\".format(mountingdistance, mounting_pcb_distance)\n        tags = tags+\" mounting-holes-distance {0}mm mounting-hole-offset {0}mm\".format(mountingdistance, mounting_pcb_distance)\n        if not hasNoBackBox:\n            footprint_name=footprint_name+\"_Housed\"\n        footprint_name=footprint_name+\"_MountingHolesOffset{0:3.2f}mm\".format(mounting_pcb_distance)\n    else:\n        if not hasNoBackBox:\n            footprint_name=footprint_name+\"_Housed\"\n\n\n    if len(webpage)>0:\n        description = description+\", see {0}\".format(webpage)\n    \n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n    \n    print(footprint_name)\n    \n    rows=2\n    pinstop=int((pins + 1)/2)\n    pinsmid=0\n    pinsbot=int((pins - 1)/2)\n    drmy=rmy/2\n    if HighDensity:\n        rows=3\n        pinstop=int((pins+1)/3)\n        pinsmid=pinstop\n        pinsbot=pins-pinstop-pinsbot\n        drmy=rmy\n\n    y1=-drmy\n    x10=-(pinstop-1)/2*rmx\n    topoffset=0\n    botoffset=rmx/2\n    if HighDensity:\n        x10=-mountingdistance/2+HighDensityOffsetMidLeft\n        topoffset=rmx/2\n        botoffset=rmx/2\n    \n    ypcb_edge=drmy+pin_pcb_distance\n    \n    back_height=backbox_height\n    if hasNoBackBox:\n        back_height=pin_pcb_distance+rmy*(rows-1)+pad/2\n\n    w_crt = max([backbox_width, shield_width])+2*crt_offset\n    h_crt = max([backbox_height, mounting_pcb_distance+mountingpad/2])+max([nut_length, can_height])+shield_thickness+2*crt_offset\n    if hasNoBackBox:\n        h_crt = back_height+max([nut_length, can_height])+shield_thickness+2*crt_offset\n    l_crt = -w_crt/2\n    t_crt = -max([backbox_height-pin_pcb_distance-drmy, drmy+pad/2])-crt_offset\n    \n    \n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n    \n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    if not isMale:\n        offset=[x10+topoffset,drmy]\n    else:\n        offset=[-(topoffset+x10),drmy]\n    kicad_modg = Translation(offset[0], offset[1])\n    kicad_mod.append(kicad_modg)\n    \n    # set general values\n    kicad_modg.append(Text(type='reference', text='REF**', at=[0, ypcb_edge-back_height-text_size[0]], layer='F.SilkS'))\n    kicad_modg.append(Text(type='user', text='%R', at=[0,ypcb_edge+shield_thickness+can_height/2], layer='F.Fab', size=text_size ,thickness=text_t))\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[0, ypcb_edge+shield_thickness+can_height+text_size[0]*1.5], layer='F.Fab'))\n    \n    \n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0 \n     \n    pad_type = Pad.TYPE_THT \n    hole_type = Pad.TYPE_NPTH \n    pad_shape1 = Pad.SHAPE_RECT \n    pad_shapeother = Pad.SHAPE_CIRCLE\n    pad_layers = Pad.LAYERS_THT\n    keepouts=[];\n\n    \n    \n    y1=-drmy\n    if isMale:\n        x1=x10+topoffset\n    else:\n        x1=-x10-topoffset\n    x1pos=0\n    leftmost=0\n    rightmost=0\n    for p in range(1, pinstop+1): \n         \n        if p == 1: \n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=pindrill, layers=pad_layers)) \n            keepouts=keepouts+addKeepoutRect(x1, y1, pad+8*slk_offset, pad+8*slk_offset)\n            x1pos=x1\n        else:\n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=pindrill, layers=pad_layers))\n            keepouts=keepouts+addKeepoutRound(x1, y1, pad+(slk_pad_offset+2*lw_slk), pad+(slk_pad_offset+2*lw_slk))\n        if hasNoBackBox:\n            kicad_modg.append(Line(start=[x1-lw_fab, y1], end=[x1-lw_fab, ypcb_edge-backcan_height], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[x1, y1], end=[x1, ypcb_edge-backcan_height], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[x1+lw_fab, y1], end=[x1+lw_fab, ypcb_edge-backcan_height], layer='F.Fab', width=lw_fab))\n        leftmost=min(leftmost,x1)\n        rightmost=max(rightmost,x1)\n        if isMale:\n            x1=x1+rmx\n        else:\n            x1=x1-rmx\n    if HighDensity:\n        if isMale:\n            x1=x10;\n        else:\n            x1=-x10;\n        y1=0\n        for p in range(pinstop+1, pinstop+pinsmid+1): \n             \n            if p == 1: \n                kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=pindrill, layers=pad_layers)) \n                keepouts=keepouts+addKeepoutRect(x1, y1, pad+8*slk_offset, pad+8*slk_offset)\n            else:\n                kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=pindrill, layers=pad_layers))\n                keepouts=keepouts+addKeepoutRound(x1, y1, pad+(slk_pad_offset+2*lw_slk), pad+(slk_pad_offset+2*lw_slk))\n            if hasNoBackBox:\n                kicad_modg.append(Line(start=[x1-lw_fab, y1], end=[x1-lw_fab, ypcb_edge-backcan_height], layer='F.Fab', width=lw_fab))\n                kicad_modg.append(Line(start=[x1, y1], end=[x1, ypcb_edge-backcan_height], layer='F.Fab', width=lw_fab))\n                kicad_modg.append(Line(start=[x1+lw_fab, y1], end=[x1+lw_fab, ypcb_edge-backcan_height], layer='F.Fab', width=lw_fab))\n            \n            leftmost=min(leftmost,x1)\n            rightmost=max(rightmost,x1)\n            if isMale:\n                x1=x1+rmx\n            else:\n                x1=x1-rmx\n\n    if isMale:\n        x1=x10+botoffset\n    else:\n        x1=-x10-botoffset\n    y1=drmy\n    for p in range(pinstop+pinsmid+1, pins+1): \n         \n        if p == 1: \n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=pindrill, layers=pad_layers)) \n            keepouts=keepouts+addKeepoutRect(x1, y1, pad+8*slk_offset, pad+8*slk_offset)\n        else:\n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=pindrill, layers=pad_layers))\n            keepouts=keepouts+addKeepoutRound(x1, y1, pad+(slk_pad_offset+2*lw_slk), pad+(slk_pad_offset+2*lw_slk))\n        if hasNoBackBox:\n            kicad_modg.append(Line(start=[x1-lw_fab, y1], end=[x1-lw_fab, ypcb_edge-backcan_height], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[x1, y1], end=[x1, ypcb_edge-backcan_height], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[x1+lw_fab, y1], end=[x1+lw_fab, ypcb_edge-backcan_height], layer='F.Fab', width=lw_fab))\n        \n        leftmost=min(leftmost,x1)\n        rightmost=max(rightmost,x1)\n        if isMale:\n            x1=x1+rmx\n        else:\n            x1=x1-rmx\n    \n    \n    # mounting holes\n    if hasMountingHoles and mountingpad>0:\n        kicad_modg.append(Pad(number=0, type=pad_type, shape=pad_shapeother, at=[-mountingdistance/2, ypcb_edge-mounting_pcb_distance], size=[mountingpad,mountingpad], drill=mountingdrill, layers=pad_layers))\n        keepouts=keepouts+addKeepoutRound(-mountingdistance/2, ypcb_edge-mounting_pcb_distance, mountingpad+(slk_pad_offset+2*lw_slk), mountingpad+(slk_pad_offset+2*lw_slk))\n        kicad_modg.append(Pad(number=0, type=pad_type, shape=pad_shapeother, at=[mountingdistance/2, ypcb_edge-mounting_pcb_distance], size=[mountingpad,mountingpad], drill=mountingdrill, layers=pad_layers))\n        keepouts=keepouts+addKeepoutRound(mountingdistance/2, ypcb_edge-mounting_pcb_distance, mountingpad+(slk_pad_offset+2*lw_slk), mountingpad+(slk_pad_offset+2*lw_slk))\n    if hasMountingHoles and mountingpad<=0 and backbox_width*backbox_height==0:\n        kicad_modg.append(Pad(number=0, type=hole_type, shape=pad_shapeother, at=[-mountingdistance/2, ypcb_edge-mounting_pcb_distance], size=[0,0], drill=mountingdrill, layers=pad_layers))\n        keepouts=keepouts+addKeepoutRound(-mountingdistance/2, ypcb_edge-mounting_pcb_distance, mountingpad+(slk_pad_offset+2*lw_slk), mountingpad+(slk_pad_offset+2*lw_slk))\n        kicad_modg.append(Pad(number=0, type=hole_type, shape=pad_shapeother, at=[mountingdistance/2, ypcb_edge-mounting_pcb_distance], size=[0,0], drill=mountingdrill, layers=pad_layers))\n        keepouts=keepouts+addKeepoutRound(mountingdistance/2, ypcb_edge-mounting_pcb_distance, mountingpad+(slk_pad_offset+2*lw_slk), mountingpad+(slk_pad_offset+2*lw_slk))\n\n    # PCB edge marker\n    #kicad_modg.append(Line(start=[-shield_width/2, ypcb_edge], end=[shield_width/2, ypcb_edge], layer='Dwgs.User', width=lw_crt))\n    #kicad_modg.append(Text(type='user', text='PCB edge', at=[-shield_width/2+5*text_size[0], ypcb_edge-text_size[1]*2/3], layer='Dwgs.User', size=[text_size[0]/2,text_size[1]/2] ,thickness=text_t/2))\n        \n    # outline\n    if not hasNoBackBox:\n        kicad_modg.append(RectLine(start=[-backbox_width/2, ypcb_edge-backbox_height], end=[backbox_width/2, ypcb_edge], layer='F.Fab', width=lw_fab))\n    else:\n        kicad_modg.append(RectLine(start=[-backcan_width/2, ypcb_edge-backcan_height], end=[backcan_width/2, ypcb_edge], layer='F.Fab', width=lw_fab))\n    kicad_modg.append(RectLine(start=[-shield_width/2, ypcb_edge], end=[shield_width/2, ypcb_edge+shield_thickness], layer='F.Fab', width=lw_fab))\n    kicad_modg.append(RectLine(start=[-can_width/2, ypcb_edge+shield_thickness], end=[can_width/2, ypcb_edge+shield_thickness+can_height], layer='F.Fab', width=lw_fab))\n    if nut_length>0 and nut_diameter>0:\n        kicad_modg.append(RectLine(start=[-mountingdistance/2-nut_diameter/2, ypcb_edge+shield_thickness], end=[-mountingdistance/2+nut_diameter/2, ypcb_edge+shield_thickness+nut_length], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(RectLine(start=[mountingdistance/2-nut_diameter/2, ypcb_edge+shield_thickness], end=[mountingdistance/2+nut_diameter/2, ypcb_edge+shield_thickness+nut_length], layer='F.Fab', width=lw_fab))\n    if hasMountingHoles:\n        kicad_modg.append(Line(start=[-mountingdistance/2-mountingdrill/2, ypcb_edge], end=[-mountingdistance/2-mountingdrill/2, ypcb_edge-mounting_pcb_distance], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[-mountingdistance/2+mountingdrill/2, ypcb_edge], end=[-mountingdistance/2+mountingdrill/2, ypcb_edge-mounting_pcb_distance], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Arc(start=[-mountingdistance/2-mountingdrill/2, ypcb_edge-mounting_pcb_distance], center=[-mountingdistance/2, ypcb_edge-mounting_pcb_distance], angle=180, layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[mountingdistance/2-mountingdrill/2, ypcb_edge], end=[mountingdistance/2-mountingdrill/2, ypcb_edge-mounting_pcb_distance], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[mountingdistance/2+mountingdrill/2, ypcb_edge], end=[mountingdistance/2+mountingdrill/2, ypcb_edge-mounting_pcb_distance], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Arc(start=[mountingdistance/2-mountingdrill/2, ypcb_edge-mounting_pcb_distance], center=[mountingdistance/2, ypcb_edge-mounting_pcb_distance], angle=180, layer='F.Fab', width=lw_fab))\n\n    # silkscreen\n    if not hasNoBackBox:\n        kicad_modg.append(PolygoneLine(polygone=[\n                                                 [-backbox_width/2-slk_offset, ypcb_edge-lw_slk/2], \n                                                 [-backbox_width/2-slk_offset, ypcb_edge-backbox_height-slk_offset], \n                                                 [backbox_width/2+slk_offset, ypcb_edge-backbox_height-slk_offset], \n                                                 [backbox_width/2+slk_offset, ypcb_edge-lw_slk/2], \n                                                ], layer='F.SilkS', width=lw_slk))\n        allEqualSidedDownTriangle(kicad_modg, xcenter=[x1pos, ypcb_edge-backbox_height-slk_offset-text_size[0]*0.75], side_length=text_size[0]/2, layer='F.SilkS', width=lw_slk)\n    else:   \n        kicad_modg.append(PolygoneLine(polygone=[\n                                                 [-backcan_width/2-slk_offset, ypcb_edge-lw_slk/2], \n                                                 [-backcan_width/2-slk_offset, ypcb_edge-backcan_height-slk_offset], \n                                                 [leftmost-pad/2-slk_pad_offset, ypcb_edge-backcan_height-slk_offset], \n                                                 [leftmost-pad/2-slk_pad_offset, ypcb_edge-back_height-slk_pad_offset], \n                                                 [rightmost+pad/2+slk_pad_offset, ypcb_edge-back_height-slk_pad_offset], \n                                                 [rightmost+pad/2+slk_pad_offset, ypcb_edge-backcan_height-slk_offset], \n                                                 [backcan_width/2+slk_offset, ypcb_edge-backcan_height-slk_offset], \n                                                 [backcan_width/2+slk_offset, ypcb_edge-lw_slk/2], \n                                                ], layer='F.SilkS', width=lw_slk))\n        allEqualSidedDownTriangle(kicad_modg, xcenter=[x1pos, ypcb_edge-back_height-slk_offset-text_size[0]*0.75], side_length=text_size[0]/2, layer='F.SilkS', width=lw_slk)\n    \n    # create courtyard\n    if not hasNoBackBox:\n        kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\n                                  end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\n                                  layer='F.CrtYd', width=lw_crt))\n    else:\n        kicad_mod.append(PolygoneLine(polygone=[\n                                                 [roundCrt(offset[0]-can_width/2-crt_offset), roundCrt(offset[1]+ypcb_edge+shield_thickness+can_height+crt_offset)], \n                                                 [roundCrt(offset[0]-can_width/2-crt_offset), roundCrt(offset[1]+ypcb_edge+shield_thickness+crt_offset)], \n                                                 [roundCrt(offset[0]-shield_width/2-crt_offset), roundCrt(offset[1]+ypcb_edge+shield_thickness+crt_offset)], \n                                                 [roundCrt(offset[0]-shield_width/2-crt_offset), roundCrt(offset[1]+ypcb_edge-crt_offset)], \n                                                 [roundCrt(offset[0]-backcan_width/2-crt_offset), roundCrt(offset[1]+ypcb_edge-crt_offset)], \n                                                 [roundCrt(offset[0]-backcan_width/2-crt_offset), roundCrt(offset[1]+ypcb_edge-backcan_height-crt_offset)], \n                                                 [roundCrt(offset[0]+leftmost-pad/2-crt_offset), roundCrt(offset[1]+ypcb_edge-backcan_height-crt_offset)], \n                                                 [roundCrt(offset[0]+leftmost-pad/2-crt_offset), roundCrt(offset[1]+ypcb_edge-back_height-crt_offset)], \n                                                 [roundCrt(offset[0]+rightmost+pad/2+crt_offset), roundCrt(offset[1]+ypcb_edge-back_height-crt_offset)], \n                                                 [roundCrt(offset[0]+rightmost+pad/2+crt_offset), roundCrt(offset[1]+ypcb_edge-backcan_height-crt_offset)], \n                                                 [roundCrt(offset[0]+backcan_width/2+crt_offset), roundCrt(offset[1]+ypcb_edge-backcan_height-crt_offset)], \n                                                 [roundCrt(offset[0]+backcan_width/2+crt_offset), roundCrt(offset[1]+ypcb_edge-crt_offset)], \n                                                 [roundCrt(offset[0]+shield_width/2+crt_offset), roundCrt(offset[1]+ypcb_edge-crt_offset)], \n                                                 [roundCrt(offset[0]+shield_width/2+crt_offset), roundCrt(offset[1]+ypcb_edge+shield_thickness+crt_offset)], \n                                                 [roundCrt(offset[0]+can_width/2+crt_offset), roundCrt(offset[1]+ypcb_edge+shield_thickness+crt_offset)], \n                                                 [roundCrt(offset[0]+can_width/2+crt_offset), roundCrt(offset[1]+ypcb_edge+shield_thickness+can_height+crt_offset)], \n                                                 [roundCrt(offset[0]-can_width/2-crt_offset), roundCrt(offset[1]+ypcb_edge+shield_thickness+can_height+crt_offset)], \n                                                ], layer='F.CrtYd', width=lw_crt))\n    \n    \n    # add model\n    kicad_mod.append(\n        Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=[0,0,0], scale=[1,1,1], rotate=[0,0,0]))\n    \n   \n    # write file\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(footprint_name + '.kicad_mod')\n    \n    \n    "
  },
  {
    "path": "scripts/tools/footprint_scripts_pin_headers.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom drawing_tools import *  # NOQA\nfrom math import sqrt\n\ncrt_offset = 0.5 # different for connectors\ntxt_offset = 1\nslk_offset = 0.11             \n\ndef makePinHeadStraight(rows, cols, rm, coldist, package_width, overlen_top, overlen_bottom, ddrill, pad,\n                        tags_additional=[], lib_name=\"Pin_Headers\", classname=\"Pin_Header\", classname_description=\"pin header\", offset3d=[0, 0, 0], scale3d=[1, 1, 1],\n                        rotate3d=[0, 0, 0], model3d_path_prefix=\"${KISYS3DMOD}\", isSocket=False):\n    h_fab = (rows - 1) * rm + overlen_top + overlen_bottom\n    w_fab = package_width\n    l_fab = (coldist * (cols - 1) - w_fab) / 2\n    t_fab = -overlen_top\n    \n    h_slk = h_fab + 2 * slk_offset\n    w_slk = max(w_fab + 2 * slk_offset, coldist * (cols - 1) - pad[0] - 4 * slk_offset)\n    l_slk = (coldist * (cols - 1) - w_slk) / 2\n    t_slk = -overlen_top - slk_offset\n    \n    w_crt = max(package_width, coldist * (cols - 1) + pad[0]) + 2 * crt_offset\n    h_crt = max(h_fab, (rows - 1) * rm + pad[1]) + 2 * crt_offset\n    l_crt = coldist * (cols - 1) / 2 - w_crt / 2\n    t_crt = (rows - 1) * rm / 2 - h_crt / 2\n    \n    text_size = w_fab*0.6\n    fab_text_size_max = 1.0\n    if text_size < fab_text_size_min:\n        text_size = fab_text_size_min\n    elif text_size > fab_text_size_max:\n        text_size = fab_text_size_max\n    text_size = round(text_size, 2)\n    text_size = [text_size,text_size]\n    text_t = text_size[0] * 0.15\n    \n    # if rm == 2.54:\n    #    footprint_name = \"Pin_Header_Straight_{0}x{1:02}\".format(cols, rows)\n    # else:\n    footprint_name = \"{3}_Straight_{0}x{1:02}_Pitch{2:03.2f}mm\".format(cols, rows, rm,classname)\n    \n    description = \"Through hole straight {3}, {0}x{1:02}, {2:03.2f}mm pitch\".format(cols, rows, rm,classname_description)\n    tags = \"Through hole {3} THT {0}x{1:02} {2:03.2f}mm\".format(cols, rows, rm,classname_description)\n    if (cols == 1):\n        description = description + \", single row\"\n        tags = tags + \" single row\"\n    elif (cols == 2):\n        description = description + \", double rows\"\n        tags = tags + \" double row\"\n    elif (cols == 3):\n        description = description + \", triple rows\"\n        tags = tags + \" triple row\"\n    elif (cols == 4):\n        description = description + \", quadruple rows\"\n        tags = tags + \" quadruple row\"\n    \n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n    \n    print(footprint_name)\n    \n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n    \n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    offset=[0,0]\n    if isSocket and cols>1:\n        offset = [-coldist, 0]\n    kicad_modg = Translation(offset[0], offset[1])\n    kicad_mod.append(kicad_modg)\n    \n    # set general values\n    kicad_modg.append(\n        Text(type='reference', text='REF**', at=[coldist * (cols - 1) / 2, t_slk - txt_offset], layer='F.SilkS'))\n    kicad_modg.append(\n        Text(type='user', text='%R', at=[rm/2*(cols-1), t_crt + offset[1] + (h_crt/2)], rotation=90, layer='F.Fab', size=text_size ,thickness=text_t))\n    kicad_modg.append(\n        Text(type='value', text=footprint_name, at=[coldist * (cols - 1) / 2, t_slk + h_slk + txt_offset], layer='F.Fab'))\n    \n    # create FAB-layer\n    chamfer = w_fab/4\n    kicad_modg.append(Line(start=[l_fab + chamfer, t_fab], end=[l_fab + w_fab, t_fab], layer='F.Fab', width=lw_fab))\n    kicad_modg.append(Line(start=[l_fab + w_fab, t_fab], end=[l_fab + w_fab, t_fab+h_fab], layer='F.Fab', width=lw_fab))\n    kicad_modg.append(Line(start=[l_fab + w_fab, t_fab+h_fab], end=[l_fab, t_fab+h_fab], layer='F.Fab', width=lw_fab))\n    kicad_modg.append(Line(start=[l_fab, t_fab+h_fab], end=[l_fab, t_fab+chamfer], layer='F.Fab', width=lw_fab))\n    kicad_modg.append(Line(start=[l_fab, t_fab+chamfer], end=[l_fab + chamfer, t_fab], layer='F.Fab', width=lw_fab))\n\n    # create SILKSCREEN-layer + pin1 marker\n    \n    # Silkscreen body\n    body_min_x_square = pad[0]/2+min_pad_distance+slk_offset\n    body_min_y_square = pad[1]/2+min_pad_distance+slk_offset\n    #drawin bottom line\n        \n    if (rows-1)*rm + body_min_y_square < t_slk + h_slk:\n        kicad_modg.append(Line(start=[l_slk, t_slk + h_slk], end=[l_slk + w_slk, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\n    else:\n        if rows == 1:\n            kicad_modg.append(Line(start=[l_slk, body_min_y_square], end=[l_slk + w_slk, body_min_y_square], layer='F.SilkS', width=lw_slk))\n        else:\n            body_min_x_round = sqrt(((pad[0]/2+min_pad_distance+slk_offset) * (pad[0]/2+min_pad_distance+slk_offset) - (overlen_bottom+slk_offset) * (overlen_bottom+slk_offset)))\n            kicad_modg.append(Line(start=[l_slk, t_slk + h_slk], end=[-body_min_x_round, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\n            kicad_modg.append(Line(start=[(cols-1)*coldist+body_min_x_round, t_slk + h_slk], end=[l_slk + w_slk, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\n            for x in range(0, (cols-1)):\n                kicad_modg.append(Line(start=[x*coldist+body_min_x_round, t_slk + h_slk], end=[(x+1)*coldist-body_min_x_round, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\n    #drawin sidelines\n    #calculate top Y positon \n    if rm < body_min_y_square*2:\n        shoulder_y_pos = body_min_y_square\n        shoulder_y_lines = 2\n    else:\n        shoulder_y_pos = rm/2\n        shoulder_y_lines = 1\n    if coldist < body_min_x_square*2:\n        top_x_pos = body_min_x_square\n        top_x_lines = 2\n    else:\n        top_x_pos = coldist/2\n        top_x_lines = 1\n    if l_slk + w_slk  > body_min_x_square+(cols-1)*coldist:\n        kicad_modg.append(Line(start=[l_slk, shoulder_y_pos], end=[l_slk, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\n        if cols == 1:\n            kicad_modg.append(Line(start=[l_slk + w_slk, shoulder_y_pos], end=[l_slk + w_slk, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\n        else:\n            kicad_modg.append(Line(start=[l_slk + w_slk, t_slk], end=[l_slk + w_slk, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\n    elif rows != 1:\n        body_min_y_round = sqrt(((pad[0]/2+min_pad_distance+slk_offset) * (pad[0]/2+min_pad_distance+slk_offset) - l_slk * l_slk))\n        kicad_modg.append(Line(start=[l_slk, shoulder_y_pos], end=[l_slk, rm-body_min_y_round], layer='F.SilkS', width=lw_slk))\n        kicad_modg.append(Line(start=[l_slk, (rows-1)*rm+body_min_y_round], end=[l_slk, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\n        if cols == 1:\n            kicad_modg.append(Line(start=[l_slk + w_slk, shoulder_y_pos], end=[l_slk + w_slk, rm-body_min_y_round], layer='F.SilkS', width=lw_slk))\n        else:\n            kicad_modg.append(Line(start=[l_slk + w_slk, body_min_y_square], end=[l_slk + w_slk, rm-body_min_y_round], layer='F.SilkS', width=lw_slk))\n        kicad_modg.append(Line(start=[l_slk + w_slk, (rows-1)*rm+body_min_y_round], end=[l_slk + w_slk, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\n        for x in range(1, (rows-1)):\n            kicad_modg.append(Line(start=[l_slk, x*rm+body_min_y_round], end=[l_slk, (x+1)*rm-body_min_y_round], layer='F.SilkS', width=lw_slk))\n            kicad_modg.append(Line(start=[l_slk + w_slk, x*rm+body_min_y_round], end=[l_slk + w_slk, (x+1)*rm-body_min_y_round], layer='F.SilkS', width=lw_slk))\n    #drawin top\n\n    if cols == 1:\n        if shoulder_y_lines == 1:\n            kicad_modg.append(Line(start=[l_slk, shoulder_y_pos], end=[l_slk + w_slk, shoulder_y_pos], layer='F.SilkS', width=lw_slk))\n        elif shoulder_y_lines == 2:\n            top_x_round = sqrt(((pad[0]/2+min_pad_distance+slk_offset) * (pad[0]/2+min_pad_distance+slk_offset) - (shoulder_y_pos-rm) * (shoulder_y_pos-rm)))\n            kicad_modg.append(Line(start=[l_slk, shoulder_y_pos], end=[l_slk + w_slk/2-top_x_round, shoulder_y_pos], layer='F.SilkS', width=lw_slk))\n            kicad_modg.append(Line(start=[l_slk + w_slk/2 + top_x_round, shoulder_y_pos], end=[l_slk + w_slk, shoulder_y_pos], layer='F.SilkS', width=lw_slk))\n    else:\n        if shoulder_y_lines == 1:\n            kicad_modg.append(Line(start=[l_slk, shoulder_y_pos], end=[top_x_pos, shoulder_y_pos], layer='F.SilkS', width=lw_slk))\n        elif shoulder_y_lines == 2:\n            top_x_round = sqrt(((pad[0]/2+min_pad_distance+slk_offset) * (pad[0]/2+min_pad_distance+slk_offset) - (shoulder_y_pos-rm) * (shoulder_y_pos-rm)))\n            if top_x_pos > coldist-top_x_round:\n                top_x_end = coldist-top_x_round\n            else:\n                top_x_end = top_x_pos\n            kicad_modg.append(Line(start=[l_slk, shoulder_y_pos], end=[-top_x_round, shoulder_y_pos], layer='F.SilkS', width=lw_slk))\n            if top_x_round*2 + lw_slk*2 < pad[0]:\n                kicad_modg.append(Line(start=[top_x_round, shoulder_y_pos], end=[top_x_end, shoulder_y_pos], layer='F.SilkS', width=lw_slk))\n        if top_x_lines == 1:\n            kicad_modg.append(Line(start=[top_x_pos, shoulder_y_pos], end=[top_x_pos, t_slk], layer='F.SilkS', width=lw_slk))\n        elif top_x_lines == 2:\n            shoulder_y_round = sqrt(((pad[0]/2+min_pad_distance+slk_offset) * (pad[0]/2+min_pad_distance+slk_offset) - (coldist-top_x_pos) * (coldist-top_x_pos)))\n            if shoulder_y_pos > rm-shoulder_y_round:\n                shoulder_y_pos = rm-shoulder_y_round\n            if shoulder_y_round*2 + lw_slk*2 < pad[1]:    \n                kicad_modg.append(Line(start=[top_x_pos, shoulder_y_pos], end=[top_x_pos, shoulder_y_round], layer='F.SilkS', width=lw_slk))\n                kicad_modg.append(Line(start=[top_x_pos, -shoulder_y_round], end=[top_x_pos, t_slk], layer='F.SilkS', width=lw_slk))\n        #highest horizontal line\n        if abs(t_slk) > body_min_y_square:\n            kicad_modg.append(Line(start=[top_x_pos, t_slk], end=[l_slk + w_slk, t_slk], layer='F.SilkS', width=lw_slk))\n        else:\n            top_x_round = sqrt(((pad[0]/2+min_pad_distance+slk_offset) * (pad[0]/2+min_pad_distance+slk_offset) - (abs(t_slk)) * (abs(t_slk))))\n            if top_x_pos > coldist-top_x_round + 2*lw_slk:\n                kicad_modg.append(Line(start=[top_x_pos, t_slk], end=[coldist-top_x_round, t_slk], layer='F.SilkS', width=lw_slk))\n            kicad_modg.append(Line(start=[coldist+top_x_round, t_slk], end=[l_slk + w_slk, t_slk], layer='F.SilkS', width=lw_slk))\n\n\n    '''\n    if cols == 1:\n        kicad_modg.append(\n            RectLine(start=[l_slk, 0.5 * rm], end=[l_slk + w_slk, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\n    else:\n        if isSocket and cols>1:\n            kicad_modg.append(PolygoneLine(\n                polygone=[[l_slk+w_slk, 0.5 * rm], [l_slk+w_slk, t_slk + h_slk], [l_slk , t_slk + h_slk], [l_slk , t_slk],\n                          [l_slk+w_slk/2, t_slk], [l_slk+w_slk/2, 0.5 * rm], [l_slk+w_slk, 0.5 * rm]], layer='F.SilkS', width=lw_slk))\n        else:\n            kicad_modg.append(PolygoneLine(\n                polygone=[[l_slk, 0.5 * rm], [l_slk, t_slk + h_slk], [l_slk + w_slk, t_slk + h_slk], [l_slk + w_slk, t_slk],\n                          [0.5 * rm, t_slk], [0.5 * rm, 0.5 * rm], [l_slk, 0.5 * rm]], layer='F.SilkS', width=lw_slk))\n    '''\n    #pin 1 marker\n    pin1_min = -(pad[0]/2+slk_offset+min_pad_distance)\n    if pin1_min < l_slk:\n        pin1_x = pin1_min\n    else:\n        pin1_x = l_slk\n    if pin1_min < t_slk:\n        pin1_y = pin1_min\n    else:\n        pin1_y = t_slk\n    if isSocket and cols>1:\n        kicad_modg.append(PolygoneLine(polygone=[[pin1_x+w_slk, 0], [pin1_x+w_slk, pin1_y], [pin1_x+w_slk-rm/2, pin1_y]], layer='F.SilkS', width=lw_slk))\n    else:\n        kicad_modg.append(PolygoneLine(polygone=[[pin1_x, 0], [pin1_x, pin1_y], [0, pin1_y]], layer='F.SilkS', width=lw_slk))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\n                              end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\n                              layer='F.CrtYd', width=lw_crt))\n    \n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0 \n     \n    pad_type = Pad.TYPE_THT \n    pad_shape1 = Pad.SHAPE_RECT \n    pad_shapeother = Pad.SHAPE_OVAL \n    pad_layers = Pad.LAYERS_THT\n     \n    p = 1 \n     \n    for r in range(1, rows + 1): \n         \n        if isSocket and cols>1: \n            x1=coldist \n        else: \n            x1 = 0 \n        for c in range(1, cols + 1): \n            if p == 1: \n                kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=ddrill, \n                                      layers=pad_layers)) \n            else:\n                kicad_modg.append(\n                    Pad(number=p, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=ddrill,\n                        layers=pad_layers))\n            \n            p = p + 1\n            if isSocket and cols>1:\n                x1 = x1 - coldist\n            else:\n                x1 = x1 + coldist\n        \n        y1 = y1 + rm\n    \n    # add model\n    kicad_modg.append(\n        Model(filename=model3d_path_prefix + \"/\" + lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=offset3d, scale=scale3d, rotate=rotate3d))\n    \n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n    \n    # write file\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name))\n\n\ndef makeIdcHeader(rows, cols, rm, coldist, body_width, overlen_top, overlen_bottom, body_offset, ddrill, pad,\n                        mating_overlen, wall_thickness, notch_width,\n                        orientation, latching,\n                        latch_len=0, latch_width=0,\n                        mh_ddrill=0, mh_pad=[0,0], mh_overlen=0, mh_offset=0, mh_number='MP',\n                        tags_additional=[], extra_description=False, lib_name=\"Connector_IDC\", classname=\"IDC-Header\", classname_description=\"IDC box header\", offset3d=[0, 0, 0], scale3d=[1, 1, 1],\n                        rotate3d=[0, 0, 0], model3d_path_prefix=\"${KISYS3DMOD}\"):\n    pin_size = 0.64 # square pin side length; this appears to be the same for all connectors so use a fixed internal value\n    \n    mh_present = True if mh_ddrill > 0 and mh_pad[0] > 0 and mh_pad[1] > 0 and mh_overlen > 0 else False\n    mh_y = [-mh_overlen, (rows - 1) * rm + mh_overlen]\n    \n    h_fab = (rows - 1) * rm + overlen_top + overlen_bottom\n    w_fab = body_width\n    l_fab = (coldist * (cols - 1) - w_fab) / 2 if body_offset == 0 else body_offset\n    t_fab = -overlen_top\n    \n    h_slk = h_fab + 2 * slk_offset\n    w_slk = max(w_fab + 2 * slk_offset, coldist * (cols - 1) - pad[0] - 4 * slk_offset)\n    l_slk = (coldist * (cols - 1) - w_slk) / 2 if body_offset == 0 else body_offset\n    t_slk = -overlen_top - slk_offset\n    \n    # these calculations are so tight that new body styles will probably break them\n    h_crt = max(max(h_fab, (rows - 1) * rm + pad[1]) + 2 * latch_len, (rows - 1) * rm + 2 * mh_overlen + mh_pad[1]) + 2 * crt_offset\n    w_crt = max(body_width, coldist * (cols - 1) + pad[0]) + 2 * crt_offset if body_offset <= 0 else pad[0] / 2 + body_offset + body_width + 2 * crt_offset\n    l_crt = l_fab - crt_offset if body_offset <= 0 else -pad[0] / 2 - crt_offset\n    t_crt = min(t_fab - latch_len, -mh_overlen - mh_pad[1] / 2) - crt_offset\n    #if orientation == 'Horizontal' and latching and mh_ddrill > 0:\n    if mh_present and (mh_offset - mh_pad[0] / 2 < l_fab):\n        # horizontal latching with mounting holes is a special case\n        l_crt = mh_offset - mh_pad[0] / 2 - crt_offset\n        w_crt = -l_crt + body_width + body_offset + crt_offset\n    \n    # center of the body (horizontal: middle pin or the center of the middle pins for vertical)\n    center_fab = [coldist * (cols - 1) / 2 if orientation == 'Vertical' else body_offset + body_width / 2, t_fab + h_fab / 2]\n    center_fp = [l_crt + w_crt / 2, center_fab[1]]\n    \n    text_size = w_fab*0.6\n    fab_text_size_max = 1.0\n    if text_size < fab_text_size_min:\n        text_size = fab_text_size_min\n    elif text_size > fab_text_size_max:\n        text_size = fab_text_size_max\n    text_size = round(text_size, 2)\n    text_size = [text_size,text_size]\n    text_t = text_size[0] * 0.15\n    \n    footprint_name = \"{3}_{0}x{1:02}{7}_P{2:03.2f}mm{4}{5}_{6}\".format(cols, rows, rm, classname, \"_Latch\" if latching else \"\", \"{0:03.1f}mm\".format(latch_len) if latch_len > 0 else \"\", orientation, \"-1MP\" if mh_present else \"\")\n    #footprint_name = footprint_name_base + \"_MountHole\" if mh_present else footprint_name_base\n    \n    if cols == 1:\n        description_rows = \"single row\"\n        tags_rows = \"single row\"\n    elif cols == 2:\n        description_rows = \"double rows\"\n        tags_rows = \"double row\"\n    elif cols == 3:\n        description_rows = \"triple rows\"\n        tags_rows = \"triple row\"\n    elif cols == 4:\n        description_rows = \"quadruple rows\"\n        tags_rows = \"quadruple row\"\n    \n    description = \"Through hole {3}, {0}x{1:02}, {2:03.2f}mm pitch, DIN 41651 / IEC 60603-13, {4}{5}{6}{7}\".format(cols, rows, rm, classname_description, description_rows, \", {0:03.1f}mm\".format(latch_len) if latch_len > 0 else \"\", \" latches\" if latching else \"\", \", mounting holes\" if mh_present else \"\", orientation.lower())\n    tags = \"Through hole {5} {3} THT {0}x{1:02} {2:03.2f}mm {4}\".format(cols, rows, rm, classname_description, tags_rows, orientation.lower())\n    \n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n    \n    if extra_description:\n        description = description + \", \" + extra_description\n    \n    print(footprint_name)\n    \n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n    \n    # instantiate footprint (SMD origin at center, THT at pin 1)\n    kicad_modg = Footprint(footprint_name)\n    kicad_mod.append(kicad_modg)\n    \n    # set general values\n    kicad_modg.append(Text(type='reference', text='REF**', at=[center_fp[0], t_crt - text_size[1] / 2], layer='F.SilkS'))\n    kicad_modg.append(Text(type='user', text='%R', at=[center_fab[0], center_fab[1]], rotation=90, layer='F.Fab', size=text_size, thickness=text_t))\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[center_fp[0], t_crt + h_crt + text_size[1] / 2], layer='F.Fab'))\n    \n    # for shrouded headers, fab and silk layers have very similar geometry\n    # can use the same code to build lines on both layers with slight changes in values between layers\n    # zip together lists with fab and then silk layer settings as the list elements so the same code can draw both layers\n    for layer, line_width, lyr_offset, chamfer in zip(['F.Fab', 'F.SilkS'], [lw_fab, lw_slk], [0, slk_offset], [min(1, w_fab / 4), 0]):\n        # body outline\n        if orientation == 'Horizontal' and latching:\n            # body outline taken from existing KiCad footprint\n            body_polygon = [{'x':body_offset - lyr_offset, 'y':t_fab - lyr_offset}, {'x':l_fab + 6.98 + lyr_offset, 'y':t_fab - lyr_offset},\n                {'x':l_fab + w_fab + lyr_offset, 'y':t_fab + 3.17 - lyr_offset}, {'x':l_fab + w_fab + lyr_offset, 'y':t_fab + 6.99 + lyr_offset},\n                {'x':l_fab + 12.7 + lyr_offset, 'y':t_fab + 9.14 + lyr_offset}, {'x':l_fab + 12.7 + lyr_offset, 'y':t_fab + h_fab - 9.14 - lyr_offset},\n                {'x':l_fab + w_fab + lyr_offset, 'y':t_fab + h_fab - 6.99 - lyr_offset}, {'x':l_fab + w_fab + lyr_offset, 'y':t_fab + h_fab - 3.17 + lyr_offset},\n                {'x':l_fab + 6.98 + lyr_offset, 'y':t_fab + h_fab + lyr_offset}, {'x':body_offset - lyr_offset, 'y':t_fab + h_fab + lyr_offset}]\n            # body outline taken from simplified 3M 3000 model (also modify arguments: body_offset=-1.24 and body_width=1.24+15.53)\n            # https://www.3m.com/3M/en_US/company-us/all-3m-products/~/3M-Four-Wall-Header-3000-Series/?N=5002385+3290316872&preselect=8709318+8710652+8733900+8734573&rt=rud\n            body_polygon = [{'x':body_offset - lyr_offset, 'y':t_fab - lyr_offset}, {'x':l_fab + 7.11 + lyr_offset, 'y':t_fab - lyr_offset},\n                {'x':l_fab + 16.77 + lyr_offset, 'y':t_fab + 3.47 - lyr_offset}, {'x':l_fab + 16.77 + lyr_offset, 'y':t_fab + 7.44 + lyr_offset},\n                {'x':l_fab + 13.21 + lyr_offset, 'y':t_fab + 8.07 + lyr_offset}, {'x':l_fab + 13.21 + lyr_offset, 'y':t_fab + h_fab - 8.07 - lyr_offset},\n                {'x':l_fab + 16.77 + lyr_offset, 'y':t_fab + h_fab - 7.44 - lyr_offset}, {'x':l_fab + 16.77 + lyr_offset, 'y':t_fab + h_fab - 3.47 + lyr_offset},\n                {'x':l_fab + 7.11 + lyr_offset, 'y':t_fab + h_fab + lyr_offset}, {'x':body_offset - lyr_offset, 'y':t_fab + h_fab + lyr_offset}]\n            kicad_mod.append(PolygoneLine(polygone=body_polygon, layer=layer, width=line_width))\n            # now draw the left side vertical line, which may be broken on the silk layer around mounting holes\n            if layer == 'F.SilkS' and mh_present and mh_pad[0]/2 - mh_offset > -body_offset + slk_offset * 1.5:\n                body_polygon = [{'x':body_offset - lyr_offset, 'y':t_fab - lyr_offset}, {'x':body_offset - lyr_offset, 'y':mh_y[0] - mh_pad[0]/2}]\n                kicad_mod.append(PolygoneLine(polygone=body_polygon, layer=layer, width=line_width))\n                body_polygon = [{'x':body_offset - lyr_offset, 'y':mh_y[0] + mh_pad[0]/2}, {'x':body_offset - lyr_offset, 'y':mh_y[1] - mh_pad[0]/2}]\n                kicad_mod.append(PolygoneLine(polygone=body_polygon, layer=layer, width=line_width))\n                body_polygon = [{'x':body_offset - lyr_offset, 'y':mh_y[1] + mh_pad[0]/2}, {'x':body_offset - lyr_offset, 'y':t_fab + h_fab + lyr_offset}]\n                kicad_mod.append(PolygoneLine(polygone=body_polygon, layer=layer, width=line_width))\n            else:\n                body_polygon = [{'x':body_offset - lyr_offset, 'y':t_fab + h_fab + lyr_offset}, {'x':body_offset - lyr_offset, 'y':t_fab - lyr_offset}]\n                kicad_mod.append(PolygoneLine(polygone=body_polygon, layer=layer, width=line_width))\n        else:\n            # body outline silk lines need to clear the mounting hole on vertical headers\n            if mh_present and layer == 'F.SilkS':\n                body_polygon = [{'x':mh_offset + mh_pad[0]/2 - lyr_offset, 'y':t_fab - lyr_offset}, {'x':l_fab + w_fab + lyr_offset, 'y':t_fab - lyr_offset},\n                    {'x':l_fab + w_fab + lyr_offset, 'y':t_fab + h_fab + lyr_offset}, {'x':mh_offset + mh_pad[0]/2 - lyr_offset, 'y':t_fab + h_fab + lyr_offset}]\n                kicad_mod.append(PolygoneLine(polygone=body_polygon, layer=layer, width=line_width))\n                body_polygon = [{'x':mh_offset - mh_pad[0]/2 + lyr_offset, 'y':t_fab - lyr_offset}, {'x':l_fab - lyr_offset, 'y':t_fab - lyr_offset},\n                    {'x':l_fab - lyr_offset, 'y':t_fab + h_fab + lyr_offset}, {'x':mh_offset - mh_pad[0]/2 + lyr_offset, 'y':t_fab + h_fab + lyr_offset}]\n                kicad_mod.append(PolygoneLine(polygone=body_polygon, layer=layer, width=line_width))\n            else:\n                body_polygon = [{'x':l_fab + chamfer - lyr_offset, 'y':t_fab - lyr_offset}, {'x':l_fab + w_fab + lyr_offset, 'y':t_fab - lyr_offset},\n                    {'x':l_fab + w_fab + lyr_offset, 'y':t_fab + h_fab + lyr_offset}, {'x':l_fab - lyr_offset, 'y':t_fab + h_fab + lyr_offset},\n                    {'x':l_fab - lyr_offset, 'y':t_fab + chamfer - lyr_offset}]\n                kicad_mod.append(PolygoneLine(polygone=body_polygon, layer=layer, width=line_width))\n        if chamfer > 0 and not (orientation == 'Horizontal' and latching):\n            kicad_modg.append(Line(start=[l_fab, t_fab + chamfer], end=[l_fab + chamfer, t_fab], layer=layer, width=line_width))\n        \n        # vertical mating connector outline (this is the same for both layers)\n        if orientation == 'Vertical':\n            mating_conn_polygon = [{'x':l_fab - lyr_offset, 'y':center_fab[1] - notch_width/2}, {'x':l_fab + wall_thickness, 'y':center_fab[1] - notch_width/2},\n                {'x':l_fab + wall_thickness, 'y':-mating_overlen}, {'x':l_fab + w_fab - wall_thickness, 'y':-mating_overlen},\n                {'x':l_fab + w_fab - wall_thickness, 'y':(rows - 1) * rm + mating_overlen}, {'x':l_fab + wall_thickness, 'y':(rows - 1) * rm + mating_overlen},\n                {'x':l_fab + wall_thickness, 'y':center_fab[1] + notch_width/2}, {'x':l_fab + wall_thickness, 'y':center_fab[1] + notch_width/2},\n                {'x':l_fab - lyr_offset, 'y':center_fab[1] + notch_width/2}]\n            kicad_mod.append(PolygoneLine(polygone=mating_conn_polygon, layer=layer, width=line_width))\n        \n        # horizontal mating connector 'notch' lines\n        if orientation == 'Horizontal' and not latching:\n            kicad_modg.append(Line(start=[body_offset - lyr_offset, center_fab[1] - notch_width / 2], end=[l_fab + w_fab + lyr_offset, center_fab[1] - notch_width / 2], layer=layer, width=line_width))\n            kicad_modg.append(Line(start=[body_offset - lyr_offset, center_fab[1] + notch_width / 2], end=[l_fab + w_fab + lyr_offset, center_fab[1] + notch_width / 2], layer=layer, width=line_width))\n        \n        # vertical latches (horizontal latches are off the PCB and not shown)\n        if orientation == 'Vertical' and latching and latch_len > 0:\n            # body outline silk lines need to clear the mounting hole on vertical headers\n            if mh_present and layer == 'F.SilkS':\n                # top latch\n                latch_top_polygon = [{'x':center_fab[0] - latch_width/2 - lyr_offset, 'y':mh_y[0] - mh_pad[1]/2 + lyr_offset}, {'x':center_fab[0] - latch_width/2 - lyr_offset, 'y':t_fab - latch_len - lyr_offset},\n                    {'x':center_fab[0] + latch_width/2 + lyr_offset, 'y':t_fab - latch_len - lyr_offset}, {'x':center_fab[0] + latch_width/2 + lyr_offset, 'y':mh_y[0] - mh_pad[1]/2 + lyr_offset}]\n                kicad_mod.append(PolygoneLine(polygone=latch_top_polygon, layer=layer, width=line_width))\n                # bottom latch\n                latch_bottom_polygon = [{'x':center_fab[0] - latch_width/2 - lyr_offset, 'y':mh_y[1] + mh_pad[1]/2 - lyr_offset}, {'x':center_fab[0] - latch_width/2 - lyr_offset, 'y':t_fab + h_fab + latch_len + lyr_offset},\n                    {'x':center_fab[0] + latch_width/2 + lyr_offset, 'y':t_fab + h_fab + latch_len + lyr_offset}, {'x':center_fab[0] + latch_width/2 + lyr_offset, 'y':mh_y[1] + mh_pad[1]/2 - lyr_offset}]\n                kicad_mod.append(PolygoneLine(polygone=latch_bottom_polygon, layer=layer, width=line_width))\n            else:\n                # top latch\n                latch_top_polygon = [{'x':center_fab[0] - latch_width/2 - lyr_offset, 'y':t_fab - lyr_offset}, {'x':center_fab[0] - latch_width/2 - lyr_offset, 'y':t_fab - latch_len - lyr_offset},\n                    {'x':center_fab[0] + latch_width/2 + lyr_offset, 'y':t_fab - latch_len - lyr_offset}, {'x':center_fab[0] + latch_width/2 + lyr_offset, 'y':t_fab - lyr_offset}]\n                kicad_mod.append(PolygoneLine(polygone=latch_top_polygon, layer=layer, width=line_width))\n                # bottom latch\n                latch_bottom_polygon = [{'x':center_fab[0] - latch_width/2 - lyr_offset, 'y':t_fab + h_fab + lyr_offset}, {'x':center_fab[0] - latch_width/2 - lyr_offset, 'y':t_fab + h_fab + latch_len + lyr_offset},\n                    {'x':center_fab[0] + latch_width/2 + lyr_offset, 'y':t_fab + h_fab + latch_len + lyr_offset}, {'x':center_fab[0] + latch_width/2 + lyr_offset, 'y':t_fab + h_fab + lyr_offset}]\n                kicad_mod.append(PolygoneLine(polygone=latch_bottom_polygon, layer=layer, width=line_width))\n    \n    # horizontal pin outlines (only applies if the body is right of the leftmost pin row)\n    #if orientation == 'Horizontal' and not latching:\n    if body_offset > 0:\n        for row in range(rows):\n            horiz_pin_polygon = [{'x':body_offset, 'y':rm * row - pin_size / 2}, {'x':-pin_size / 2, 'y':rm * row - pin_size / 2},\n                {'x':-pin_size / 2, 'y':rm * row + pin_size / 2}, {'x':body_offset, 'y':rm * row + pin_size / 2}]\n            kicad_modg.append(PolygoneLine(polygone=horiz_pin_polygon, layer='F.Fab', width=lw_fab))\n    \n    # silk pin 1 mark (triangle to the left of pin 1)\n    slk_mark_height = 1\n    slk_mark_width = 1\n    slk_mark_tip = min(l_fab, -pad[0] / 2) - 0.5 # offset 0.5mm from pin 1 or the body\n    slk_polygon = [{'x':slk_mark_tip, 'y':0}, {'x':slk_mark_tip - slk_mark_width, 'y':-slk_mark_height / 2},\n        {'x':slk_mark_tip - slk_mark_width, 'y':slk_mark_height / 2}, {'x':slk_mark_tip, 'y':0}]\n    kicad_mod.append(PolygoneLine(polygone=slk_polygon, layer='F.SilkS', width=lw_slk))\n    \n    # create courtyard\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt), roundCrt(t_crt)], end=[roundCrt(l_crt + w_crt),\n                roundCrt(t_crt + h_crt)], layer='F.CrtYd', width=lw_crt))\n    \n    # create pads (first the left row then the right row)\n    for start_pos, initial in zip([0, coldist], range(1, cols + 1)):\n        kicad_modg.append(PadArray(pincount=rows, spacing=[0,rm], start=[start_pos,0], initial=initial, increment=cols,\n            type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, size=pad, drill=ddrill, layers=Pad.LAYERS_THT))\n    \n    # create mounting hole pads\n    if mh_present:\n        for mh_y_offset in mh_y:\n            kicad_modg.append(Pad(number=mh_number, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=[mh_offset, mh_y_offset], size=mh_pad,\n                drill=mh_ddrill, layers=Pad.LAYERS_THT))\n    \n    # add model (even if there are mounting holes on the footprint do not include that in the 3D model)\n    kicad_modg.append(Model(filename=\"{0}/{1}.3dshapes/{2}.wrl\".format(model3d_path_prefix, lib_name, footprint_name), at=offset3d, scale=scale3d, rotate=rotate3d))\n    \n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n    \n    # write file\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name))\n\n\n#\n#             <-->pack_offset\n#                 <------->pack_width\n#                          <------------------------------>pin_length\n#    <-coldist>\n# +---            +-------+\n# | OOO      OOO  |       +-------------------------------+            ^\n# | OOO ==== OOO  |       |                               +    ^       pin_width\n#   OOO      OOO  |       +-------------------------------+    |       v\n#                 +-------+                                    rm\n#   OOO      OOO  |       +-------------------------------+    |\n#   OOO ==== OOO  |       |                               +    v\n#   OOO      OOO  |       +-------------------------------+\n#                 +-------+                                    rm\n#\ndef makePinHeadAngled(rows, cols, rm, coldist, pack_width, pack_offset, pin_length, pin_width, ddrill, pad,\n                      tags_additional=[], lib_name=\"Pin_Headers\", classname=\"Pin_Header\",\n                      classname_description=\"pin header\", offset3d=[0, 0, 0], scale3d=[1, 1, 1],\n                      rotate3d=[0, 0, 0], model3d_path_prefix=\"${KISYS3DMOD}\"):\n    h_fabb = (rows - 1) * rm + rm / 2 + rm / 2\n    w_fabb = pack_width\n    l_fabb = coldist * (cols - 1) + pack_offset\n    t_fabb = -rm / 2\n    l_fabp = l_fabb + w_fabb\n    t_fabp = -pin_width / 2\n    text_size = w_fabb*0.6\n    fab_text_size_max = 1.0\n    if text_size < fab_text_size_min:\n        text_size = fab_text_size_min\n    elif text_size > fab_text_size_max:\n        text_size = fab_text_size_max\n    text_size = round(text_size, 2)\n    text_size = [text_size,text_size]\n    text_t = text_size[0] * 0.15\n    \n    h_slkb = h_fabb + 2 * slk_offset\n    w_slkb = w_fabb + 2 * slk_offset\n    l_slkb = l_fabb - slk_offset\n    t_slkb = t_fabb - slk_offset\n    l_slkp = l_slkb + w_slkb\n    t_slkp = t_fabp - slk_offset\n    l_slk = -rm / 2\n    t_slk = -rm / 2\n    body_lines_y = False\n\n    w_crt = rm / 2 + (cols - 1) * coldist + pack_offset + pack_width + pin_length + 2 * crt_offset\n    h_crt = h_fabb + 2 * crt_offset\n    l_crt = -rm / 2 - crt_offset\n    t_crt = -rm / 2 - crt_offset\n    \n    # if rm == 2.54:\n    #    footprint_name = \"Pin_Header_Angled_{0}x{1:02}\".format(cols, rows)\n    # else:\n    footprint_name = \"{3}_Angled_{0}x{1:02}_Pitch{2:03.2f}mm\".format(cols, rows, rm, classname)\n    \n    description = \"Through hole angled {4}, {0}x{1:02}, {2:03.2f}mm pitch, {3}mm pin length\".format(cols, rows,\n                                                                                                    rm,\n                                                                                                    pin_length,\n                                                                                                    classname_description)\n    tags = \"Through hole angled {3} THT {0}x{1:02} {2:03.2f}mm\".format(cols, rows, rm, classname_description)\n    if (cols == 1):\n        description = description + \", single row\"\n        tags = tags + \" single row\"\n    elif (cols == 2):\n        description = description + \", double rows\"\n        tags = tags + \" double row\"\n    elif (cols == 3):\n        description = description + \", triple rows\"\n        tags = tags + \" triple row\"\n    \n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n    \n    print(footprint_name)\n    \n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n    \n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    offset = [0, 0]\n    kicad_modg = Translation(offset[0], offset[1])\n    kicad_mod.append(kicad_modg)\n    \n    # set general values\n    kicad_modg.append(\n        Text(type='reference', text='REF**', at=[l_crt + w_crt / 2, t_crt + crt_offset - txt_offset], layer='F.SilkS'))\n    kicad_modg.append(\n        Text(type='user', text='%R', at=[l_fabb + (w_fabb/2), t_crt + offset[1] + (h_crt/2)], rotation=90, layer='F.Fab', size=text_size ,thickness=text_t))\n    kicad_modg.append(\n        Text(type='value', text=footprint_name, at=[l_crt + w_crt / 2, t_crt + h_crt - crt_offset + txt_offset],\n             layer='F.Fab'))\n    \n    # create FAB-layer\n    chamfer = w_fabb/4\n    kicad_modg.append(Line(start=[l_fabb + chamfer, t_fabb], end=[l_fabb + w_fabb, t_fabb], layer='F.Fab', width=lw_fab))\n    kicad_modg.append(Line(start=[l_fabb + w_fabb, t_fabb], end=[l_fabb + w_fabb, t_fabb+rm*rows], layer='F.Fab', width=lw_fab))\n    kicad_modg.append(Line(start=[l_fabb + w_fabb, t_fabb+rm*rows], end=[l_fabb, t_fabb+rm*rows], layer='F.Fab', width=lw_fab))\n    kicad_modg.append(Line(start=[l_fabb, t_fabb+rm*rows], end=[l_fabb, t_fabb+chamfer], layer='F.Fab', width=lw_fab))\n    kicad_modg.append(Line(start=[l_fabb, t_fabb+chamfer], end=[l_fabb + chamfer, t_fabb], layer='F.Fab', width=lw_fab))\n    y1 = t_fabb\n    yp = t_fabp\n    for r in range(1, rows + 1):\n        kicad_modg.append(Line(start=[-pin_width/2, yp], end=[l_fabb, yp], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[-pin_width/2, yp], end=[-pin_width/2, yp + pin_width], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[-pin_width/2, yp + pin_width], end=[l_fabb, yp + pin_width], layer='F.Fab', width=lw_fab))\n\n        kicad_modg.append(Line(start=[l_fabb + w_fabb, yp], end=[l_fabp + pin_length, yp], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[l_fabp + pin_length, yp], end=[l_fabp + pin_length, yp + pin_width], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[l_fabb + w_fabb, yp + pin_width], end=[l_fabp + pin_length, yp + pin_width], layer='F.Fab', width=lw_fab))\n\n        y1 = y1 + rm\n        yp = yp + rm\n    \n    # create SILKSCREEN-layer + pin1 marker\n\n    #calculate point to avoid collision with pad clearance\n    pin_line_x = sqrt(((pad[0]/2+min_pad_distance+slk_offset) * (pad[0]/2+min_pad_distance+slk_offset) - (pin_width/2+slk_offset) * (pin_width/2+slk_offset)))\n    # Silkscreen body\n    body_min_x_square = pad[0]/2+min_pad_distance+slk_offset\n    body_min_y_square = pad[1]/2+min_pad_distance+slk_offset\n\n    if rm/2 < body_min_y_square:\n        body_min_x_round = sqrt((((pad[0]/2+min_pad_distance+slk_offset) * (pad[0]/2+min_pad_distance+slk_offset)) - (rm/2 * rm/2)))\n        if l_slkb > body_min_x_round + (cols-1)*coldist and l_slkb < body_min_x_square +(cols-1)*coldist:\n            body_lines_y = sqrt((((pad[0]/2+min_pad_distance+slk_offset) * (pad[0]/2+min_pad_distance+slk_offset)) - ((l_slkb-(cols-1)*coldist) * (l_slkb-(cols-1)*coldist))))\n    else:\n        body_min_x_round  = 0\n    if rm/2+slk_offset < body_min_y_square:\n        bodyend_min_x_round = sqrt((((pad[0]/2+min_pad_distance+slk_offset) * (pad[0]/2+min_pad_distance+slk_offset)) - ((rm/2+slk_offset) * (rm/2+slk_offset))))\n    else:\n        bodyend_min_x_round = 0\n    # if body is starting outside the pads\n    if l_slkb-slk_offset > pad[0]/2 + min_pad_distance + (cols-1)*coldist:\n        kicad_modg.append(RectLine(start=[l_slkb, t_slkb], end=[l_slkp, t_slkb+rm*rows+slk_offset*2], layer='F.SilkS', width=lw_slk))\n    else:\n        if l_slkb < body_min_x_square + (cols-1)*coldist and t_slkb-slk_offset > -(body_min_y_square + (cols-1)*coldist):\n            if cols == 1:\n                upper_body_x = body_min_x_square\n            else:\n                upper_body_x = bodyend_min_x_round + (cols-1)*coldist\n        else:\n            upper_body_x = l_slkb\n        if rows == 1 and cols == 1:\n            lower_body_x = body_min_x_square  + (cols-1)*coldist\n        elif l_slkb < bodyend_min_x_round + (cols-1)*coldist and t_slkb-slk_offset > -(body_min_y_square + (cols-1)*coldist):\n            lower_body_x = bodyend_min_x_round + (cols-1)*coldist\n        else:\n            lower_body_x = l_slkb\n        if body_lines_y != False:\n            if cols == 1:\n                kicad_modg.append(PolygoneLine(polygone=[[upper_body_x, t_slkb], [l_slkp, t_slkb], [l_slkp, t_slkb+rm*rows+slk_offset*2],\n                    [lower_body_x, t_slkb+rm*rows+slk_offset*2],[lower_body_x, t_slkb+rm*rows-rm/2+slk_offset+body_lines_y]], layer='F.SilkS', width=lw_slk))\n            else:\n                kicad_modg.append(PolygoneLine(polygone=[[upper_body_x, -body_lines_y],[upper_body_x, t_slkb], [l_slkp, t_slkb], [l_slkp, t_slkb+rm*rows+slk_offset*2],\n                    [lower_body_x, t_slkb+rm*rows+slk_offset*2],[lower_body_x, t_slkb+rm*rows-rm/2+slk_offset+body_lines_y]], layer='F.SilkS', width=lw_slk))\n        else:\n            kicad_modg.append(PolygoneLine(polygone=[[upper_body_x, t_slkb], [l_slkp, t_slkb], [l_slkp, t_slkb+rm*rows+slk_offset*2],\n                [lower_body_x, t_slkb+rm*rows+slk_offset*2]], layer='F.SilkS', width=lw_slk))\n\n    for r in range(0, rows):\n        if r != 0:\n            if r == 1 and rm/2 < body_min_y_square and cols == 1:\n                if l_slkb < body_min_x_square:\n                    kicad_modg.append(Line(start=[body_min_x_square, (r-1)*rm+rm/2], end=[l_slkp, (r-1)*rm+rm/2], layer='F.SilkS',width=lw_slk))\n                else:\n                    kicad_modg.append(Line(start=[l_slkb, (r-1)*rm+rm/2], end=[l_slkp, (r-1)*rm+rm/2], layer='F.SilkS',width=lw_slk))\n            else:\n                # add line between rows\n                if l_slkb < body_min_x_round + (cols-1)*coldist:\n                    kicad_modg.append(Line(start=[body_min_x_round+ (cols-1)*coldist, (r-1)*rm+rm/2], end=[l_slkp, (r-1)*rm+rm/2], layer='F.SilkS',width=lw_slk))\n                else:\n                    kicad_modg.append(Line(start=[l_slkb, (r-1)*rm+rm/2], end=[l_slkp, (r-1)*rm+rm/2], layer='F.SilkS',width=lw_slk))\n                    if body_lines_y != False:\n                        kicad_modg.append(Line(start=[l_slkb, (r-1)*rm+body_lines_y], end=[l_slkb, (r)*rm-body_lines_y], layer='F.SilkS',width=lw_slk))\n                \n\n        # pin\n        kicad_modg.append(PolygoneLine(polygone=[[l_slkp, r*rm-pin_width/2-slk_offset], [l_slkp + pin_length, r*rm-pin_width/2-slk_offset], \n            [l_slkp + pin_length, r*rm+pin_width/2+slk_offset],[l_slkp, r*rm+pin_width/2+slk_offset]], layer='F.SilkS', width=lw_slk))\n        # color the first pin\n        if r == 0:\n            y = -(pin_width/2)\n            while y < pin_width/2:\n                kicad_modg.append(Line(start=[l_slkp, y], end=[l_slkp + pin_length, y], layer='F.SilkS', width=lw_slk))\n                y += lw_slk\n        # if body is starting at the pads\n        if l_slkb-slk_offset > pad[0]/2 + min_pad_distance + (cols-1)*coldist:\n            if r == 0 and cols == 1:\n                #add the lines between pads and silkscreenbody\n                kicad_modg.append(Line(start=[pad[0]/2+min_pad_distance+slk_offset, r*rm-pin_width/2-slk_offset], \n                    end=[l_slkb, r*rm-pin_width/2-slk_offset], layer='F.SilkS', width=lw_slk))\n                kicad_modg.append(Line(start=[pad[0]/2+min_pad_distance+slk_offset, r*rm+pin_width/2+slk_offset],\n                    end=[l_slkb, r*rm+pin_width/2+slk_offset], layer='F.SilkS', width=lw_slk))\n            else:\n                #add the lines between pads and silkscreenbody\n                kicad_modg.append(Line(start=[(cols-1)*coldist + pin_line_x, r*rm-pin_width/2-slk_offset], \n                    end=[l_slkb, r*rm-pin_width/2-slk_offset], layer='F.SilkS', width=lw_slk))\n                kicad_modg.append(Line(start=[(cols-1)*coldist + pin_line_x, r*rm+pin_width/2+slk_offset],\n                    end=[l_slkb, r*rm+pin_width/2+slk_offset], layer='F.SilkS', width=lw_slk))\n        \n        if cols > 1:\n            for c in range(1, cols):\n                #add the lines between pads\n                start_point_x = (c-1)*coldist+pin_line_x\n                end_point_x = c*coldist-pin_line_x\n                if start_point_x < end_point_x - lw_slk:\n                    if r == 0 and c == 1:\n                        kicad_modg.append(Line(start=[pad[0]/2+min_pad_distance+slk_offset, r*rm-pin_width/2-slk_offset], \n                            end=[end_point_x, r*rm-pin_width/2-slk_offset], layer='F.SilkS', width=lw_slk))\n                        kicad_modg.append(Line(start=[pad[0]/2+min_pad_distance+slk_offset, r*rm+pin_width/2+slk_offset],\n                            end=[end_point_x, r*rm+pin_width/2+slk_offset], layer='F.SilkS', width=lw_slk))\n                    else:\n                        kicad_modg.append(Line(start=[start_point_x, r*rm-pin_width/2-slk_offset], \n                        end=[end_point_x, r*rm-pin_width/2-slk_offset], layer='F.SilkS', width=lw_slk))\n                        kicad_modg.append(Line(start=[start_point_x, r*rm+pin_width/2+slk_offset],\n                        end=[end_point_x, r*rm+pin_width/2+slk_offset], layer='F.SilkS', width=lw_slk))\n\n    \n    # pin 1 marker\n    pin1_min = -(pad[0]/2+slk_offset+min_pad_distance)\n    if pin1_min < l_slk:\n        pin1_x = pin1_min\n    else:\n        pin1_x = l_slk\n    if pin1_min < t_slk:\n        pin1_y = pin1_min\n    else:\n        pin1_y = t_slk\n    kicad_modg.append(PolygoneLine(polygone=[[pin1_x, 0], [pin1_x, pin1_y], [0, pin1_y]], layer='F.SilkS', width=lw_slk))\n    \n    # create courtyard\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\n                              end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\n                              layer='F.CrtYd', width=lw_crt))\n    \n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0\n    \n    pad_type = Pad.TYPE_THT\n    pad_shape1 = Pad.SHAPE_RECT\n    pad_shapeother = Pad.SHAPE_OVAL\n    pad_layers = Pad.LAYERS_THT\n    \n    p = 1\n    \n    for r in range(1, rows + 1):\n        x1 = 0\n        for c in range(1, cols + 1):\n            if p == 1:\n                kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=ddrill,\n                                      layers=pad_layers))\n            else:\n                kicad_modg.append(\n                    Pad(number=p, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=ddrill,\n                        layers=pad_layers))\n            \n            p = p + 1\n            x1 = x1 + coldist\n        \n        y1 = y1 + rm\n    \n    # add model\n    kicad_modg.append(\n        Model(filename=model3d_path_prefix + \"/\" + lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=offset3d, scale=scale3d, rotate=rotate3d))\n    \n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n    \n    # write file\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name))\n\n#\n#                                                          <-->pack_offset\n#                 <--------------pack_width--------------->\n#                                                             <-coldist>\n#                 +---------------------------------------+            ---+\n#                 |                                       |  OOO      OOO |          ^\n#                 |                                       |  OOO ==== OOO |  ^       pin_width\n#                 |                                       |  OOO      OOO    |       v\n#                 +---------------------------------------+                  rm\n#                 |                                       |  OOO      OOO    |\n#                 |                                       |  OOO ==== OOO    v\n#                 |                                       |  OOO      OOO\n#                 +---------------------------------------+\n#\ndef makeSocketStripAngled(rows, cols, rm, coldist, pack_width, pack_offset, pin_width, ddrill, pad,\n                      tags_additional=[], lib_name=\"$Socket_Strips\", classname=\"Socket_Strip\",\n                      classname_description=\"socket strip\", offset3d=[0, 0, 0], scale3d=[1, 1, 1],\n                      rotate3d=[0, 0, 0], model3d_path_prefix=\"${KISYS3DMOD}\"):\n    h_fabb = (rows - 1) * rm + rm / 2 + rm / 2\n    w_fabb = -pack_width\n    l_fabb = -1*(coldist * (cols - 1) + pack_offset)\n    t_fabb = -rm / 2\n    l_fabp = l_fabb + w_fabb\n    t_fabp = -pin_width / 2\n\n    h_slkb = cc_fabb + 2 * slk_offset\n    w_slkb = w_fabb - 2 * slk_offset\n    l_slkb = l_fabb + slk_offset\n    t_slkb = t_fabb - slk_offset\n    l_slkp = l_slkb + w_slkb\n    t_slkp = t_fabp - slk_offset\n    l_slk = -rm / 2\n    t_slk = -rm / 2\n    \n    w_crt = -1*(rm / 2 + (cols - 1) * coldist + pack_offset + pack_width  + 2 * crt_offset)\n    h_crt = h_fabb + 2 * crt_offset\n    l_crt = rm / 2 + crt_offset\n    t_crt = -rm / 2 - crt_offset\n    \n    # if rm == 2.54:\n    #    footprint_name = \"Pin_Header_Angled_{0}x{1:02}\".format(cols, rows)\n    # else:\n    footprint_name = \"{3}_Angled_{0}x{1:02}_Pitch{2:03.2f}mm\".format(cols, rows, rm, classname)\n    \n    description = \"Through hole angled {4}, {0}x{1:02}, {2:03.2f}mm pitch, {3}mm socket length\".format(cols, rows,\n                                                                                                    rm,\n                                                                                                    pack_width,\n                                                                                                    classname_description)\n    tags = \"Through hole angled {3} THT {0}x{1:02} {2:03.2f}mm\".format(cols, rows, rm, classname_description)\n    if (cols == 1):\n        description = description + \", single row\"\n        tags = tags + \" single row\"\n    elif (cols == 2):\n        description = description + \", double rows\"\n        tags = tags + \" double row\"\n    elif (cols == 3):\n        description = description + \", triple rows\"\n        tags = tags + \" triple row\"\n    \n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n    \n    print(footprint_name)\n    \n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n    \n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    offset = [0, 0]\n    kicad_modg =Translation(offset[0], offset[1])\n    kicad_mod.append(kicad_modg)\n    \n    # set general values\n    kicad_modg.append(\n        Text(type='reference', text='REF**', at=[l_crt + w_crt / 2, t_crt + crt_offset - txt_offset], layer='F.SilkS'))\n    kicad_modg.append(\n        Text(type='user', text='%R', at=[l_crt + w_crt / 2, t_crt + crt_offset - txt_offset], layer='F.Fab'))\n    kicad_modg.append(\n        Text(type='value', text=footprint_name, at=[l_crt + w_crt / 2, t_crt + h_crt - crt_offset + txt_offset],\n             layer='F.Fab'))\n    \n    # create FAB-layer\n    y1 = t_fabb\n    yp = t_fabp\n    for r in range(1, rows + 1):\n        kicad_modg.append(RectLine(start=[l_fabb, y1], end=[l_fabb + w_fabb, y1 + rm], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(\n            RectLine(start=[0, yp], end=[l_fabb , yp + pin_width], layer='F.Fab', width=lw_fab))\n        y1 = y1 + rm\n        yp = yp + rm\n    \n    # create SILKSCREEN-layer + pin1 marker\n    y1 = t_slkb\n    yp = t_slkp\n    for r in range(1, rows + 1):\n        if (rows == 1 and r == 1):\n            kicad_modg.append(\n                RectLine(start=[l_slkb, y1], end=[l_slkp, y1 + rm + 2 * slk_offset], layer='F.SilkS',\n                         width=lw_slk))\n        if (r == 1 or r == rows):\n            kicad_modg.append(RectLine(start=[l_slkb, y1], end=[l_slkp, y1 + rm + slk_offset], layer='F.SilkS',\n                                       width=lw_slk))\n            y1 = y1 + slk_offset\n        else:\n            kicad_modg.append(RectLine(start=[l_slkb, y1], end=[l_slkp, y1 + rm], layer='F.SilkS', width=lw_slk))\n        \n        kicad_modg.append(Line(start=[-1*((cols - 1) * coldist + pad[0] / 2 + slk_offset+lw_slk), yp], end=[l_slkb, yp], layer='F.SilkS',width=lw_slk))\n        kicad_modg.append(Line(start=[-1*((cols - 1) * coldist + pad[0] / 2 + slk_offset+lw_slk), yp + pin_width + 2 * slk_offset],end=[l_slkb, yp + pin_width + 2 * slk_offset], layer='F.SilkS', width=lw_slk))\n        if cols > 1:\n            for c in range(2, cols + 1):\n                kicad_modg.append(Line(start=[-1*((c - 2) * coldist + pad[0] / 2 + slk_offset+lw_slk), yp],\n                                       end=[-1*((c - 1) * coldist - pad[0] / 2 - slk_offset-lw_slk), yp], layer='F.SilkS',\n                                       width=lw_slk))\n                kicad_modg.append(\n                    Line(start=[-1*((c - 2) * coldist + pad[0] / 2 + slk_offset+lw_slk), yp + pin_width + 2 * slk_offset],\n                         end=[-1*((c - 1) * coldist - pad[0] / 2 - slk_offset-lw_slk), yp + pin_width + 2 * slk_offset],\n                         layer='F.SilkS', width=lw_slk))\n        if r == 1:\n            y = y1 + lw_slk\n            while y < y1 + rm + 2 * slk_offset:\n                kicad_modg.append(Line(start=[l_slkb, y], end=[l_slkp, y], layer='F.SilkS', width=lw_slk))\n                y = y + lw_slk\n        y1 = y1 + rm\n        yp = yp + rm\n    \n    kicad_modg.append(PolygoneLine(polygone=[[0, -rm/2], [rm/2, -rm/2], [rm/2, 0]], layer='F.SilkS', width=lw_slk))\n    \n    # create courtyard\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\n                              end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\n                              layer='F.CrtYd', width=lw_crt))\n    \n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0\n    \n    pad_type = Pad.TYPE_THT\n    pad_shape1 = Pad.SHAPE_RECT\n    pad_shapeother = Pad.SHAPE_OVAL\n    pad_layers = Pad.LAYERS_THT \n\n    p = 1\n    for r in range(1, rows + 1):\n        x1 = 0\n        for c in range(1, cols + 1):\n            if p == 1:\n                kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=ddrill,\n                                      layers=pad_layers))\n            else:\n                kicad_modg.append(\n                    Pad(number=p, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=ddrill,\n                        layers=pad_layers))\n        \n            p = p + 1\n            x1 = x1 - coldist\n    \n        y1 = y1 + rm\n    \n    # add model\n    kicad_modg.append(\n        Model(filename=model3d_path_prefix + \"/\" + lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=offset3d, scale=scale3d, rotate=rotate3d))\n    \n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n    \n    # write file\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name))    \n    \n    \n    \n    \n    \ndef makePinHeadStraightSMD(rows, cols, rm, coldist, rmx_pad_offset,rmx_pin_length, pin_width, package_width, overlen_top, overlen_bottom, pad,\n                        start_left=True, tags_additional=[], lib_name=\"$Pin_Headers\", classname=\"Pin_Header\", classname_description=\"pin header\", offset3d=[0, 0, 0], scale3d=[1, 1, 1],\n                        rotate3d=[0, 0, 0], model3d_path_prefix=\"${KISYS3DMOD}\", isSocket=False):\n    ddrill=0.5\n    h_fab = (rows - 1) * rm + overlen_top + overlen_bottom\n    w_fab = package_width\n    l_fab = (coldist * (cols - 1) - w_fab) / 2\n    t_fab = -overlen_top\n    \n    h_slk = h_fab + 2 * slk_offset\n    w_slk = max(w_fab + 2 * slk_offset, coldist * (cols - 1) - pad[0] - 4 * slk_offset)\n    l_slk = (coldist * (cols - 1) - w_slk) / 2\n    t_slk = -overlen_top - slk_offset\n    \n    w_crt = max(package_width, coldist * (cols - 1)+2*rmx_pad_offset + pad[0]) + 2 * crt_offset\n    h_crt = max(h_fab, (rows - 1) * rm + pad[1]) + 2 * crt_offset\n    l_crt = coldist * (cols - 1) / 2 - w_crt / 2\n    t_crt = (rows - 1) * rm / 2 - h_crt / 2\n    \n    # if rm == 2.54:\n    #    footprint_name = \"Pin_Header_Straight_{0}x{1:02}\".format(cols, rows)\n    # else:\n    footprint_name = \"{3}_Straight_{0}x{1:02}_Pitch{2:03.2f}mm_SMD\".format(cols, rows, rm,classname)\n    \n    description = \"surface-mounted straight {3}, {0}x{1:02}, {2:03.2f}mm pitch\".format(cols, rows, rm,classname_description)\n    tags = \"Surface mounted {3} SMD {0}x{1:02} {2:03.2f}mm\".format(cols, rows, rm,classname_description)\n    if (cols == 1):\n        description = description + \", single row\"\n        tags = tags + \" single row\"\n        if start_left:\n            description = description + \", style 1 (pin 1 left)\"\n            tags = tags + \" style1 pin1 left\"\n            footprint_name = footprint_name + \"_Pin1Left\"\n        else:\n            description = description + \", style 2 (pin 1 right)\"\n            tags = tags + \" style2 pin1 right\"\n            footprint_name = footprint_name + \"_Pin1Right\"\n    elif (cols == 2):\n        description = description + \", double rows\"\n        tags = tags + \" double row\"\n\n\n\n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n    \n    print(footprint_name)\n    \n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n    kicad_mod.setAttribute('smd')\n    \n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    offset = [-(cols-1)*coldist/2, -(rows-1)*rm/2.0]\n    \n    kicad_modg = Translation(offset[0], offset[1])\n    kicad_mod.append(kicad_modg)\n    \n    # set general values\n    kicad_modg.append(\n        Text(type='reference', text='REF**', at=[coldist * (cols - 1) / 2, t_slk - txt_offset], layer='F.SilkS'))\n    kicad_modg.append(\n        Text(type='user', text='%R', at=[rm/2*(cols-1),(rows-1)*rm/2.0], rotation=90, layer='F.Fab'))\n    kicad_modg.append(\n        Text(type='value', text=footprint_name, at=[coldist * (cols - 1) / 2, t_slk + h_slk + txt_offset], layer='F.Fab'))\n\n    cleft = range(0, rows, 2)\n    cright = range(1, rows, 2)\n    if not start_left:\n        cleft = range(1, rows, 2)\n        cright = range(0, rows, 2)\n\n    # create FAB-layer\n    chamfer = (rm-pin_width)/2\n    kicad_modg.append(Line(start=[l_fab + w_fab, t_fab+h_fab], end=[l_fab, t_fab+h_fab], layer='F.Fab', width=lw_fab))\n    if start_left == True:\n        kicad_modg.append(Line(start=[l_fab + chamfer, t_fab], end=[l_fab + w_fab, t_fab], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[l_fab, t_fab+h_fab], end=[l_fab, t_fab+chamfer], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[l_fab, t_fab+chamfer], end=[l_fab + chamfer, t_fab], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[l_fab + w_fab, t_fab], end=[l_fab + w_fab, t_fab+h_fab], layer='F.Fab', width=lw_fab))\n    else:\n        kicad_modg.append(Line(start=[l_fab, t_fab], end=[l_fab + w_fab - chamfer, t_fab], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[l_fab + w_fab, t_fab+h_fab], end=[l_fab + w_fab, t_fab+chamfer], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[l_fab + w_fab, t_fab+chamfer], end=[l_fab + w_fab - chamfer, t_fab], layer='F.Fab', width=lw_fab))\n        kicad_modg.append(Line(start=[l_fab, t_fab], end=[l_fab, t_fab+h_fab], layer='F.Fab', width=lw_fab))\n\n    if cols==1:\n        for c in cleft:\n            kicad_modg.append(Line(start=[l_fab, c*rm-pin_width/2], end=[-rmx_pin_length, c*rm-pin_width/2], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[-rmx_pin_length, c*rm-pin_width/2], end=[-rmx_pin_length, c*rm+pin_width/2], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[-rmx_pin_length, c*rm+pin_width/2], end=[l_fab, c*rm+pin_width/2], layer='F.Fab', width=lw_fab))\n        for c in cright:\n            kicad_modg.append(Line(start=[l_fab + w_fab, c*rm-pin_width/2], end=[rmx_pin_length, c*rm-pin_width/2], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[rmx_pin_length, c*rm-pin_width/2], end=[rmx_pin_length, c*rm+pin_width/2], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[rmx_pin_length, c*rm+pin_width/2], end=[l_fab + w_fab, c*rm+pin_width/2], layer='F.Fab', width=lw_fab))\n    elif cols == 2:\n        for c in range(0,rows):\n            kicad_modg.append(Line(start=[l_fab, c*rm-pin_width/2], end=[-rmx_pin_length+rm/2, c*rm-pin_width/2], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[-rmx_pin_length+rm/2, c*rm-pin_width/2], end=[-rmx_pin_length+rm/2, c*rm+pin_width/2], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[-rmx_pin_length+rm/2, c*rm+pin_width/2], end=[l_fab, c*rm+pin_width/2], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[l_fab + w_fab, c*rm-pin_width/2], end=[rm/2+rmx_pin_length, c*rm-pin_width/2], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[rm/2+rmx_pin_length, c*rm-pin_width/2], end=[rm/2+rmx_pin_length, c*rm+pin_width/2], layer='F.Fab', width=lw_fab))\n            kicad_modg.append(Line(start=[rm/2+rmx_pin_length, c*rm+pin_width/2], end=[l_fab + w_fab, c*rm+pin_width/2], layer='F.Fab', width=lw_fab))\n\n    # create SILKSCREEN-layer + pin1 marker\n    slk_offset_pad = pad[1]/2+slk_offset+min_pad_distance\n    kicad_modg.append(Line(start=[l_slk, t_slk], end=[l_slk + w_slk, t_slk], layer='F.SilkS', width=lw_slk))\n    kicad_modg.append(Line(start=[l_slk, t_slk+h_slk], end=[l_slk + w_slk, t_slk+h_slk], layer='F.SilkS', width=lw_slk))\n   \n    if cols == 1:\n        for c in cleft:\n            if c == 0:\n                kicad_modg.append(Line(start=[l_slk , -slk_offset_pad], end=[-rmx_pad_offset-pad[0]/2+lw_slk/2 , -slk_offset_pad], layer='F.SilkS', width=lw_slk))\n                kicad_modg.append(Line(start=[l_slk , t_slk], end=[l_slk, -slk_offset_pad], layer='F.SilkS', width=lw_slk))\n                kicad_modg.append(Line(start=[l_slk+w_slk, (rows-1)*rm+slk_offset_pad],end=[l_slk+w_slk, t_slk+h_slk],layer='F.SilkS', width=lw_slk))\n                kicad_modg.append(Line(start=[l_slk+w_slk, -slk_offset_pad], end=[l_slk+w_slk, min(t_slk+h_slk,(c+1) * rm - slk_offset_pad)], layer='F.SilkS', width=lw_slk))\n            elif c == rows-1:\n                kicad_modg.append(Line(start=[l_slk+w_slk, max(t_slk, (c-1) * rm + slk_offset_pad)], end=[l_slk+w_slk, t_slk+h_slk], layer='F.SilkS', width=lw_slk))\n            else:\n                kicad_modg.append(Line(start=[l_slk+w_slk, max(t_slk, (c-1) * rm + slk_offset_pad)], end=[l_slk+w_slk, min(t_slk+h_slk,(c+1) * rm - slk_offset_pad)], layer='F.SilkS', width=lw_slk))\n        for c in cright:\n            if c == 0:\n                kicad_modg.append(Line(start=[l_slk+w_slk, -slk_offset_pad],end=[rmx_pad_offset+pad[0]/2-lw_slk/2, -slk_offset_pad],layer='F.SilkS', width=lw_slk))\n                kicad_modg.append(Line(start=[l_slk+w_slk, t_slk],end=[l_slk+w_slk, -slk_offset_pad],layer='F.SilkS', width=lw_slk))\n                kicad_modg.append(Line(start=[l_slk, (rows-1)*rm+slk_offset_pad],end=[l_slk, t_slk+h_slk],layer='F.SilkS', width=lw_slk))\n                kicad_modg.append(Line(start=[l_slk , -slk_offset_pad],end=[l_slk, min(t_slk+h_slk,(c+1) * rm - slk_offset_pad)], layer='F.SilkS',width=lw_slk))\n            if c == rows-1:\n                kicad_modg.append(Line(start=[l_slk , max(t_slk, (c-1) * rm + slk_offset_pad)],end=[l_slk, t_slk+h_slk], layer='F.SilkS',width=lw_slk))\n            else:\n                kicad_modg.append(Line(start=[l_slk , max(t_slk, (c-1) * rm + slk_offset_pad)],end=[l_slk, min(t_slk+h_slk,(c+1) * rm - slk_offset_pad)], layer='F.SilkS',width=lw_slk))\n    if (cols==2):\n        if isSocket:\n            #print(pad[0]/2+rmx_pad_offset,pad[0]/2,rmx_pad_offset)\n            kicad_modg.append(Line(start=[pad[0]/2+rmx_pad_offset+coldist, -(pad[1] / 2 + 2*lw_slk + slk_offset)], end=[l_slk+w_slk, -(pad[1] / 2 + 2*lw_slk + slk_offset)], layer='F.SilkS', width=lw_slk))\n        else:\n            kicad_modg.append(Line(start=[-rmx_pad_offset+rm/2-pad[0]/2+lw_slk/2, -slk_offset_pad], end=[l_slk, -slk_offset_pad], layer='F.SilkS', width=lw_slk))\n            kicad_modg.append(Line(start=[l_slk , t_slk], end=[l_slk, -slk_offset_pad], layer='F.SilkS', width=lw_slk))\n            kicad_modg.append(Line(start=[l_slk+w_slk , t_slk], end=[l_slk+w_slk, -slk_offset_pad], layer='F.SilkS', width=lw_slk))\n            kicad_modg.append(Line(start=[l_slk, (rows-1)*rm+slk_offset_pad],end=[l_slk, t_slk+h_slk],layer='F.SilkS', width=lw_slk))\n            kicad_modg.append(Line(start=[l_slk+w_slk, (rows-1)*rm+slk_offset_pad],end=[l_slk+w_slk, t_slk+h_slk],layer='F.SilkS', width=lw_slk))\n        if slk_offset_pad*2 < rm - lw_slk*2:\n            for c in range(0,rows-1):\n                kicad_modg.append(Line(start=[l_slk, c*rm+slk_offset_pad],end=[l_slk, (c+1)*rm-slk_offset_pad],layer='F.SilkS', width=lw_slk))\n                kicad_modg.append(Line(start=[l_slk+w_slk, c*rm+slk_offset_pad],end=[l_slk+w_slk, (c+1)*rm-slk_offset_pad],layer='F.SilkS', width=lw_slk))\n    # create courtyard\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\n                              end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\n                              layer='F.CrtYd', width=lw_crt))\n    \n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0\n    \n    pad_type = Pad.TYPE_SMT\n    pad_shape1 = Pad.SHAPE_RECT\n    pad_layers = Pad.LAYERS_SMT\n    \n    if cols==1:\n        for c in cleft:\n            kicad_modg.append(Pad(number=c+1, type=pad_type, shape=pad_shape1, at=[-rmx_pad_offset, c*rm], size=pad, drill=ddrill,layers=pad_layers))\n        for c in cright:\n            kicad_modg.append(Pad(number=c+1, type=pad_type, shape=pad_shape1, at=[rmx_pad_offset, c * rm], size=pad, drill=ddrill,layers=pad_layers))\n    elif cols==2:\n        p = 1\n        for c in range(0,rows):\n            if isSocket:\n                kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[rm/2+rmx_pad_offset, c * rm], size=pad, drill=ddrill,layers=pad_layers))\n                p=p+1\n                kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[-rmx_pad_offset+rm/2, c * rm], size=pad, drill=ddrill, layers=pad_layers))\n                p=p+1\n            else:\n                kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[-rmx_pad_offset+rm/2, c * rm], size=pad, drill=ddrill, layers=pad_layers))\n                p=p+1\n                kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[rmx_pad_offset+rm/2, c * rm], size=pad, drill=ddrill,layers=pad_layers))\n                p=p+1\n\n    # add model\n    kicad_modg.append(\n        Model(filename=model3d_path_prefix + \"/\" + lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=offset3d, scale=scale3d, rotate=rotate3d))\n    \n    # print render tree\n    # print(kicad_mod.getRenderTree())\n    # print(kicad_mod.getCompleteRenderTree())\n    \n    # write file\n    output_dir = '{lib_name:s}.pretty/'.format(lib_name=lib_name)\n    if not os.path.isdir(output_dir): #returns false if path does not yet exist!! (Does not check path validity)\n        os.makedirs(output_dir)\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile('{outdir:s}{fp_name:s}.kicad_mod'.format(outdir=output_dir, fp_name=footprint_name))\n"
  },
  {
    "path": "scripts/tools/footprint_scripts_potentiometers.py",
    "content": "#!/usr/bin/env python\r\n\r\nimport sys\r\nimport os\r\nimport math\r\nimport argparse\r\n\r\n# ensure that the kicad-footprint-generator directory is available\r\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\r\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\r\n\r\nfrom KicadModTree import *  # NOQA\r\nfrom drawing_tools import *\r\nfrom footprint_global_properties import *\r\n\r\n'''\r\n\r\nAn external argument interface is provided.\r\nIt should be used to make footprints part-by-part as needed.\r\nOnly minimal testing and error checking provided!\r\n\r\nSeparate scripts are provided to make \"off the shelf\" pots using these functions.\r\nSee make_Potentiometer_SMD.py and make_Potentiomter_THT.py\r\n\r\n'''\r\n\r\ndef makePotentiometerHorizontal(class_name=\"\", wbody=0, hbody=0, dscrew=0, style=\"normal\", ddrill=0,\r\n                              wscrew=0, wshaft=0, dshaft=0,\r\n                              pinxoffset=0, pinyoffset=0, pins=3, R_POW=0, x_3d=[0, 0, 0], s_3d=[1, 1, 1], r_3d=[0, 0, 0], has3d=1,\r\n                              rmx=5.08, rmy=5.08,\r\n                              specialtags=[], add_description=\"\", lib_name=\"Potentiometer\", name_additions=[], script3d=\"\",\r\n                              height3d=10, screwzpos=5, mh_ddrill=1.5, mh_count=0, mh_rmx=0, mh_rmy=15, mh_xoffset=0, mh_yoffset=0):\r\n    \"\"\"\r\n    create potentiometer footprints, horizontally mounted\r\n    \r\n    style=\"normal\":\r\n            ^   ^      +-----------+\r\n     pinyoffset |      |           |\r\n            v   |   ^  |   O1   O4 +-------+                                              ^\r\n                | rmy  |           |       +-------------------------------+ ^            |\r\n                |   v  |   O2   O5 |       |                               | dshaft       |\r\n                |      |           |       +-------------------------------+ v            dscrew\r\n                hbody  |   O3   O6 +-------+                                              v\r\n                |      |           |\r\n                v      +-----------+       <----------wshaft--------------->\r\n                            <rmx>  <------->wscrew\r\n                       <---wbody--->\r\n                                 <->pinxoffset\r\n    \r\n    \r\n    style=\"trimmer\" (only valid for 3-pin!!!):\r\n        O1           ^\r\n                     rmy\r\n                O2   v\r\n    \r\n        O3\r\n         <-rmx-->\r\n    \r\n    Parameters:\r\n        class_name: manufacturer and MPN like \"Bourns 3214W\" (str)\r\n        wbody: body length (float)\r\n        hbody: body height (float)\r\n        wscrew: collar length (float)\r\n        dscrew: collar diameter (float)\r\n        wshaft: shaft length (float)\r\n        dshaft: shaft diameter (float)\r\n        style: type of pot from \"normal\" or \"trimmer\" [default = \"normal\"] (str)\r\n        pinxoffset: distance from face of body to first column of pins [default = 0] (float)\r\n        pinyoffset: distance from top of body to first row of pins [default = 0] (float)\r\n        pins: number of pins; \"trimmer\" style can only support 3 pins [default = 3] (int)\r\n        rmx: column spacing of pins [default = 5.08] (float)\r\n        rmy: row (or vertical) spacing of pins [default = 5.08] (float)\r\n        ddrill: drill hole diameter [default = 1.5] (float)\r\n        R_POW: power rating of pot with zero being default [default = 0] (float)\r\n        x_3d: 3D model location [default = [0, 0, 0]] (list of floats)\r\n        s_3d: 3D model scaling [default = [1 / 2.54, 1 / 2.54, 1 / 2.54]] (list of floats)\r\n        r_3d: 3D model rotation [default = [0, 0, 0]] (list of floats)\r\n        has3d: presence of 3D model [default = 1] (bool)\r\n        specialtags: keywords that will be comma-delimited [default = []] (list of strs)\r\n        add_description: descriptive text [default = \"\"] (str)\r\n        lib_name: library name [default = \"Potentiometers\"] (str)\r\n        name_additions: extra text for footprint name that will be underscore-delimited [default = []] (list of strs)\r\n        script3d: script to kick off 3D model generation in FreeCad [default = \"\"] (str)\r\n        height3d: height of 3D model [default = 10] (float)\r\n        screwzpos: height of collar above bottom of body [default = 5] (float)\r\n        mh_ddrill: drill hole diameter of mounting holes [default = 1.5] (float)\r\n        mh_count: number of mounting holes; 1, 2, or 4 are supported [default = 0] (int)\r\n        mh_rmx: column spacing of mounting holes [default = 0] (float)\r\n        mh_rmy: row spacing of mounting holes [default = 15] (float)\r\n        mh_xoffset: distance from face of body to first column of mounting holes [default = 0] (float)\r\n        mh_yoffset: distance from top of body to first row of mounting holes [default = 0] (float)\r\n    \r\n    Returns:\r\n        None\r\n    \"\"\"\r\n    padx = 1.8 * ddrill\r\n    pady = padx\r\n    txt_offset = 1\r\n    slk_offset = 0.12\r\n    grid_crt = 0.01\r\n    \r\n    pad1style = Pad.SHAPE_CIRCLE\r\n    \r\n    cols = pins / 3\r\n    overpadwidth = rmx * (cols - 1) + padx\r\n    overpadheight = rmy * 2 + pady\r\n    \r\n    # generate list of pads depending on pin count\r\n    padpos = []\r\n    offset = [0, 0]\r\n    if pins >= 3:\r\n        # for 3 pins, pot could be normal with a vertical column of pins or a trimmer with staggered pins\r\n        if style==\"trimmer\":\r\n            padpos.append([3, 0, 2 * rmy, ddrill, padx, pady])\r\n            padpos.append([2, rmx, rmy, ddrill, padx, pady])\r\n            padpos.append([1, 0, 0, ddrill, padx, pady])\r\n            offset = [0, 0]\r\n        else:\r\n            padpos.append([3, 0, 0, ddrill, padx, pady])\r\n            padpos.append([2, 0, rmy, ddrill, padx, pady])\r\n            padpos.append([1, 0, 2 * rmy, ddrill, padx, pady])\r\n            offset = [0, -2 * rmy]\r\n    if pins >= 6:\r\n        padpos.append([6, -rmx, 0, ddrill, padx, pady])\r\n        padpos.append([5, -rmx, rmy, ddrill, padx, pady])\r\n        padpos.append([4, -rmx, 2 * rmy, ddrill, padx, pady])\r\n    if pins >= 9:\r\n        padpos.append([9, -2*rmx, 0, ddrill, padx, pady])\r\n        padpos.append([8, -2*rmx, rmy, ddrill, padx, pady])\r\n        padpos.append([7, -2*rmx, 2 * rmy, ddrill, padx, pady])\r\n\r\n    # add mounting holes to list of pads\r\n    if mh_count == 1:\r\n        padpos.append(['', mh_xoffset, -mh_yoffset, mh_ddrill, 2 * mh_ddrill, 2 * mh_ddrill])\r\n    if mh_count == 2:\r\n        padpos.append(['', mh_xoffset, -mh_yoffset, mh_ddrill, 2 * mh_ddrill, 2 * mh_ddrill])\r\n        padpos.append(['', mh_xoffset - mh_rmx, -mh_yoffset + mh_rmy, mh_ddrill, 2 * mh_ddrill, 2 * mh_ddrill])\r\n    if mh_count == 4:\r\n        padpos.append(['', mh_xoffset, -mh_yoffset, mh_ddrill, 2 * mh_ddrill, 2 * mh_ddrill])\r\n        padpos.append(['', mh_xoffset - mh_rmx, -mh_yoffset + mh_rmy, mh_ddrill, 2 * mh_ddrill, 2 * mh_ddrill])\r\n        padpos.append(['', mh_xoffset - mh_rmx, -mh_yoffset, mh_ddrill, 2 * mh_ddrill, 2 * mh_ddrill])\r\n        padpos.append(['', mh_xoffset, -mh_yoffset + mh_rmy, mh_ddrill, 2 * mh_ddrill, 2 * mh_ddrill])\r\n    \r\n    lbody_fab = -(wbody - pinxoffset) # left side of body\r\n    tbody_fab = -pinyoffset # top of body\r\n    wbody_fab = wbody # body length\r\n    hbody_fab = hbody # body height\r\n    \r\n    wscrew_fab = wscrew # collar length\r\n    hscrew_fab = dscrew # collar height\r\n    lscrew_fab = lbody_fab + wbody_fab # left side of collar\r\n    tscrew_fab = tbody_fab + (hbody_fab - hscrew_fab) / 2.0 # top of collar\r\n    \r\n    wshaft_fab = wshaft # shaft length\r\n    hshaft_fab = dshaft # shaft diameter\r\n    lshaft_fab = lscrew_fab + wscrew_fab # left side of shaft\r\n    tshaft_fab = tbody_fab + (hbody_fab - hshaft_fab) / 2.0 # top of shaft\r\n    \r\n    lbody_slk = lbody_fab - math.copysign(slk_offset, wbody_fab)\r\n    tbody_slk = tbody_fab - slk_offset\r\n    wbody_slk = wbody_fab + math.copysign(2 * slk_offset, wbody_fab)\r\n    hbody_slk = hbody_fab + 2 * slk_offset\r\n    \r\n    lscrew_slk = lbody_slk + wbody_slk\r\n    tscrew_slk = tscrew_fab - slk_offset\r\n    wscrew_slk = wscrew_fab\r\n    hscrew_slk = hscrew_fab + 2 * slk_offset\r\n\r\n    lshaft_slk = lscrew_slk + wscrew_slk\r\n    tshaft_slk = tshaft_fab - slk_offset\r\n    wshaft_slk = wshaft_fab\r\n    hshaft_slk = hshaft_fab + 2 * slk_offset\r\n\r\n    if wbody_fab < 0:\r\n        wscrew_slk = wscrew_slk + 2 * slk_offset\r\n        wshaft_slk = wshaft_slk + 2 * slk_offset\r\n\r\n    minx = miny = 1e99\r\n    maxx = maxy = -1e99\r\n    for p in padpos:\r\n        maxx = max(maxx, p[1] + p[4] / 2)\r\n        minx = min(minx, p[1] - p[4] / 2)\r\n        maxy = max(maxy, p[2] + p[5] / 2)\r\n        miny = min(miny, p[2] - p[5] / 2)\r\n    \r\n    minx = min(minx, lbody_fab, lbody_fab + wbody_fab + wscrew_fab + wshaft_fab)\r\n    miny = min(miny, tbody_fab, tscrew_fab, tshaft_fab)\r\n    maxx = max(maxx, lbody_fab + wbody_fab + wscrew_fab + wshaft_fab, lbody_fab)\r\n    maxy = max(maxy, tbody_fab + hbody_fab, tscrew_fab + hscrew_fab, tshaft_fab + hshaft_fab)\r\n    \r\n    h_crt = (maxy - miny) + 2 * crt_offset\r\n    w_crt = (maxx - minx) + 2 * crt_offset\r\n    l_crt = minx - crt_offset\r\n    t_crt = miny - crt_offset\r\n    \r\n    pow_rat = \"\"\r\n    if R_POW > 0:\r\n        pow_rat = \"{0}W\".format(R_POW)\r\n        if (1 / R_POW == int(1 / R_POW)):\r\n            pow_rat = pow_rat + \" = 1/{0}W\".format(int(1 / R_POW))\r\n    \r\n    tgs = specialtags\r\n    print tgs\r\n    print class_name\r\n    tgs.append(class_name)\r\n    if len(pow_rat) > 0:\r\n        tgs.append(pow_rat)\r\n    \r\n    description = \"Potentiometer, horizontal\"\r\n    tags = \"Potentiometer horizontal\"\r\n    for t in tgs:\r\n        description = description + \", \" + t\r\n        tags = tags + \" \" + t\r\n    description = description + \", \" + add_description\r\n    \r\n    footprint_name = \"\"\r\n    for n in name_additions: footprint_name = footprint_name + \"_\" + n\r\n    footprint_name = lib_name + \"_\" + \"_\".join(class_name.split()) + \"_Horizontal\"\r\n        \r\n    print(footprint_name)\r\n    \r\n    if script3d != \"\":\r\n        with open(script3d, \"a\") as myfile:\r\n            myfile.write(\"\\n\\n # {0}\\n\".format(footprint_name))\r\n            myfile.write(\"import FreeCAD\\n\")\r\n            myfile.write(\"import os\\n\")\r\n            myfile.write(\"import os.path\\n\\n\")\r\n            myfile.write(\"App.ActiveDocument.clearAll()\\n\")\r\n\r\n            line=0\r\n            line += 1; script3d_writevariable(myfile, line, 'lbody_fab', min(lbody_fab+wbody_fab,lbody_fab)+offset[0])\r\n            line += 1; script3d_writevariable(myfile, line, 'tbody_fab', min(tbody_fab+hbody_fab,tbody_fab)+offset[1])\r\n            line += 1; script3d_writevariable(myfile, line, 'wbody_fab', math.fabs(wbody_fab))\r\n            line += 1; script3d_writevariable(myfile, line, 'hbody_fab', math.fabs(hbody_fab))\r\n            line += 1; script3d_writevariable(myfile, line, 'lscrew_fab', min(lscrew_fab+wscrew_fab,lscrew_fab)+offset[0])\r\n            line += 1; script3d_writevariable(myfile, line, 'tscrew_fab', min(tscrew_fab+hscrew_fab,tscrew_fab)+offset[1])\r\n            line += 1; script3d_writevariable(myfile, line, 'wscrew_fab', math.fabs(wscrew_fab))\r\n            line += 1; script3d_writevariable(myfile, line, 'hscrew_fab', math.fabs(hscrew_fab))\r\n            line += 1; script3d_writevariable(myfile, line, 'lshaft_fab', min(lshaft_fab+wshaft_fab,lshaft_fab)+offset[0])\r\n            line += 1; script3d_writevariable(myfile, line, 'tshaft_fab', min(tshaft_fab+hshaft_fab,tshaft_fab)+offset[1])\r\n            line += 1; script3d_writevariable(myfile, line, 'wshaft_fab', math.fabs(wshaft_fab))\r\n            line += 1; script3d_writevariable(myfile, line, 'hshaft_fab', math.fabs(hshaft_fab))\r\n            line += 1; script3d_writevariable(myfile, line, 'rmx', rmx)\r\n            line += 1; script3d_writevariable(myfile, line, 'rmy', rmy)\r\n            for p in padpos:\r\n                if p[0]==1:\r\n                    line += 1;\r\n                    script3d_writevariable(myfile, line, 'padx', p[1])\r\n                    line += 1;\r\n                    script3d_writevariable(myfile, line, 'pady', p[2])\r\n            line += 1; script3d_writevariable(myfile, line, 'd_wire', ddrill-0.3)\r\n            line += 1; script3d_writevariable(myfile, line, 'height', height3d)\r\n            line += 1; script3d_writevariable(myfile, line, 'screwzpos', screwzpos)\r\n            written=False\r\n            for p in padpos:\r\n                if p[0] == 0 and not written:\r\n                    line += 1;\r\n                    script3d_writevariable(myfile, line, 'mhpadx', p[1])\r\n                    line += 1;\r\n                    script3d_writevariable(myfile, line, 'mhpady', p[2])\r\n                    written=True\r\n            line += 1; script3d_writevariable(myfile, line, 'mh_rmx', mh_rmx)\r\n            line += 1; script3d_writevariable(myfile, line, 'mh_rmy', mh_rmy)\r\n            line += 1; script3d_writevariable(myfile, line, 'offsetx', offset[0])\r\n            line += 1; script3d_writevariable(myfile, line, 'offsety', offset[1])\r\n\r\n\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\\n\")\r\n            myfile.write(\"doc = FreeCAD.activeDocument()\\n\")\r\n            myfile.write(\"__objs__=[]\\n\")\r\n            myfile.write(\"for obj in doc.Objects:\t\\n\")\r\n            myfile.write(\"    if obj.ViewObject.Visibility:\\n\")\r\n            myfile.write(\"        __objs__.append(obj)\\n\")\r\n            myfile.write(\"\\nFreeCADGui.export(__objs__,os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.wrl\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"doc.saveCopy(os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.FCStd\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"print(\\\"created {0}\\\")\\n\".format(footprint_name))\r\n    \r\n    # init kicad footprint\r\n    kicad_mod = Footprint(footprint_name)\r\n    kicad_mod.setDescription(description)\r\n    kicad_mod.setTags(tags)\r\n    \r\n    kicad_modg = Translation(offset[0], offset[1])\r\n    kicad_mod.append(kicad_modg)\r\n    \r\n    # set general values\r\n    kicad_modg.append(Text(type='reference', text='REF**', at=[0, t_crt - txt_offset], layer='F.SilkS'))\r\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[0, t_crt + h_crt + txt_offset], layer='F.Fab'))\r\n    \r\n    # create FAB-layer\r\n    # horizontal pot: place refdes on F.Fab in center of body and shrink size if body is small\r\n    text_size = min(1, abs(round(wbody_fab / 4.5, 2)))\r\n    kicad_modg.append(Text(type='user', text='%R', at=[lbody_fab+wbody_fab/2.0, tbody_fab+hbody_fab/2.0], size=[text_size, text_size], layer='F.Fab'))\r\n    \r\n    kicad_modg.append(RectLine(start=[lbody_fab, tbody_fab], end=[lbody_fab + wbody_fab, tbody_fab + hbody_fab], layer='F.Fab',width=lw_fab))\r\n    if wscrew_fab * hscrew_fab != 0:\r\n        kicad_modg.append(\r\n            RectLine(start=[lscrew_fab, tscrew_fab], end=[lscrew_fab + wscrew_fab, tscrew_fab + hscrew_fab],layer='F.Fab', width=lw_fab))\r\n    if wshaft_fab * hshaft_fab != 0:\r\n        kicad_modg.append(\r\n            RectLine(start=[lshaft_fab, tshaft_fab], end=[lshaft_fab + wshaft_fab, tshaft_fab + hshaft_fab],layer='F.Fab', width=lw_fab))\r\n    \r\n    # build keepout for silkscreen\r\n    keepouts = []\r\n    for p in padpos:\r\n        keepouts = keepouts + addKeepoutRound(p[1], p[2], p[4] + 2 * lw_slk + 2 * slk_offset, p[5] + 2 * lw_slk + 2 * slk_offset)\r\n    \r\n    # create SILKSCREEN-layer\r\n    addRectWithKeepout(kicad_modg, lbody_slk, tbody_slk, wbody_slk, hbody_slk, 'F.SilkS', lw_slk, keepouts, 0.001)\r\n    if wscrew>0 and wscrew_slk * hscrew_slk != 0:\r\n        addRectWithKeepout(kicad_modg, lscrew_slk, tscrew_slk, wscrew_slk, hscrew_slk, 'F.SilkS', lw_slk, keepouts,0.001)\r\n    if wshaft>0 and wshaft_slk * hshaft_slk != 0:\r\n        addRectWithKeepout(kicad_modg, lshaft_slk, tshaft_slk, wshaft_slk, hshaft_slk, 'F.SilkS', lw_slk, keepouts,0.001)\r\n    \r\n    # create courtyard\r\n    kicad_mod.append(RectLine(start=[roundG(l_crt + offset[0], grid_crt), roundG(t_crt + offset[1], grid_crt)],\r\n                              end=[roundG(l_crt + w_crt + offset[0], grid_crt), roundG(t_crt + h_crt + offset[1], grid_crt)],layer='F.CrtYd', width=lw_crt))\r\n    \r\n    # create pads\r\n    for p in padpos:\r\n        ps = Pad.SHAPE_CIRCLE\r\n        if p[0] == 1:\r\n            ps = pad1style\r\n        kicad_modg.append(Pad(number=p[0], type=Pad.TYPE_THT, shape=ps, at=[p[1], p[2]], size=[p[4], p[5]], drill=p[3],\r\n                              layers=['*.Cu', '*.Mask']))\r\n    \r\n    # add model\r\n    if (has3d != 0):\r\n        kicad_modg.append(Model(filename=\"${KISYS3DMOD}/\" + lib_name + \"_THT.3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=r_3d))\r\n    \r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n    \r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(footprint_name + '.kicad_mod')\r\n\r\n\r\n\r\ndef makePotentiometerVertical(class_name, wbody, hbody, screwstyle=\"none\", style=\"normal\", d_body=0, dshaft=6,\r\n                                dscrew=7, c_ddrill=0, c_offsetx=0, c_offsety=0, pinxoffset=0, pinyoffset=0,\r\n                                pins=3, rmx=5.08, rmy=5.08, ddrill=1.5, shaft_hole=False, SMD_pads=False,\r\n                                SMD_padsize=[], SMD_type=\"3-5\", R_POW=0, x_3d=[0, 0, 0], s_3d=[1, 1, 1], r_3d=[0, 0, 0], has3d=1,\r\n                                specialtags=[], add_description=\"\", lib_name=\"Potentiometer\", name_additions=[],\r\n                                script3d=\"\", height3d=10, mh_ddrill=1.5, mh_count=0, mh_rmx=0, mh_rmy=15,\r\n                                mh_xoffset=0, mh_yoffset=0, mh_smd=False, mh_padsize=[], mh_nopads=False):\r\n    \"\"\"\r\n    create potentiometer footprints, vertically mounted\r\n    \r\n    style=normal\r\n                        <-->pinxoffset\r\n            ^   ^          +---------------+ ^\r\n     pinyoffset |          |               | |\r\n            v   |   ^  O1  |               | cofsety\r\n                | rmy      |     CCCCC     | |\r\n                |   v  O2  |     CCCCC     | v\r\n                |          |     CCCCC     |\r\n                hbody  O3  |               |\r\n                |          |               |\r\n                v          +---------------+\r\n                           <------->coffsetx\r\n                           <-----wbody----->\r\n    \r\n    \r\n    style=trimmer (only valid for 3-pin!!!)    \r\n        O1           ^\r\n                     rmy\r\n                O2   v\r\n    \r\n        O3\r\n         <-rmx-->\r\n    \r\n    Parameters:\r\n        class_name: manufacturer and MPN like \"Bourns 3214W\" (str)\r\n        wbody: body length (float)\r\n        hbody: body height (float)\r\n        screwstyle: screw style from \"none\", \"slit\", or \"cross\" [default = \"none\"] (str)\r\n        style: type of pot from \"normal\" or \"trimmer\" [default = \"normal\"] (str)\r\n        d_body: diameter of body for circular pot [default = 0] (float)\r\n        dshaft: shaft diameter [default = 6] (float)\r\n        dscrew: collar diameter [default = 7] (float)\r\n        c_ddrill: drill diameter to fit collar or zero for no hole [default = 0] (float)\r\n        c_offsetx: distance from left side of body to collar center [default = 0] (float)\r\n        c_offsety:: distance from top of body to collar center [default = 0] (float)\r\n        pinxoffset: distance from left side of body to first column of pins [default = 0] (float)\r\n        pinyoffset: distance from top of body to first row of pins [default = 0] (float)\r\n        pins: number of pins; \"trimmer\" style can only support 3 pins [default = 3] (int)\r\n        rmx: column spacing of pins [default = 5.08] (float)\r\n        rmy: row (or vertical) spacing of pins [default = 5.08] (float)\r\n        ddrill: drill hole diameter [default = 1.5] (float)\r\n        shaft_hole: places hole under pot for shaft through PCB [default = False] (bool)\r\n        SMD_pads: allows using SMD pads [default = False] (bool)\r\n        SMD_padsize: X and Y dimensions of SMD pads in [X, Y] format [default = []] (list of floats)\r\n        SMD_type: allow specifying the SMD pad layout from below options [default = \"3-5\"] (str)\r\n                \"3-5\": 5 pin pot with 3 pins on left side and 2 pins on right side with no middle pin\r\n        R_POW: power rating of pot with zero being default [default = 0] (float)\r\n        x_3d: 3D model location [default = [0, 0, 0]] (list of floats)\r\n        s_3d: 3D model scaling [default = [1 / 2.54, 1 / 2.54, 1 / 2.54]] (list of floats)\r\n        r_3d: 3D model rotation [default = [0, 0, 0]] (list of floats)\r\n        has3d: presence of 3D model [default = 1] (bool)\r\n        specialtags: keywords that will be comma-delimited [default = []] (list of strs)\r\n        add_description: descriptive text [default = \"\"] (str)\r\n        lib_name: library name [default = \"Potentiometers\"] (str)\r\n        name_additions: extra text for footprint name that will be underscore-delimited [default = []] (list of strs)\r\n        script3d: script to kick off 3D model generation in FreeCad [default = \"\"] (str)\r\n        height3d: height of 3D model [default = 10] (float)\r\n        mh_ddrill: drill hole diameter of mounting holes [default = 1.5] (float)\r\n        mh_count: number of mounting holes; 1, 2, or 4 are supported [default = 0] (int)\r\n        mh_rmx: column spacing of mounting holes [default = 0] (float)\r\n        mh_rmy: row spacing of mounting holes [default = 15] (float)\r\n        mh_xoffset: distance from left side of body to first column of mounting holes [default = 0] (float)\r\n        mh_yoffset: distance from top of body to first row of mounting holes [default = 0] (float)\r\n        mh_smd: allows using SMD mounting holes [default = False] (bool)\r\n        mh_padsize: X and Y dimensions of SMD mounting holes in [X, Y] format [default = []] (list of floats)\r\n        mh_nopads: allows selecting the presence of mounting holes [default = False] (bool)\r\n    \r\n    Returns:\r\n        None\r\n    \"\"\"\r\n    padx = 1.8 * ddrill\r\n    pady = padx\r\n    if SMD_pads and len(SMD_padsize) >= 2:\r\n        padx = SMD_padsize[0]\r\n        pady = SMD_padsize[1]\r\n    \r\n    txt_offset = 1\r\n    slk_offset = 0.12\r\n    grid_crt = 0.01\r\n    \r\n    pad1style = Pad.SHAPE_CIRCLE\r\n    \r\n    cols = pins / 3\r\n    overpadwidth = rmx * (cols - 1) + padx\r\n    overpadheight = rmy * 2 + pady\r\n    \r\n    padpos = []\r\n    offset = [0, 0]\r\n    padtype = Pad.TYPE_THT\r\n    padstyle = Pad.SHAPE_CIRCLE\r\n    if SMD_pads:\r\n        padtype = Pad.TYPE_SMT\r\n        padstyle = Pad.SHAPE_RECT\r\n    mhtype = Pad.TYPE_NPTH\r\n    mhstyle = Pad.SHAPE_CIRCLE\r\n    if mh_smd:\r\n        mhtype = Pad.TYPE_SMT\r\n        mhstyle = Pad.SHAPE_RECT\r\n    if pins >= 3:\r\n        if style == \"trimmer\":\r\n            padpos.append([3, 0, 0, ddrill, padx, pady, padtype, padstyle])\r\n            padpos.append([2, rmx, rmy, ddrill, padx, pady, padtype, padstyle])\r\n            padpos.append([1, 0, 2 * rmy, ddrill, padx, pady, padtype, padstyle])\r\n            offset = [0, -2 * rmy]\r\n            if SMD_pads:\r\n                offset = [-rmx/2.0, -rmy]\r\n        else:\r\n            padpos.append([3, 0, 0, ddrill, padx, pady, padtype, padstyle])\r\n            padpos.append([2, 0, rmy, ddrill, padx, pady, padtype, padstyle])\r\n            padpos.append([1, 0, 2 * rmy, ddrill, padx, pady, padtype, padstyle])\r\n            offset = [0, -2 * rmy]\r\n            if SMD_pads:\r\n                offset = [0, -rmy]\r\n    if pins == 4:\r\n        padpos.append([4, 0, -rmy, ddrill, padx, pady, padtype, padstyle])\r\n    if pins == 5 and SMD_pads and SMD_type == \"3-5\":\r\n        padpos.append([5, -rmx / 2.0 + rmx + pinxoffset, 0, ddrill, padx, pady, padtype, padstyle])\r\n        padpos.append([4, -rmx / 2.0 + rmx + pinxoffset, 2 * rmy, ddrill, padx, pady, padtype, padstyle])\r\n        if SMD_pads:\r\n            offset[0] = -rmx / 2.0\r\n    if pins >= 6:\r\n        padpos.append([6, -rmx, 0, ddrill, padx, pady, padtype, padstyle])\r\n        padpos.append([5, -rmx, rmy, ddrill, padx, pady, padtype, padstyle])\r\n        padpos.append([4, -rmx, 2 * rmy, ddrill, padx, pady, padtype, padstyle])\r\n        if SMD_pads:\r\n            offset[0] = -rmx / 2.0\r\n    if pins >= 9:\r\n        padpos.append([9, -2 * rmx, 0, ddrill, padx, pady, padtype, padstyle])\r\n        padpos.append([8, -2 * rmx, rmy, ddrill, padx, pady, padtype, padstyle])\r\n        padpos.append([7, -2 * rmx, 2 * rmy, ddrill, padx, pady, padtype, padstyle])\r\n        if SMD_pads:\r\n            offset[0] = -rmx\r\n    \r\n    mhpadsizex = 2 * mh_ddrill\r\n    mhpadsizey = mhpadsizex\r\n    if mh_nopads:\r\n        mhpadsizex = mh_ddrill\r\n        mhpadsizey = mhpadsizex\r\n    if mh_smd and len(mh_padsize) >= 2:\r\n        mhpadsizex = mh_padsize[0]\r\n        mhpadsizey = mh_padsize[1]\r\n    \r\n    if mh_count == 1:\r\n        padpos.append(['', mh_xoffset, -mh_yoffset, mh_ddrill, mhpadsizex, mhpadsizey, mhtype, mhstyle])\r\n    if mh_count == 2:\r\n        padpos.append(['', mh_xoffset, -mh_yoffset, mh_ddrill, mhpadsizex, mhpadsizey, mhtype, mhstyle])\r\n        padpos.append(['', mh_xoffset - mh_rmx, -mh_yoffset + mh_rmy, mh_ddrill, mhpadsizex, mhpadsizey, mhtype, mhstyle])\r\n    if mh_count == 4:\r\n        padpos.append(['', mh_xoffset, -mh_yoffset, mh_ddrill, mhpadsizex, mhpadsizey, mhtype, mhstyle])\r\n        padpos.append(['', mh_xoffset - mh_rmx, -mh_yoffset + mh_rmy, mh_ddrill, mhpadsizex, mhpadsizey, mhtype, mhstyle])\r\n        padpos.append(['', mh_xoffset - mh_rmx, -mh_yoffset, mh_ddrill, mhpadsizex, mhpadsizey, mhtype, mhstyle])\r\n        padpos.append(['', mh_xoffset, -mh_yoffset + mh_rmy, mh_ddrill, mhpadsizex, mhpadsizey, mhtype, mhstyle])\r\n    \r\n    lbody_fab = pinxoffset # why does the X offset of the pin set the body's left side location?!?!?!\r\n    tbody_fab = -pinyoffset\r\n    wbody_fab = wbody\r\n    hbody_fab = hbody\r\n    cdbody_fab = d_body\r\n    clbody_fab = lbody_fab + c_offsetx\r\n    ctbody_fab = tbody_fab + c_offsety\r\n    \r\n    if c_ddrill > 0 and shaft_hole == True:\r\n        padpos.append(['', clbody_fab, ctbody_fab, c_ddrill, c_ddrill, c_ddrill, mhtype, mhstyle])\r\n    \r\n    lbody_slk = lbody_fab - slk_offset\r\n    tbody_slk = tbody_fab - slk_offset\r\n    wbody_slk = wbody_fab + 2 * slk_offset\r\n    hbody_slk = hbody_fab + 2 * slk_offset\r\n    cdbody_slk = cdbody_fab + 2 * slk_offset\r\n    clbody_slk = clbody_fab\r\n    ctbody_slk = ctbody_fab\r\n    \r\n    minx = miny = 1e99\r\n    maxx = maxy = -1e99\r\n    for p in padpos:\r\n        maxx = max(maxx, p[1] + p[4] / 2)\r\n        minx = min(minx, p[1] - p[4] / 2)\r\n        maxy = max(maxy, p[2] + p[5] / 2)\r\n        miny = min(miny, p[2] - p[5] / 2)\r\n    \r\n    minx = min(minx, lbody_fab, clbody_fab - cdbody_fab / 2)\r\n    miny = min(miny, tbody_fab, ctbody_fab - cdbody_fab / 2)\r\n    maxx = max(maxx, lbody_fab + wbody_fab, clbody_fab + cdbody_fab / 2)\r\n    maxy = max(maxy, tbody_fab + hbody_fab, ctbody_fab + cdbody_fab / 2)\r\n    \r\n    h_crt = (maxy - miny) + 2 * crt_offset\r\n    w_crt = (maxx - minx) + 2 * crt_offset\r\n    l_crt = minx - crt_offset\r\n    t_crt = miny - crt_offset\r\n    \r\n    pow_rat = \"\"\r\n    if R_POW > 0:\r\n        pow_rat = \"{0}W\".format(R_POW)\r\n        if (1 / R_POW == int(1 / R_POW)):\r\n            pow_rat = pow_rat + \" = 1/{0}W\".format(int(1 / R_POW))\r\n    \r\n    tgs = specialtags\r\n    tgs.append(class_name)\r\n    if len(pow_rat) > 0:\r\n        tgs.append(pow_rat)\r\n    \r\n    description = \"Potentiometer, vertical\"\r\n    tags = \"Potentiometer vertical\"\r\n    if shaft_hole:\r\n        description = description + \", shaft hole\"\r\n        tags = tags + \" hole\"\r\n    for t in tgs:\r\n        description = description + \", \" + t\r\n        tags = tags + \" \" + t\r\n    description = description + \", \" + add_description\r\n    \r\n    for n in name_additions: footprint_name = footprint_name + \"_\" + n\r\n    footprint_name = lib_name + \"_\" + \"_\".join(class_name.split()) + \"_Vertical\"\r\n    if shaft_hole: footprint_name = footprint_name + \"_Hole\"\r\n        \r\n    print(footprint_name)\r\n    \r\n    if script3d != \"\":\r\n        with open(script3d, \"a\") as myfile:\r\n            myfile.write(\"\\n\\n # {0}\\n\".format(footprint_name))\r\n            myfile.write(\"import FreeCAD\\n\")\r\n            myfile.write(\"import os\\n\")\r\n            myfile.write(\"import os.path\\n\\n\")\r\n\r\n            myfile.write(\"App.ActiveDocument.clearAll()\\n\")\r\n            \r\n            line = 0\r\n            line += 1; script3d_writevariable(myfile, line, 'lbody_fab', min(lbody_fab+wbody_fab,lbody_fab)+offset[0])\r\n            line += 1; script3d_writevariable(myfile, line, 'tbody_fab', min(tbody_fab+hbody_fab,tbody_fab)+offset[1])\r\n            line += 1; script3d_writevariable(myfile, line, 'wbody_fab', math.fabs(wbody_fab))\r\n            line += 1; script3d_writevariable(myfile, line, 'hbody_fab', math.fabs(hbody_fab))\r\n            line += 1; script3d_writevariable(myfile, line, 'clbody_fab', clbody_fab+offset[0])\r\n            line += 1; script3d_writevariable(myfile, line, 'ctbody_fab', ctbody_fab+offset[1])\r\n            line += 1; script3d_writevariable(myfile, line, 'cdbody_fab', cdbody_fab)\r\n            line += 1; script3d_writevariable(myfile, line, 'dscrew', dscrew)\r\n            line += 1; script3d_writevariable(myfile, line, 'dshaft', dshaft)\r\n            line += 1; script3d_writevariable(myfile, line, 'rmx', rmx)\r\n            line += 1; script3d_writevariable(myfile, line, 'rmy', rmy)\r\n            for p in padpos:\r\n                if p[0] == 1:\r\n                    line += 1;\r\n                    script3d_writevariable(myfile, line, 'padx', p[1])\r\n                    line += 1;\r\n                    script3d_writevariable(myfile, line, 'pady', p[2])\r\n            line += 1; script3d_writevariable(myfile, line, 'd_wire', ddrill-0.3)\r\n            line += 1; script3d_writevariable(myfile, line, 'height', height3d)\r\n            written=False\r\n            for p in padpos:\r\n                if p[0] == 0 and not written:\r\n                    line += 1;\r\n                    script3d_writevariable(myfile, line, 'mhpadx', p[1])\r\n                    line += 1;\r\n                    script3d_writevariable(myfile, line, 'mhpady', p[2])\r\n                    written=True\r\n            line += 1; script3d_writevariable(myfile, line, 'mh_rmx', mh_rmx)\r\n            line += 1; script3d_writevariable(myfile, line, 'mh_rmy', mh_rmy)\r\n            line += 1; script3d_writevariable(myfile, line, 'offsetx', offset[0])\r\n            line += 1; script3d_writevariable(myfile, line, 'offsety', offset[1])\r\n\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\\n\")\r\n            myfile.write(\"doc = FreeCAD.activeDocument()\\n\")\r\n            myfile.write(\"__objs__=[]\\n\")\r\n            myfile.write(\"for obj in doc.Objects:\t\\n\")\r\n            myfile.write(\"    if obj.ViewObject.Visibility:\\n\")\r\n            myfile.write(\"        __objs__.append(obj)\\n\")\r\n            myfile.write(\"\\nFreeCADGui.export(__objs__,os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.wrl\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"doc.saveCopy(os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.FCStd\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"print(\\\"created {0}\\\")\\n\".format(footprint_name))\r\n    \r\n    # init kicad footprint\r\n    kicad_mod = Footprint(footprint_name)\r\n    kicad_mod.setDescription(description)\r\n    kicad_mod.setTags(tags)\r\n    if SMD_pads:\r\n        kicad_mod.setAttribute('smd')\r\n    \r\n    kicad_modg = Translation(offset[0], offset[1])\r\n    kicad_mod.append(kicad_modg)\r\n    \r\n    # set general values\r\n    kicad_modg.append(Text(type='reference', text='REF**', at=[l_crt + w_crt / 2, t_crt - txt_offset], layer='F.SilkS'))\r\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[l_crt + w_crt / 2, t_crt + h_crt + txt_offset], layer='F.Fab'))\r\n    \r\n    # create FAB-layer\r\n    drawbody = wbody > 0\r\n    if cdbody_fab > 0:\r\n        if style == \"trimmer\":\r\n            dy = hbody_fab / 2.0\r\n            if drawbody and dy <= cdbody_fab / 2:\r\n                dx = math.sqrt(cdbody_fab * cdbody_fab / 4 - dy * dy)\r\n                alpha = 360 - 2 * math.atan(dy / dy) / 3.1415 * 180\r\n                kicad_modg.append(PolygoneLine(polygone=[[clbody_fab - dx, ctbody_fab - dy],[lbody_fab, ctbody_fab - dy],\r\n                                 [lbody_fab, ctbody_fab + dy],[clbody_fab - dx, ctbody_fab + dy]], layer='F.Fab', width=lw_fab))\r\n                kicad_modg.append(Arc(center=[clbody_fab, ctbody_fab], start=[clbody_fab-dx, ctbody_fab-dy], angle=alpha,layer='F.Fab', width=lw_fab))\r\n            else:\r\n                kicad_modg.append(Circle(center=[clbody_fab, ctbody_fab], radius=cdbody_fab / 2.0, layer='F.Fab', width=lw_fab))\r\n                \r\n                # vertical trimmer with circular body: place refdes on F.Fab inside\r\n                # calculate text size (also used for offset distance inside outer circle)\r\n                text_size = min(1, round((cdbody_fab - dscrew) / 4.0, 2))\r\n                kicad_modg.append(Text(type='user', text='%R', at=[clbody_fab - cdbody_fab / 2.0 + text_size * 1.2, ctbody_fab],\r\n                                 size=[text_size, text_size], layer='F.Fab', rotation = 90))\r\n                \r\n                if drawbody:\r\n                    kicad_modg.append(RectLine(start=[lbody_fab, tbody_fab], end=[lbody_fab + wbody_fab, tbody_fab + hbody_fab],\r\n                                 layer='F.Fab', width=lw_fab))\r\n        else:\r\n            cdradius = cdbody_fab / 2.0\r\n            kicad_modg.append(Circle(center=[clbody_fab, ctbody_fab], radius=cdradius, layer='F.Fab', width=lw_fab))\r\n            dy = hbody_fab / 2.0\r\n            \r\n            #kicad_modg.append(Text(type='user', text='REF**', at=[clbody_fab, ctbody_fab], size=[min(1.0, cdradius), min(1.0, cdradius)], layer='F.Fab'))\r\n            \r\n            if drawbody and dy <= cdbody_fab / 2.0:\r\n                dx = math.sqrt(cdbody_fab * cdbody_fab / 4 - dy * dy)\r\n                \r\n                # vertical pot with circular body: place refdes on F.Fab inside left edge of body\r\n                kicad_modg.append(Text(type='user', text='%R', at=[lbody_fab + 1, ctbody_fab], layer='F.Fab', rotation = 90))\r\n                \r\n                kicad_modg.append(PolygoneLine(polygone=[[clbody_fab - dx, ctbody_fab - dy],[lbody_fab, ctbody_fab - dy],\r\n                             [lbody_fab, ctbody_fab + dy],[clbody_fab - dx, ctbody_fab + dy]], layer='F.Fab', width=lw_fab))\r\n            elif drawbody:\r\n                kicad_modg.append(RectLine(start=[lbody_fab, tbody_fab], end=[lbody_fab + wbody_fab, tbody_fab + hbody_fab],\r\n                             layer='F.Fab', width=lw_fab))\r\n    elif drawbody:\r\n        # vertical pot with square body: place refdes on F.Fab inside left edge of body\r\n        kicad_modg.append(Text(type='user', text='%R', at=[lbody_fab + 1, ctbody_fab], layer='F.Fab', rotation = 90))\r\n        \r\n        kicad_modg.append(RectLine(start=[lbody_fab, tbody_fab], end=[lbody_fab + wbody_fab, tbody_fab + hbody_fab],\r\n                                   layer='F.Fab', width=lw_fab))\r\n    \r\n    if dscrew > 0:\r\n        #kicad_modg.append(Circle(center=[clbody_fab, ctbody_fab], radius=dscrew / 2.0, layer='F.Fab', width=lw_fab))\r\n        if screwstyle == \"slit\":\r\n            addSlitScrew(kicad_modg, clbody_fab, ctbody_fab, dscrew / 2.0, 'F.Fab', lw_fab)\r\n        elif screwstyle == \"cross\":\r\n            addCrossScrew(kicad_modg, clbody_fab, ctbody_fab, dscrew / 2.0, 'F.Fab', lw_fab)\r\n    \r\n    if dshaft > 0 and shaft_hole == False:\r\n        kicad_modg.append(Circle(center=[clbody_fab, ctbody_fab], radius=dshaft / 2.0, layer='F.Fab', width=lw_fab))\r\n    \r\n    # build keepout for silkscreen\r\n    keepouts = []\r\n    for p in padpos:\r\n        if p[7] == Pad.SHAPE_CIRCLE:\r\n            keepouts = keepouts + addKeepoutRound(p[1], p[2], p[4] + 2 * lw_slk + 2 * slk_offset, p[5] + 2 * lw_slk + 2 * slk_offset)\r\n        else:\r\n            keepouts = keepouts + addKeepoutRect(p[1], p[2], p[4] + 2 * lw_slk + 2 * slk_offset, p[5] + 2 * lw_slk + 2 * slk_offset)\r\n    # debug_draw_keepouts(kicad_modg,keepouts)\r\n    \r\n    # create SILKSCREEN-layer\r\n    drawbody = wbody > 0\r\n    if cdbody_fab > 0:\r\n        addCircleWithKeepout(kicad_modg, clbody_slk, ctbody_slk, cdbody_slk / 2.0, 'F.SilkS', lw_slk, keepouts)\r\n        dy = hbody_slk / 2.0\r\n        if drawbody and dy <= cdbody_slk / 2.0:\r\n            dx = math.sqrt(cdbody_slk * cdbody_slk / 4.0 - dy * dy)\r\n            addHLineWithKeepout(kicad_modg, clbody_slk - dx, lbody_slk, ctbody_slk - dy, 'F.SilkS', lw_slk,keepouts)\r\n            addVLineWithKeepout(kicad_modg, lbody_slk, ctbody_slk - dy, ctbody_slk + dy, 'F.SilkS', lw_slk,keepouts)\r\n            addHLineWithKeepout(kicad_modg, clbody_slk - dx, lbody_slk, ctbody_slk + dy, 'F.SilkS', lw_slk,keepouts)\r\n            drawbody = False\r\n    \r\n    if drawbody:\r\n        addRectWithKeepout(kicad_modg, lbody_slk, tbody_slk, wbody_slk, hbody_slk, 'F.SilkS', lw_slk, keepouts,0.001)\r\n        \r\n    # create courtyard\r\n    kicad_mod.append(RectLine(start=[roundG(l_crt + offset[0], grid_crt), roundG(t_crt + offset[1], grid_crt)],\r\n                              end=[roundG(l_crt + w_crt + offset[0], grid_crt), roundG(t_crt + h_crt + offset[1], grid_crt)],\r\n                              layer='F.CrtYd', width=lw_crt))\r\n    # create pads\r\n    for p in padpos:\r\n        if p[6] == Pad.TYPE_SMT:\r\n            kicad_modg.append(Pad(number=p[0], type=p[6], shape=p[7], at=[p[1], p[2]], size=[p[4], p[5]], drill=p[3], layers=['F.Cu', 'F.Paste', 'F.Mask']))\r\n        else:\r\n            kicad_modg.append(Pad(number=p[0], type=p[6], shape=p[7], at=[p[1], p[2]], size=[p[4], p[5]], drill=p[3], layers=['*.Cu', '*.Mask']))\r\n    \r\n    # add model\r\n    if (has3d != 0):\r\n        if SMD_pads:\r\n            kicad_modg.append(Model(filename=\"${KISYS3DMOD}/\" + lib_name + \"_SMD.3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=r_3d))\r\n        else:\r\n            kicad_modg.append(Model(filename=\"${KISYS3DMOD}/\" + lib_name + \"_THT.3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=r_3d))\r\n    \r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n    \r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(footprint_name + '.kicad_mod')\r\n\r\n\r\ndef makeSpindleTrimmer(class_name, wbody, hbody, pinxoffset, pinyoffset, rmx2, rmy2, rmx3, rmy3, dscrew, ddrill=1,\r\n                            wscrew=0, screwxoffset=0, screwyoffset=0, style = \"screwleft\", screwstyle=\"slit\",\r\n                            shaft_hole=False, SMD_pads=False, SMD_padsize=[], R_POW=0, x_3d=[0, 0, 0], s_3d=[1, 1, 1], r_3d=[0, 0, 0],\r\n                            has3d=1, specialtags=[], add_description=\"\", lib_name=\"Potentiometer\", name_additions=[],\r\n                            script3d=\"\", height3d=10):\r\n    \"\"\"\r\n    create spindle trimmer potentiometer (only valid for 3-pin!!!)\r\n                                                          <-----------rmx2------------->\r\n                      screwxoffset<>      <------------------rmx3---------------------->\r\n       screwyoffset ^              +---------------------------------------------------------------+         ^       ^\r\n                    |     ^   +----|                                                               |         |       |\r\n                    v  dsrew  +--  |                     O2O                                       | ^       |       pinyoffset\r\n                          v   +----|                                                               | rmy2    |       |\r\n                        wscrew<--->|     O3O                                           O1O         | v       hbody   v\r\n                                   |                                                               |         |\r\n                                   +---------------------------------------------------------------+         v\r\n                                   <----------------------------wbody------------------------------>\r\n                                   <------pinxoffset------------------------------------>\r\n    \r\n    Parameters:\r\n        class_name: manufacturer and MPN like \"Bourns 3214W\" (str)\r\n        wbody: body length (float)\r\n        hbody: body height (float)\r\n        pinxoffset: distance from left side of body to pin 1 (float)\r\n        pinyoffset: distance from top of body to pin 1 (float)\r\n        rmx2: distance from pin 1 left to pin 2 (float)\r\n        rmy2: distance from pin 1 up to pin 2 (float)\r\n        rmx3: distance from pin 1 left to pin 3 (float)\r\n        rmy3: distance from pin 1 up to pin 3 (float)\r\n        dscrew: screw diameter (float)\r\n        ddrill: drill hole diameter [default = 1] (float)\r\n        wscrew: length of screw for left screw types [default = 0] (float)\r\n        screwxoffset: distance from left side of body to screw for top screw types [default = 0] (float)\r\n        screwyoffset: distance from top of body to center of screw [default = 0] (float)\r\n        style: location of screw from \"screwleft\" or \"screwtop\" [default = \"screwleft\"] (str)\r\n        screwstyle: screw style from \"slit\" or \"cross\" [default = \"slit\"] (str)\r\n        SMD_pads: allows using SMD pads [default = False] (bool)\r\n        SMD_padsize: X and Y dimensions of SMD pads in [X, Y] format [default = []] (list of floats)\r\n        R_POW: power rating of pot with zero being default [default = 0] (float)\r\n        x_3d: 3D model location [default = [0, 0, 0]] (list of floats)\r\n        s_3d: 3D model scaling [default = [1 / 2.54, 1 / 2.54, 1 / 2.54]] (list of floats)\r\n        r_3d: 3D model rotation [default = [0, 0, 0]] (list of floats)\r\n        has3d: presence of 3D model [default = 1] (bool)\r\n        specialtags: keywords that will be comma-delimited [default = []] (list of strs)\r\n        add_description: descriptive text [default = \"\"] (str)\r\n        lib_name: library name [default = \"Potentiometers\"] (str)\r\n        name_additions: extra text for footprint name that will be underscore-delimited [default = []] (list of strs)\r\n        script3d: script to kick off 3D model generation in FreeCad [default = \"\"] (str)\r\n        height3d: height of 3D model [default = 10] (float)\r\n            \r\n    Returns:\r\n        None\r\n    \"\"\"\r\n    padx = 1.8 * ddrill\r\n    pady = padx\r\n    if SMD_pads and len(SMD_padsize) >= 2:\r\n        padx = SMD_padsize[0]\r\n        pady = SMD_padsize[1]\r\n    \r\n    txt_offset = 1\r\n    slk_offset = 0.12\r\n    grid_crt = 0.01\r\n    \r\n    padpos = []\r\n    padtype = Pad.TYPE_THT\r\n    padstyle = Pad.SHAPE_CIRCLE\r\n    if SMD_pads:\r\n        padtype = Pad.TYPE_SMT\r\n        padstyle = Pad.SHAPE_RECT\r\n    padpos.append([1, pinxoffset, pinyoffset, ddrill, padx, pady, padtype, padstyle])\r\n    if SMD_pads and len(SMD_padsize) >= 4:\r\n        padpos.append([2, pinxoffset+rmx2, pinyoffset+rmy2, ddrill, SMD_padsize[2], SMD_padsize[3], padtype, padstyle])\r\n    else:\r\n        padpos.append([2, pinxoffset + rmx2, pinyoffset + rmy2, ddrill, padx, pady, padtype, padstyle])\r\n    if SMD_pads and len(SMD_padsize) >= 6:\r\n        padpos.append([3, pinxoffset + rmx3, pinyoffset + rmy3, ddrill, SMD_padsize[4], SMD_padsize[5], padtype, padstyle])\r\n    else:\r\n        padpos.append([3, pinxoffset+rmx3, pinyoffset+rmy3, ddrill, padx, pady, padtype, padstyle])\r\n    offset = [-pinxoffset, -pinyoffset]\r\n    if SMD_pads:\r\n        offset = [-(max(padpos[0][1],padpos[1][1],padpos[2][1])+min(padpos[0][1],padpos[1][1],padpos[2][1]))/2, -(max(padpos[0][2],padpos[1][2],padpos[2][2])+min(padpos[0][2],padpos[1][2],padpos[2][2]))/2]\r\n        #offset = [-(pinxoffset+pinxoffset+rmx2+pinxoffset+rmx3)/3.0, -(pinyoffset+pinyoffset+rmy2+pinyoffset+rmy3)/3.0]\r\n    \r\n    lbody_fab = 0\r\n    tbody_fab = 0\r\n    wbody_fab = wbody\r\n    hbody_fab = hbody\r\n\r\n    lbody_slk = lbody_fab - slk_offset\r\n    tbody_slk = tbody_fab - slk_offset\r\n    wbody_slk = wbody_fab + 2 * slk_offset\r\n    hbody_slk = hbody_fab + 2 * slk_offset\r\n    \r\n    if style == \"screwtop\" and shaft_hole == True:\r\n        padpos.append(['', screwxoffset, screwyoffset, ddrill, ddrill, ddrill, Pad.TYPE_NPTH, Pad.SHAPE_CIRCLE])\r\n\r\n    if style==\"screwleft\":\r\n        orientation = \"horizontal\"\r\n        lscrew_fab=lbody_fab+screwxoffset-wscrew\r\n        tscrew_fab = tbody_fab + screwyoffset-dscrew/2.0\r\n        wscrew_fab = wscrew\r\n        hscrew_fab = dscrew\r\n        lscrew_slk=lscrew_fab-slk_offset\r\n        tscrew_slk = tscrew_fab-slk_offset\r\n        wscrew_slk = wscrew_fab\r\n        hscrew_slk = hscrew_fab+slk_offset*2\r\n    elif style==\"screwtop\":\r\n        orientation = \"vertical\"\r\n        lscrew_fab=lbody_fab+screwxoffset\r\n        tscrew_fab = tbody_fab + screwyoffset\r\n        wscrew_fab = dscrew\r\n        hscrew_fab = dscrew\r\n        lscrew_slk = lscrew_fab\r\n        tscrew_slk = tscrew_fab\r\n        wscrew_slk = wscrew_fab + 2*slk_offset\r\n        hscrew_slk = hscrew_fab + 2*slk_offset\r\n\r\n    minx = miny = 1e99\r\n    maxx = maxy = -1e99\r\n    for p in padpos:\r\n        maxx = max(maxx, p[1] + p[4] / 2)\r\n        minx = min(minx, p[1] - p[4] / 2)\r\n        maxy = max(maxy, p[2] + p[5] / 2)\r\n        miny = min(miny, p[2] - p[5] / 2)\r\n    \r\n    minx = min(minx, lbody_fab)\r\n    miny = min(miny, tbody_fab)\r\n    maxx = max(maxx, lbody_fab + wbody_fab)\r\n    maxy = max(maxy, tbody_fab + hbody_fab)\r\n    if style == \"screwleft\":\r\n        minx = min(minx, lscrew_fab)\r\n        miny = min(miny, tscrew_fab)\r\n        maxx = max(maxx, lscrew_fab + wscrew_fab)\r\n        maxy = max(maxy, tscrew_fab + hscrew_fab)\r\n\r\n    h_crt = (maxy - miny) + 2 * crt_offset\r\n    w_crt = (maxx - minx) + 2 * crt_offset\r\n    l_crt = minx - crt_offset\r\n    t_crt = miny - crt_offset\r\n    \r\n    pow_rat = \"\"\r\n    if R_POW > 0:\r\n        pow_rat = \"{0}W\".format(R_POW)\r\n        if (1 / R_POW == int(1 / R_POW)):\r\n            pow_rat = pow_rat + \" = 1/{0}W\".format(int(1 / R_POW))\r\n    \r\n    tgs = specialtags\r\n    tgs.append(class_name)\r\n    if len(pow_rat) > 0:\r\n        tgs.append(pow_rat)\r\n    \r\n    description = \"Potentiometer, \" + orientation\r\n    tags = \"Potentiometer \" + orientation\r\n    if shaft_hole:\r\n        description = description + \", shaft hole\"\r\n        tags = tags + \" hole\"\r\n    for t in tgs:\r\n        description = description + \", \" + t\r\n        tags = tags + \" \" + t\r\n    description = description + \", \" + add_description\r\n    \r\n    for n in name_additions: footprint_name = footprint_name + \"_\" + n\r\n    footprint_name = lib_name + \"_\" + \"_\".join(class_name.split()) + \"_\" + orientation.capitalize()\r\n    if shaft_hole: footprint_name = footprint_name + \"_Hole\"\r\n        \r\n    print(footprint_name)\r\n    \r\n    if script3d != \"\":\r\n        with open(script3d, \"a\") as myfile:\r\n\r\n            myfile.write(\"\\n\\n # {0}\\n\".format(footprint_name))\r\n            myfile.write(\"import FreeCAD\\n\")\r\n            myfile.write(\"import os\\n\")\r\n            myfile.write(\"import os.path\\n\\n\")\r\n            myfile.write(\"App.ActiveDocument.clearAll()\\n\")\r\n            line = 0\r\n            line += 1; script3d_writevariable(myfile, line, 'lbody_fab', min(lbody_fab+wbody_fab,lbody_fab)+offset[0])\r\n            line += 1; script3d_writevariable(myfile, line, 'tbody_fab', min(tbody_fab+hbody_fab,tbody_fab)+offset[1])\r\n            line += 1; script3d_writevariable(myfile, line, 'wbody_fab', math.fabs(wbody_fab))\r\n            line += 1; script3d_writevariable(myfile, line, 'hbody_fab', math.fabs(hbody_fab))\r\n            line += 1; script3d_writevariable(myfile, line, 'lscrew_fab', min(lscrew_fab+wscrew_fab,lscrew_fab)+offset[0])\r\n            line += 1; script3d_writevariable(myfile, line, 'tscrew_fab', min(tscrew_fab+hscrew_fab,tscrew_fab)+offset[1])\r\n            line += 1; script3d_writevariable(myfile, line, 'wscrew_fab', math.fabs(wscrew_fab))\r\n            line += 1; script3d_writevariable(myfile, line, 'hscrew_fab', math.fabs(hscrew_fab))\r\n            line += 1; script3d_writevariable(myfile, line, 'dscrew', dscrew)\r\n            line += 1; script3d_writevariable(myfile, line, 'wscrew', wscrew)\r\n            line += 1; script3d_writevariable(myfile, line, 'rmxtwo', rmx2)\r\n            line += 1; script3d_writevariable(myfile, line, 'rmytwo', rmy2)\r\n            line += 1; script3d_writevariable(myfile, line, 'rmxthree', rmx3)\r\n            line += 1; script3d_writevariable(myfile, line, 'rmythree', rmy3)\r\n            for p in padpos:\r\n                if p[0] == 1:\r\n                    line += 1;\r\n                    script3d_writevariable(myfile, line, 'padx', p[1])\r\n                    line += 1;\r\n                    script3d_writevariable(myfile, line, 'pady', p[2])\r\n            line += 1; script3d_writevariable(myfile, line, 'd_wire', ddrill-0.3)\r\n            line += 1; script3d_writevariable(myfile, line, 'height', height3d)\r\n            line += 1; script3d_writevariable(myfile, line, 'offsetx', offset[0])\r\n            line += 1; script3d_writevariable(myfile, line, 'offsety', offset[1])\r\n\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\\n\")\r\n            myfile.write(\"doc = FreeCAD.activeDocument()\\n\")\r\n            myfile.write(\"__objs__=[]\\n\")\r\n            myfile.write(\"for obj in doc.Objects:\t\\n\")\r\n            myfile.write(\"    if obj.ViewObject.Visibility:\\n\")\r\n            myfile.write(\"        __objs__.append(obj)\\n\")\r\n            myfile.write(\"\\nFreeCADGui.export(__objs__,os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.wrl\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"doc.saveCopy(os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.FCStd\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"print(\\\"created {0}\\\")\\n\".format(footprint_name))\r\n    \r\n    # init kicad footprint\r\n    kicad_mod = Footprint(footprint_name)\r\n    kicad_mod.setDescription(description)\r\n    kicad_mod.setTags(tags)\r\n    if SMD_pads:\r\n        kicad_mod.setAttribute('smd')\r\n    \r\n    kicad_modg = Translation(offset[0], offset[1])\r\n    kicad_mod.append(kicad_modg)\r\n    \r\n    # set general values\r\n    kicad_modg.append(Text(type='reference', text='REF**', at=[l_crt + w_crt / 2.0, t_crt - txt_offset], layer='F.SilkS'))\r\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[l_crt + w_crt / 2.0, t_crt + h_crt + txt_offset], layer='F.Fab'))\r\n    \r\n    # create FAB-layer\r\n    kicad_modg.append(RectLine(start=[lbody_fab, tbody_fab], end=[lbody_fab + wbody_fab, tbody_fab + hbody_fab], layer='F.Fab', width=lw_fab))\r\n    if style == \"screwleft\":\r\n        if wscrew > 0:\r\n            kicad_modg.append(RectLine(start=[lscrew_fab, tscrew_fab], end=[lscrew_fab + wscrew_fab, tscrew_fab + hscrew_fab], layer='F.Fab',width=lw_fab))\r\n            kicad_modg.append(Line(start=[lscrew_fab, tscrew_fab+hscrew_fab/2.0], end=[lscrew_fab + wscrew_fab/2.0, tscrew_fab + hscrew_fab/2.0], layer='F.Fab', width=lw_fab))\r\n        \r\n        # trimmer pot with rectangular body: place refdes on F.Fab centered in body\r\n        text_size = round(min(1, lbody_fab + wbody_fab, tbody_fab + hbody_fab), 2)\r\n        kicad_modg.append(Text(type='user', text='%R', at=[lbody_fab+wbody_fab/2.0, tbody_fab+hbody_fab/2.0], size=[text_size, text_size], layer='F.Fab'))\r\n    elif style == \"screwtop\":\r\n        # screw graphics are inside body somewhere, so determine where to place F.Fab ref des text\r\n        if (hbody_fab / 2.0 == tscrew_fab):\r\n            # screw is centered vertically in body, so place at top center of body\r\n            text_x = lbody_fab + wbody_fab / 2.0\r\n            text_y = tscrew_fab - wscrew_fab + 0.3\r\n            text_size = round(min(1, (hbody_fab - wscrew_fab) / 4.0), 2)\r\n        else:\r\n            # determine if screw is closer to left or right side of body, then place centered on other side of body\r\n            text_y = tbody_fab + hbody_fab / 2.0\r\n            if (lscrew_fab <= wbody_fab - lscrew_fab):\r\n                text_x = lscrew_fab + (wbody_fab - lscrew_fab) / 2.0\r\n                text_size = round(min(1, (wbody_fab - lscrew_fab) / 6.0), 2)\r\n            else:\r\n                text_x = lbody_fab + lscrew_fab / 2.0\r\n                text_size = round(min(1, lscrew_fab / 6.0), 2)\r\n\r\n        # trimmer pot top-mount with rectangular body: place refdes on F.Fab at location found above        \r\n        kicad_modg.append(Text(type='user', text='%R', at=[text_x, text_y], size=[text_size, text_size], layer='F.Fab'))\r\n        \r\n        if shaft_hole == False:\r\n            if screwstyle==\"slit\":\r\n                addSlitScrew(kicad_modg, lscrew_fab, tscrew_fab, wscrew_fab / 2.0, 'F.Fab', lw_fab)\r\n            else:\r\n                addCrossScrew(kicad_modg, lscrew_fab, tscrew_fab, wscrew_fab / 2.0, 'F.Fab', lw_fab)\r\n        \r\n    # build keepout for silkscreen\r\n    keepouts = []\r\n    for p in padpos:\r\n        if p[7] == Pad.SHAPE_CIRCLE:\r\n            keepouts = keepouts + addKeepoutRound(p[1], p[2], p[4] + 2 * lw_slk + 2 * slk_offset, p[5] + 2 * lw_slk + 2 * slk_offset)\r\n        else:\r\n            keepouts = keepouts + addKeepoutRect(p[1], p[2], p[4] + 2 * lw_slk + 2 * slk_offset, p[5] + 2 * lw_slk + 2 * slk_offset)\r\n    # debug_draw_keepouts(kicad_modg,keepouts)\r\n    \r\n    # create SILKSCREEN-layer\r\n    addRectWithKeepout(kicad_modg, lbody_slk, tbody_slk, wbody_slk, hbody_slk, 'F.SilkS', lw_slk, keepouts)\r\n    if style == \"screwleft\" and wscrew > 0:\r\n        addRectWithKeepout(kicad_modg, lscrew_slk, tscrew_slk, wscrew_slk, hscrew_slk, 'F.SilkS', lw_slk, keepouts)\r\n        addHLineWithKeepout(kicad_modg, lscrew_slk, lscrew_slk+wscrew_slk/2.0, tscrew_slk+hscrew_slk/2.0, 'F.SilkS', lw_slk, keepouts)\r\n    '''elif style == \"screwtop\":\r\n        if screwstyle == \"slit\":\r\n            addSlitScrewWithKeepouts(kicad_modg, lscrew_slk, tscrew_slk, wscrew_slk / 2.0, 'F.SilkS', lw_slk, keepouts)\r\n        else:\r\n            addCrossScrewWithKeepouts(kicad_modg, lscrew_slk, tscrew_slk, wscrew_slk / 2.0, 'F.SilkS', lw_slk, keepouts)'''\r\n\r\n    # create courtyard\r\n    kicad_mod.append(RectLine(start=[roundG(l_crt + offset[0], grid_crt), roundG(t_crt + offset[1], grid_crt)],\r\n                             end=[roundG(l_crt + w_crt + offset[0], grid_crt), roundG(t_crt + h_crt + offset[1], grid_crt)], layer='F.CrtYd', width=lw_crt))\r\n    \r\n    # create pads\r\n    for p in padpos:\r\n        if p[6] == Pad.TYPE_SMT:\r\n            kicad_modg.append(Pad(number=p[0], type=p[6], shape=p[7], at=[p[1], p[2]], size=[p[4], p[5]], drill=p[3],\r\n                                  layers=['F.Cu', 'F.Paste', 'F.Mask']))\r\n        else:\r\n            kicad_modg.append(Pad(number=p[0], type=p[6], shape=p[7], at=[p[1], p[2]], size=[p[4], p[5]], drill=p[3],\r\n                                  layers=['*.Cu', '*.Mask']))\r\n    \r\n    # add model\r\n    if (has3d != 0):\r\n        if SMD_pads:\r\n            kicad_modg.append(Model(filename=\"${KISYS3DMOD}/\" + lib_name + \"_SMD.3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=r_3d))\r\n        else:\r\n            kicad_modg.append(Model(filename=\"${KISYS3DMOD}/\" + lib_name + \"_THT.3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=r_3d))\r\n    \r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n    \r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(footprint_name + '.kicad_mod')\r\n'''\rif __name__ == '__main__':\r\n\r\n    # handle arguments\r\n    parser = argparse.ArgumentParser()\r\n    \r\n    # general parameters (used for 'horizontal' types)\r\n    parser.add_argument('type', help='type of potentiometer (horizontal, vertical, spindle)', nargs='?', choices=['horizontal', 'vertical', 'spindle'])\r\n    parser.add_argument('--class_name', help='class_name: manufacturer and MPN like \"Bourns 3214W\" (str)', nargs='?', required=True)\r\n    parser.add_argument('--wbody', help='wbody: body length (float)', type=float, nargs='?', required=True)\r\n    parser.add_argument('--hbody', help='hbody: body height (float)', type=float, nargs='?', required=True)\r\n    parser.add_argument('--wscrew', help='wscrew: collar length (float)', type=float, nargs='?')\r\n    parser.add_argument('--dscrew', help='dscrew: collar diameter (float)', type=float, nargs='?', required=True)\r\n    parser.add_argument('--wshaft', help='wshaft: shaft length (float)', type=float, nargs='?')\r\n    parser.add_argument('--dshaft', help='dshaft: shaft diameter (float)', type=float, nargs='?')\r\n    parser.add_argument('--style', help='style: type of pot from \"normal\" or \"trimmer\" [default = \"normal\"] (str) style: location of screw from \"screwleft\" or \"screwtop\" [default = \"screwleft\"] (str)', nargs='?', required=True)\r\n    parser.add_argument('--pinxoffset', help='pinxoffset: distance from face of body to first column of pins [default = 0] (float)', type=float, nargs='?', default=0)\r\n    parser.add_argument('--pinyoffset', help='pinyoffset: distance from top of body to first row of pins [default = 0] (float)', type=float, nargs='?', default=0)\r\n    parser.add_argument('--pins', help='pins: number of pins; \"trimmer\" style can only support 3 pins [default = 3] (int)', type=int, nargs='?', default=3)\r\n    parser.add_argument('--rmx', help='rmx: column spacing of pins [default = 5.08] (float)', type=float, nargs='?')\r\n    parser.add_argument('--rmy', help='rmy: row (or vertical) spacing of pins [default = 5.08] (float)', type=float, nargs='?')\r\n    parser.add_argument('--ddrill', help='ddrill: drill hole diameter [default = 1.5] (float)', type=float, nargs='?', required=True)\r\n    parser.add_argument('--R_POW', help='R_POW: power rating of pot with zero being default [default = 0] (float)', type=float, nargs='?', default=0)\r\n    parser.add_argument('--x_3d', help='x_3d: 3D model location [default = [0, 0, 0]] (list of floats)', nargs=3)\r\n    parser.add_argument('--s_3d', help='s_3d: 3D model scaling [default = [1 / 2.54, 1 / 2.54, 1 / 2.54]] (list of floats)', nargs=3)\r\n    parser.add_argument('--r_3d', help='r_3d: 3D model rotation [default = [0, 0, 0]] (list of floats)', nargs=3)\r\n    parser.add_argument('--has3d', help='has3d: presence of 3D model [default = 1] (bool)', type=bool, nargs='?', default=1)\r\n    parser.add_argument('--specialtags', help='specialtags: keywords that will be comma-delimited [default = []] (list of strs)', nargs='*')\r\n    parser.add_argument('--add_description', help='add_description: descriptive text [default = \"\"] (str)', nargs='?', default=\"\")\r\n    parser.add_argument('--lib_name', help='lib_name: library name [default = \"Potentiometer\"] (str)', nargs='?', default=\"Potentiometer\")\r\n    parser.add_argument('--name_additions', help='name_additions: extra text for footprint name that will be underscore-delimited [default = \"\"] (str)', nargs='?', default=\"\")\r\n    parser.add_argument('--script3d', help='script3d: script to kick off 3D model generation in FreeCad [default = \"\"] (str)', nargs='?', default=\"\")\r\n    parser.add_argument('--height3d', help='height3d: height of 3D model [default = 10] (float)', type=float, nargs='?', default=10)\r\n    parser.add_argument('--screwzpos', help='screwzpos: height of collar above bottom of body [default = 5] (float)', type=float, nargs='?', default=5)\r\n    parser.add_argument('--mh_count', help='mh_count: number of mounting holes; 1, 2, or 4 are supported [default = 0] (int)', type=int, nargs='?', default=0)\r\n    parser.add_argument('--mh_ddrill', help='mh_ddrill: drill hole diameter of mounting holes [default = 1.5] (float)', type=float, nargs='?', default=0)\r\n    parser.add_argument('--mh_rmx', help='mh_rmx: column spacing of mounting holes [default = 0] (float)', type=float, nargs='?', default=0)\r\n    parser.add_argument('--mh_rmy', help='mh_rmy: row spacing of mounting holes [default = 15] (float)', type=float, nargs='?', default=0)\r\n    parser.add_argument('--mh_xoffset', help='mh_xoffset: distance from face of body to first column of mounting holes [default = 0] (float)', type=float, nargs='?', default=0)\r\n    parser.add_argument('--mh_yoffset', help='mh_yoffset: distance from top of body to first row of mounting holes [default = 0] (float)', type=float, nargs='?', default=0)\r\n    \r\n    # additional parameters for 'vertical' types\r\n    parser.add_argument('--screwstyle', help='screwstyle: screw style from \"none\", \"slit\", or \"cross\" [default = \"slit\"] (str)', nargs='?')\r\n    parser.add_argument('--d_body', help='d_body: diameter of body for circular pot [default = 0] (float)', type=float, nargs='?')\r\n    parser.add_argument('--c_ddrill', help='c_ddrill: drill diameter to fit collar or zero for no hole [default = 0] (float)', type=float, nargs='?', default=0)\r\n    parser.add_argument('--c_offsetx', help='c_offsetx: distance from left side of body to collar center [default = 0] (float)', type=float, nargs='?')\r\n    parser.add_argument('--c_offsety', help='c_offsety:: distance from top of body to collar center [default = 0] (float)', type=float, nargs='?')\r\n    parser.add_argument('--shaft_hole', help='shaft_hole: places hole under pot for shaft through PCB [default = True] (bool)', type=bool, nargs='?', default=False)\r\n    parser.add_argument('--SMD_pads', help='SMD_pads: allows using SMD pads [default = False] (bool)', type=bool, nargs='?', default=False)\r\n    parser.add_argument('--SMD_padsize', help='SMD_padsize: X and Y dimensions of SMD pads in [X, Y] format [default = []] (list of floats)', type=float, nargs=2)\r\n    parser.add_argument('--SMD_type', help='SMD_type: allow specifying the SMD pad layout from below options [default = \"3-5\"] (str) \"3-5\": 5 pin pot with 3 pins on left side and 2 pins on right side', nargs='?')\r\n    parser.add_argument('--mh_smd', help='mh_smd: allows using SMD mounting holes [default = False] (bool)', type=bool, nargs='?', default=False)\r\n    parser.add_argument('--mh_padsize', help='mh_padsize: X and Y dimensions of SMD mounting holes in [X, Y] format [default = []] (list of floats)', type=float, nargs=2)\r\n    parser.add_argument('--mh_nopads', help='mh_nopads: allows selecting the presence of mounting holes [default = False] (bool)', type=bool, nargs='?', default=False)\r\n    \r\n    # additional parameters for 'spindle' types (may not use all parameters above)\r\n    parser.add_argument('--rmx2', help='rmx2: distance from pin 1 left to pin 2 (float)', type=float, nargs='?')\r\n    parser.add_argument('--rmy2', help='rmy2: distance from pin 1 up to pin 2 (float)', type=float, nargs='?')\r\n    parser.add_argument('--rmx3', help='rmx3: distance from pin 1 left to pin 3 (float)', type=float, nargs='?')\r\n    parser.add_argument('--rmy3', help='rmy3: distance from pin 1 up to pin 3 (float)', type=float, nargs='?')\r\n    parser.add_argument('--screwxoffset', help='screwxoffset: distance from left side of body to screw for top screw types [default = 0] (float)', type=float, nargs='?', default=0)\r\n    parser.add_argument('--screwyoffset', help='screwyoffset: distance from top of body to center of screw [default = 0] (float)', type=float, nargs='?', default=0)\r\n    \r\n    parser.add_argument('-v', '--verbose', help='show extra information while generating the footprint', action='store_true')\r\n    args = parser.parse_args()\r\n    print('\\n')\r\n    print(args)\r\n    \r\n    # some special handling of arguments, especially list types\r\n    '''if not args.x_3d:\r\n        x_3d = [0, 0, 0]\r\n    else:\r\n        x_3d = args.x_3d\r\n    \r\n    if not args.s_3d:\r\n        s_3d = [1, 1, 1]\r\n    else:\r\n        s_3d = args.s_3d\r\n    \r\n    if not args.r_3d:\r\n        r_3d = [0, 0, 0]\r\n    else:\r\n        r_3d = args.r_3d\r\n    \r\n    if not args.specialtags:\r\n        specialtags = []\r\n    else:\r\n        specialtags = args.specialtags\r\n    \r\n    if not args.name_additions:\r\n        name_additions = []\r\n    else:\r\n        name_additions = args.name_additions'''\r\n        \r\n    # for troubleshooting, below are shell commands to generate a footprint in various ways:\r\n    # full: all arguments are given with non-default values\r\n    # miss1: one required argument checked by argparse is missing\r\n    # miss2: one required argument not checked by argparse is missing\r\n    # minimal: only required arguments are given\r\n    \r\n    #python footprint_scripts_potentiometers.py \"horizontal\" --class_name \"Hfull\" --wbody 9.3 --hbody 16.9 --wscrew 6 --dscrew 7 --wshaft 44 --dshaft 4 --style \"normal\" --pinxoffset 6.3 --pinyoffset 3.45 --pins 3 --rmx 5 --rmy 5 --ddrill 1.3 --R_POW 1 --x_3d 0.7 0.8 0.9 --s_3d 0.4 0.5 0.6 --r_3d 0.1 0.2 0.3 --has3d 1 --specialtags \"tag1\" \"tag2\" --add_description \"http://www.omeg.co.uk/pc6bubrc.htm\" --lib_name \"Potentiometer\" --name_additions \"addition1 addition2\" --script3d \"pots_ver.py\" --height3d 21 --screwzpos 12.5 --mh_ddrill 1.1 --mh_count 2 --mh_rmx 1 --mh_rmy 0.5 --mh_xoffset 0.2 --mh_yoffset 11\r\n    #python footprint_scripts_potentiometers.py \"horizontal\" --class_name \"Hmiss1\" --hbody 16.9 --wscrew 6 --dscrew 7 --wshaft 44 --dshaft 4 --style \"normal\" --pinxoffset 6.3 --pinyoffset 3.45 --pins 3 --rmx 5 --rmy 5 --ddrill 1.3 --R_POW 1 --x_3d 0.7 0.8 0.9 --s_3d 0.4 0.5 0.6 --r_3d 0.1 0.2 0.3 --has3d 1 --specialtags \"tag1\" \"tag2\" --add_description \"http://www.omeg.co.uk/pc6bubrc.htm\" --lib_name \"Potentiometer\" --name_additions \"addition1 addition2\" --script3d \"pots_ver.py\" --height3d 21 --screwzpos 12.5 --mh_ddrill 1.1 --mh_count 2 --mh_rmx 1 --mh_rmy 0.5 --mh_xoffset 0.2 --mh_yoffset 11\r\n    #python footprint_scripts_potentiometers.py \"horizontal\" --class_name \"Hmiss2\" --wbody 9.3 --hbody 16.9 --wscrew 6 --dscrew 7 --wshaft 44 --dshaft 4 --style \"normal\" --pinxoffset 6.3 --pinyoffset 3.45 --pins 3 --rmy 5 --ddrill 1.3 --R_POW 1 --x_3d 0.7 0.8 0.9 --s_3d 0.4 0.5 0.6 --r_3d 0.1 0.2 0.3 --has3d 1 --specialtags \"tag1\" \"tag2\" --add_description \"http://www.omeg.co.uk/pc6bubrc.htm\" --lib_name \"Potentiometer\" --name_additions \"addition1 addition2\" --script3d \"pots_ver.py\" --height3d 21 --screwzpos 12.5 --mh_ddrill 1.1 --mh_count 2 --mh_rmx 1 --mh_rmy 0.5 --mh_xoffset 0.2 --mh_yoffset 11\r\n    #python footprint_scripts_potentiometers.py \"horizontal\" --class_name \"Hmin\" --wbody 9.3 --hbody 16.9 --wscrew 6 --dscrew 7 --wshaft 44 --dshaft 4 --style \"normal\" --rmx 5 --rmy 5 --ddrill 1.3\r\n    \r\n    #python footprint_scripts_potentiometers.py \"vertical\" --class_name \"Vfull\" --wbody 8 --hbody 16 --d_body 0 --dshaft 6 --dscrew 10 --c_ddrill 10.5 --c_offsetx 10 --c_offsety 8 --pinxoffset 0.5 --pinyoffset 3 --pins 3 --rmx 7.5 --rmy 5 --ddrill 1.3 --specialtags [] --add_description \"http://www.piher-nacesa.com/pdf/20-PC16v03.pdf\" --lib_name \"Potentiometer\" --name_additions \"addition\" --script3d \"pots_hor_below.py\" --height3d 20.5\r\n    #python footprint_scripts_potentiometers.py \"vertical\" --class_name \"Vmiss\" --hbody 16 --d_body 0 --dshaft 6 --dscrew 10 --c_ddrill 10.5 --c_offsetx 10 --c_offsety 8 --pinxoffset 0.5 --pinyoffset 3 --pins 3 --rmx 7.5 --rmy 5 --ddrill 1.3 --specialtags [] --add_description \"http://www.piher-nacesa.com/pdf/20-PC16v03.pdf\" --lib_name \"Potentiometer\" --name_additions \"\" --script3d \"pots_hor_below.py\" --height3d 20.5\r\n    #python footprint_scripts_potentiometers.py \"vertical\"--class_name \"Vmin\" --wbody 8 --hbody 16 --d_body 0 --dshaft 6 --dscrew 10 --c_ddrill 10.5 --c_offsetx 10 --c_offsety 8 --pinxoffset 0.5 --pinyoffset 3 --pins 3 --rmx 7.5 --rmy 5 --ddrill 1.3\r\n    \r\n    #python footprint_scripts_potentiometers.py \"spindle\" --class_name \"Sfull\" --ddrill 1 --wbody 19.3 --hbody 4.06 --pinxoffset 16 --pinyoffset 3.3 --rmx2 -7.62 --rmy2 -2.54 --rmx3 -12.7 --rmy3 0 --dscrew 3 --wscrew 1.52 --screwxoffset 0 --screwyoffset 2.03 --style=style --screwstyle \"slit\" --SMD_pads True --SMD_padsize 2.5 2.5 --add_description \"https://www.bourns.com/pdfs/3005.pdf\" --lib_name \"Potentiometer\" --script3d \"trimmer_screwleft.py\" --height3d 7.87\r\n\r\n    # ensure all required attributes for pot type are given and, if so, pass arguments to function\r\n    # note that the argparse interface traps and reports errors for the 'type' parameter and all 'horizontal' type arguments\r\n    # for 'vertical' and 'spindle' types, argument presence is checked but argument type is not\r\n    if (args.type == \"horizontal\"):\r\n        if (None in [args.wscrew, args.wshaft, args.dshaft, args.rmx, args.rmy]):\r\n            sys.exit(\"Error: All required arguments were not provided for a horizontal potentiometer\")\r\n        else:\r\n            '''if not args.style:\r\n                style = \"normal\"\r\n            else:\r\n                style = args.style'''\r\n            \r\n            makePotentiometerHorizontal(class_name=args.class_name, wbody=args.wbody, hbody=args.hbody, wscrew=args.wscrew, dscrew=args.dscrew,\r\n                            wshaft=args.wshaft, dshaft=args.dshaft, style=args.style, pinxoffset=args.pinxoffset, pinyoffset=args.pinyoffset,\r\n                            pins=args.pins, rmx=args.rmx, rmy=args.rmy, ddrill=args.ddrill, R_POW=args.R_POW, x_3d=args.x_3d, s_3d=args.s_3d, r_3d=args.r_3d, has3d=args.has3d,\r\n                            specialtags=args.specialtags, add_description=args.add_description, lib_name=args.lib_name, name_additions=args.name_additions,\r\n                            script3d=args.script3d, height3d=args.height3d, screwzpos=args.screwzpos, mh_ddrill=args.mh_ddrill, mh_count=args.mh_count,\r\n                            mh_rmx=args.mh_rmx, mh_rmy=args.mh_rmy, mh_xoffset=args.mh_xoffset, mh_yoffset=args.mh_yoffset)\r\n    elif (args.type == \"vertical\"):\r\n        if (None in [args.screwstyle, args.d_body, args.dshaft, args.c_offsetx, args.c_offsety, args.rmx, args.rmy, args.SMD_type]):\r\n            sys.exit(\"Error: Argument(s) missing for a vertical potentiometer (screwstyle, d_body, dshaft, c_offsetx, c_offsety, rmx, rmy, SMD_type)\")\r\n        else:\r\n            makePotentiometerVertical(class_name=args.class_name, wbody=args.wbody, hbody=args.hbody, screwstyle=args.screwstyle, style=args.style,\r\n                            d_body=args.d_body, dshaft=args.dshaft, dscrew=args.dscrew, c_ddrill=args.c_ddril, c_offsetx=args.c_offsetx,\r\n                            c_offsety=args.c_offsety, pinxoffset=args.pinxoffset, pinyoffset=args.pinyoffset, pins=args.pins, rmx=args.rmx, rmy=args.rmy,\r\n                            ddrill=args.ddrill, shaft_hole=args.shaft_hole, SMD_pads=args.SMD_pads, SMD_padsize=args.SMD_padsize, SMD_type=args.SMD_type, R_POW=args.R_POW,\r\n                            x_3d=x_3d, s_3d=s_3d, r_3d=r_3d, has3d=args.has3d, specialtags=specialtags, add_description=args.add_description, lib_name=args.lib_name,\r\n                            name_additions=name_additions, script3d=args.script3d, height3d=args.height3d, mh_ddrill=args.mh_drill, mh_count=args.mh_count,\r\n                            mh_rmx=args.mh_rmx, mh_rmy=args.mh_rmy, mh_xoffset=args.mh_xoffset, mh_yoffset=args.mh_yoffset, mh_smd=args.mh_smd,\r\n                            mh_padsize=args.mh_padsize, mh_nopads=args.mh_nopads)\r\n    elif (args.type == \"spindle\"):\r\n        if (None in [args.rmx2, args.rmy2, args.rmx3, args.rmy3, args.wscrew, args.screwstyle]):\r\n            sys.exit(\"Error: Argument(s) missing for a spindle potentiometer (rmx2, rmy2, rmx3, rmy3, wscrew, screwstyle)\")\r\n        else:\r\n            makeSpindleTrimmer(class_name=args.class_name, wbody=args.wbody, hbody=args.hbody, pinxoffset=args.pinxoffset, pinyoffset=args.pinyoffset,\r\n                            rmx2=args.rmx2, rmy2=args.rmy2, rmx3=args.rmx3, rmy3=args.rmy3, dscrew=args.dscrew, ddrill=args.ddrill, wscrew=args.wscrew,\r\n                            screwxoffset=args.screwxoffset, screwyoffset=args.screwyoffset, style=args.style, screwstyle=args.screwstyle, SMD_pads=args.SMD_pads,\r\n                            SMD_padsize=args.SMD_padsize, R_POW=args.R_POW, x_3d=x_3d, s_3d=s_3d, r_3d=r_3d, has3d=args.has3d, specialtags=specialtags,\r\n                            add_description=args.add_description, lib_name=args.lib_name, name_additions=name_additions, script3d=args.script3d, height3d=args.height3d)\r\n'''\r\n"
  },
  {
    "path": "scripts/tools/footprint_scripts_resistorlike.py",
    "content": "#!/usr/bin/env python\r\n\r\nimport sys\r\nimport os\r\nimport math\r\n\r\n# ensure that the kicad-footprint-generator directory is available\r\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\r\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\r\n\r\nfrom KicadModTree import *  # NOQA\r\nfrom drawing_tools import *\r\nfrom footprint_global_properties import *\r\n\r\nslk_offset=lw_slk\r\n\r\n# classnamefancy -> long form of class name for description field\r\n# part names uses short/ordinary classname\r\ndef getFancyClassName(classname=\"R\"):\r\n    if (classname == \"R\"):\r\n        classnamefancy = \"Resistor\"\r\n    elif (classname == \"D\"):\r\n        classnamefancy = \"Diode\"\r\n    elif (classname == \"L\"):\r\n        classnamefancy = \"Inductor\"\r\n    else:\r\n        classnamefancy = classname\r\n    return classnamefancy\r\n\r\n# returns a string for the description for the power rating\r\ndef getPowRat(R_POW=0.0):\r\n    pow_rat = \"\"\r\n    if not (R_POW==int(R_POW)):\r\n        R_POW = round(R_POW, 3)\r\n    if R_POW > 0.0:\r\n        pow_rat=\"{0}W\".format(R_POW)\r\n        if (1.0/R_POW==int(1.0/R_POW)) and (R_POW<1.0):\r\n            pow_rat=pow_rat+\" = 1/{0}W\".format(int(1.0/R_POW))\r\n        else:\r\n            pow_rat=\"{0}W\".format(R_POW)\r\n    return pow_rat\r\n\r\n# simple axial round (type=\"cyl\") / box (type=\"box\") / bare metal wire (type=\"bridge\") resistor, horizontally mounted\r\n# optionally with additional shunt leads: hasShuntPins=True, shuntPinsRM=DISTANCE\r\n# deco=\"none\"/\"elco\"/\"diode\"\r\n\r\ndef makeResistorAxialHorizontal(seriesname, rm, rmdisp, w, d, ddrill, R_POW, type=\"cyl\", d2=0, hasShuntPins=False, shuntPinsRM=0, x_3d=[0,0,0], s_3d=[1, 1, 1], has3d=1, specialfpname=\"\", specialtags=[], add_description=\"\", classname=\"R\", lib_name=\"Resistor_THT\", name_additions=[], deco=\"none\", script3d=\"\"):\r\n    padx=2*ddrill\r\n    pady=padx\r\n\r\n    pad1style=Pad.SHAPE_CIRCLE\r\n    polsign_slk=[]\r\n\r\n    if deco==\"elco\" or deco==\"cp\" or deco==\"tantal\" or deco==\"diode\":\r\n        pad1style=Pad.SHAPE_RECT\r\n\r\n    l_fab=(rm-w)/2\r\n    l_dbar_fab=l_fab\r\n    t_fab=-d/2\r\n    h_fab=d\r\n    w_fab=w\r\n    h_slk=d+2*slk_offset\r\n    w_slk=w+2*slk_offset\r\n    l_slk=l_fab-slk_offset\r\n    l_dbar_slk=l_dbar_fab\r\n    r_slk=l_slk+w_slk\r\n    t_slk=-h_slk/2\r\n    w_crt=rm+padx+2*crt_offset\r\n    h_crt=max(d, pady)+2*crt_offset\r\n    l_crt=min(l_fab, -padx/2)-crt_offset\r\n    t_crt=min(-d/2, -pady/2)-crt_offset\r\n\r\n    # if seriesname == \"DO-34_SOD68\":\r\n    #     print (\"w{}, h{}, l{}, t{}\".format(w_crt, h_crt, l_crt, t_crt))\r\n\r\n    fabtxt_size=1;\r\n    fabtxt_thick=0.15\r\n    if w_fab<=5 or h_fab<=1:\r\n        fabtxt_size=min(h_fab*0.8, w_fab/5)\r\n        fabtxt_thick=0.15*fabtxt_size\r\n    fabtxt_size=max(0.25,fabtxt_size)\r\n    fabtxt_thick=max(0.15/4,fabtxt_thick)\r\n\r\n    add_plus_sign_slk = False\r\n    if deco==\"elco\" or deco==\"cp\" or deco==\"tantal\":\r\n        polsign_slk=[l_slk+padx*0.75,-pady*0.75/2,padx*0.75,pady*0.75]\r\n        add_plus_sign_slk = True\r\n\r\n    if deco==\"diode\":\r\n        l_dbar_fab=l_fab+w_fab*0.15\r\n        l_dbar_slk=l_dbar_fab\r\n\r\n    snfp=\"\"\r\n    sn=\"\"\r\n    snt=\"\"\r\n    if len(seriesname)>0:\r\n        snfp=\"_\"+seriesname\r\n        sn=\", \"+seriesname+\" series\"\r\n        snt = \" \" + seriesname + \" series\"\r\n\r\n    pow_rat = getPowRat(R_POW)\r\n\r\n    classnamefancy = getFancyClassName(classname)\r\n\r\n    fnpins=\"_P{0:0.2f}mm\".format(rmdisp)\r\n    if hasShuntPins:\r\n        fnpins = \"_PS{0:0.2f}mm_P{1:0.2f}mm\".format(shuntPinsRM,rmdisp)\r\n    dimdesc=\"length*diameter={0}*{1}mm^2\".format(w, d)\r\n    dimdesct = \"length {0}mm diameter {1}mm\".format(w, d)\r\n    if deco==\"diode\":\r\n        footprint_name=classname+snfp+fnpins+\"_Horizontal\"\r\n    else:\r\n        footprint_name=classname+\"{3}_L{1:0.1f}mm_D{2:0.1f}mm{0}_Horizontal\".format(fnpins,w,d,snfp)\r\n\r\n    if type==\"box\":\r\n        footprint_name = classname+\"{4}_L{3:0.1f}mm_W{1:0.1f}mm{0}\".format(fnpins, d,d2,w, snfp)\r\n        dimdesc = \"length*width*height={0}*{1}*{1}mm^3\".format(w,d, d2)\r\n        dimdesct = \"length {0}mm width {1}mm height {1}mm\".format(w, d, d2)\r\n        description=classnamefancy+\"{3}, Box, pin pitch={0}mm, {1}, {2}\".format(rm, pow_rat, dimdesc,sn)\r\n        tags=classnamefancy+\"{3} Box pin pitch {0}mm {1} {2}\".format(rm, pow_rat, dimdesct, snt)\r\n    elif type==\"bridge\":\r\n        footprint_name = classname+\"{3}_L{2:0.1f}mm_W{1:0.1f}mm{0}\".format(fnpins, d,w, snfp)\r\n        dimdesc = \"length*width={0}*{1}mm^2\".format(w,d)\r\n        dimdesct = \"length {0}mm width {1}mm \".format(w, d)\r\n        description=classnamefancy+\"{3}, Bare Metal Strip/Wire, Horizontal, pin pitch={0}mm, {1}, {2}\".format(rm, pow_rat, dimdesc,sn)\r\n        tags=classnamefancy+\"{3} Bare Metal Strip Wire Horizontal pin pitch {0}mm {1} {2}\".format(rm, pow_rat, dimdesct, snt)\r\n    else:\r\n        description=classnamefancy+\"{3}, Axial, Horizontal, pin pitch={0}mm, {1}, {2}\".format(rm, pow_rat, dimdesc,sn)\r\n        tags=classnamefancy+\"{3} Axial Horizontal pin pitch {0}mm {1} {2}\".format(rm, pow_rat, dimdesct, snt)\r\n\r\n\r\n    if hasShuntPins:\r\n        description = description + \", shunt pin pitch = {0:0.2f}mm\".format(shuntPinsRM)\r\n        tags = tags + \" shunt pin pitch {0:0.2f}mm\".format(shuntPinsRM)\r\n\r\n    for t in specialtags:\r\n        description=description+\", \"+t\r\n        tags = tags + \" \" + t\r\n    if (specialfpname!=\"\"):\r\n        footprint_name=specialfpname;\r\n\r\n    if len(add_description) > 0:\r\n        description = description + \", \" + add_description\r\n\r\n    for n in name_additions:\r\n        if len(n)>0:\r\n            footprint_name=footprint_name+\"_\"+n\r\n\r\n    print(footprint_name)\r\n\r\n\r\n    if script3d!=\"\":\r\n        with open(script3d, \"a\") as myfile:\r\n            myfile.write(\"\\n    \\\"{0}\\\" : Params(# from Jan Kriege's 3d models\\n\".format(footprint_name))\r\n            myfile.write(\"        L = {:0.2f}, # Body Length\\n\".format(w))\r\n            myfile.write(\"        D = {:0.2f}, # Body Diameter\\n\".format(d))\r\n            myfile.write(\"        d = {:0.2f}, # Lead Diameter\\n\".format(ddrill-0.3))\r\n            myfile.write(\"        F = {:0.2f}, # Lead Seperation\\n\".format(rm))\r\n            myfile.write(\"        ll = 2.0, # Lead Length\\n\")\r\n            myfile.write(\"        bs = 0.0, # Board Seperation\\n\")\r\n\r\n            myfile.write(\"        modelName = '{0}', # Modelname\\n\".format(footprint_name))\r\n            myfile.write(\"        rotation = 0, # Rotation\\n\")\r\n            myfile.write(\"        dest_dir_prefix = '../Capacitors_THT.3dshapes/', # Destination\\n\")\r\n            myfile.write(\"    ),\\n\")\r\n            #Jans' 3D script\r\n            '''\r\n            myfile.write(\"\\n\\n # {0}\\n\".format(footprint_name))\r\n            myfile.write(\"import FreeCAD\\n\")\r\n            myfile.write(\"import os\\n\")\r\n            myfile.write(\"import os.path\\n\\n\")\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B4', '0.02')\\n\")\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"# L\\nApp.ActiveDocument.Spreadsheet.set('B1', '{0}')\\n\".format(w) )\r\n            myfile.write(\"# d\\nApp.ActiveDocument.Spreadsheet.set('B2', '{0}')\\n\".format(d))\r\n            myfile.write(\"# d2\\nApp.ActiveDocument.Spreadsheet.set('C2', '{0}')\\n\".format(d2))\r\n            myfile.write(\"# RM\\nApp.ActiveDocument.Spreadsheet.set('B3', '{0}')\\n\".format(rm))\r\n            myfile.write(\"# shuntPinsRM\\nApp.ActiveDocument.Spreadsheet.set('C3', '{0}')\\n\".format(shuntPinsRM))\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B4', '{0}')\\n\".format(ddrill-0.3))\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"doc = FreeCAD.activeDocument()\\n\")\r\n            myfile.write(\"__objs__=[]\\n\")\r\n            myfile.write(\"for obj in doc.Objects:\t\\n\")\r\n            myfile.write(\"    if obj.ViewObject.Visibility:\\n\")\r\n            myfile.write(\"        __objs__.append(obj)\\n\")\r\n            myfile.write(\"\\nFreeCADGui.export(__objs__,os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.wrl\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"doc.saveCopy(os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.FCStd\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"print(\\\"created {0}\\\")\\n\".format(footprint_name))\r\n            '''\r\n\r\n\r\n\r\n    # init kicad footprint\r\n    kicad_mod = Footprint(footprint_name)\r\n    kicad_mod.setDescription(description)\r\n    kicad_mod.setTags(tags)\r\n\r\n    # set general values\r\n    kicad_mod.append(Text(type='reference', text='REF**', at=[rm/2, t_slk-txt_offset], layer='F.SilkS'))\r\n    kicad_mod.append(Text(type='value', text=footprint_name, at=[rm/2, h_slk/2+txt_offset], layer='F.Fab'))\r\n    if deco==\"diode\":\r\n        kicad_mod.append(Text(type='user', text='%R', at=[rm/2+w_fab*0.15/2, 0], layer='F.Fab', size=[fabtxt_size, fabtxt_size], thickness=fabtxt_thick))\r\n    else:\r\n        kicad_mod.append(Text(type='user', text='%R', at=[rm/2, 0], layer='F.Fab', size=[fabtxt_size, fabtxt_size], thickness=fabtxt_thick))\r\n\r\n    # create FAB-layer\r\n    if deco==\"elco\" or deco==\"cp\" or deco==\"tantal\":\r\n        kicad_mod.append(Line(start=[l_fab, t_fab], end=[l_fab, t_fab+d], layer='F.Fab', width=lw_fab))\r\n        kicad_mod.append(Line(start=[l_fab+w, t_fab], end=[l_fab+w, t_fab+d], layer='F.Fab', width=lw_fab))\r\n        kicad_mod.append(PolygoneLine(polygone=[[l_fab, t_fab], [polsign_slk[0], t_fab], [polsign_slk[0]+polsign_slk[2]/2, t_fab+polsign_slk[3]/2], [polsign_slk[0]+polsign_slk[2], t_fab],[l_fab+w, t_fab]], layer='F.Fab', width=lw_fab))\r\n        kicad_mod.append(PolygoneLine(polygone=[[l_fab, t_fab+d], [polsign_slk[0], t_fab+h_fab], [polsign_slk[0]+polsign_slk[2]/2, t_fab+h_fab-polsign_slk[3]/2], [polsign_slk[0]+polsign_slk[2], t_fab+h_fab],[l_fab+w, t_fab+d]], layer='F.Fab', width=lw_fab))\r\n    else:\r\n        kicad_mod.append(RectLine(start=[l_fab, t_fab], end=[l_fab+w, t_fab+d], layer='F.Fab', width=lw_fab))\r\n    if type != \"bridge\":\r\n        kicad_mod.append(Line(start=[0, 0], end=[l_fab, 0], layer='F.Fab', width=lw_fab))\r\n        kicad_mod.append(Line(start=[rm, 0], end=[l_fab+w, 0], layer='F.Fab', width=lw_fab))\r\n    if len(polsign_slk)==4:\r\n        addPlusWithKeepout(kicad_mod, polsign_slk[0],polsign_slk[1], polsign_slk[2],polsign_slk[3], 'F.Fab', lw_fab, [], 0.05)\r\n    if deco==\"diode\":\r\n        kicad_mod.append(Line(start=[l_dbar_fab, t_fab], end=[l_dbar_fab, t_fab+h_fab], layer='F.Fab', width=lw_fab))\r\n        kicad_mod.append(Line(start=[l_dbar_fab+lw_fab, t_fab], end=[l_dbar_fab+lw_fab, t_fab+h_fab], layer='F.Fab', width=lw_fab))\r\n        kicad_mod.append(Line(start=[l_dbar_fab-lw_fab, t_fab], end=[l_dbar_fab-lw_fab, t_fab+h_fab], layer='F.Fab', width=lw_fab))\r\n\r\n    # create SILKSCREEN-layer\r\n    if add_plus_sign_slk:\r\n        polsign_size = padx*0.75\r\n        # (((d_fab-polsign_size)/2.0-polsign_size/10.0)\r\n        polsign_pos_x = l_slk-padx/2.\r\n        polsign_pos_y = -pady-min_pad_distance\r\n        kicad_mod.append(Line(start=[polsign_pos_x-polsign_size/2., polsign_pos_y], end=[polsign_pos_x+polsign_size/2.,polsign_pos_y], layer='F.SilkS', width=lw_slk))\r\n        kicad_mod.append(Line(start=[polsign_pos_x, polsign_pos_y-polsign_size/2.], end=[polsign_pos_x,polsign_pos_y+polsign_size/2.], layer='F.SilkS', width=lw_slk))\r\n    if deco==\"elco\" or deco==\"cp\" or deco==\"tantal\":\r\n        kicad_mod.append(Line(start=[l_slk, t_slk], end=[l_slk, t_slk+h_slk], layer='F.SilkS', width=lw_slk))\r\n        kicad_mod.append(Line(start=[l_slk+w_slk, t_slk], end=[l_slk+w_slk, t_slk+h_slk], layer='F.SilkS', width=lw_slk))\r\n        kicad_mod.append(PolygoneLine(polygone=[[l_slk, t_slk], [polsign_slk[0], t_slk], [polsign_slk[0]+polsign_slk[2]/2, t_slk+polsign_slk[3]/2], [polsign_slk[0]+polsign_slk[2], t_slk],[l_slk+w_slk, t_slk]], layer='F.SilkS', width=lw_slk))\r\n        kicad_mod.append(PolygoneLine(polygone=[[l_slk, t_slk+h_slk], [polsign_slk[0], t_slk+h_slk], [polsign_slk[0]+polsign_slk[2]/2, t_slk+h_slk-polsign_slk[3]/2], [polsign_slk[0]+polsign_slk[2], t_slk+h_slk],[l_slk+w_slk, t_slk+h_slk]], layer='F.SilkS', width=lw_slk))\r\n    else:\r\n        if l_slk<padx/2+lw_slk+slk_offset:\r\n            if t_slk<-(pady/2+lw_slk+slk_offset):\r\n                kicad_mod.append(PolygoneLine(polygone=[[l_slk, -pady/2-lw_slk-slk_offset], [l_slk, t_slk], [l_slk + w_slk, t_slk], [l_slk + w_slk, -pady/2-lw_slk-slk_offset]], layer='F.SilkS', width=lw_slk))\r\n                kicad_mod.append(PolygoneLine(polygone=[[l_slk, pady/2+lw_slk+slk_offset], [l_slk, t_slk + h_slk], [l_slk + w_slk, t_slk + h_slk], [l_slk + w_slk, pady/2+lw_slk+slk_offset]], layer='F.SilkS', width=lw_slk))\r\n            else:\r\n                kicad_mod.append(Line(start=[l_slk, t_slk], end=[l_slk + w_slk, t_slk], layer='F.SilkS', width=lw_slk))\r\n                kicad_mod.append(Line(start=[l_slk, t_slk + h_slk], end=[l_slk + w_slk, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\r\n        else:\r\n            kicad_mod.append(RectLine(start=[l_slk, t_slk], end=[l_slk + w_slk, t_slk + h_slk], layer='F.SilkS', width=lw_slk))\r\n        if type == \"bridge\":\r\n            y=-d2/2; y0=y; y1=y\r\n            while y<d2/2:\r\n                y1=y\r\n                kicad_mod.append(Line(start=[padx/2+2*lw_slk+slk_offset, y], end=[rm-2*lw_slk-padx/2-slk_offset,y], layer='F.SilkS', width=lw_slk))\r\n                y=y+lw_slk\r\n            kicad_mod.append(Line(start=[padx / 2 + 2 * lw_slk + slk_offset, y0], end=[padx / 2 + 2 * lw_slk + slk_offset, y1], layer='F.SilkS', width=lw_slk))\r\n            kicad_mod.append(Line(start=[rm - 2 * lw_slk - padx / 2 - slk_offset, y0], end=[rm - 2 * lw_slk - padx / 2 - slk_offset, y1], layer='F.SilkS', width=lw_slk))\r\n    if padx/2+lw_slk+slk_offset<l_slk:\r\n        kicad_mod.append(Line(start=[padx/2+lw_slk+slk_offset, 0], end=[l_slk, 0], layer='F.SilkS', width=lw_slk))\r\n        kicad_mod.append(Line(start=[rm-padx/2-lw_slk-slk_offset, 0], end=[l_slk+w_slk, 0], layer='F.SilkS', width=lw_slk))\r\n\r\n    if deco==\"diode\":\r\n        kicad_mod.append(Line(start=[l_dbar_slk, t_slk], end=[l_dbar_slk, t_slk+h_slk], layer='F.SilkS', width=lw_slk))\r\n        kicad_mod.append(Line(start=[l_dbar_slk+lw_slk, t_slk], end=[l_dbar_slk+lw_slk, t_slk+h_slk], layer='F.SilkS', width=lw_slk))\r\n        kicad_mod.append(Line(start=[l_dbar_slk-lw_slk, t_slk], end=[l_dbar_slk-lw_slk, t_slk+h_slk], layer='F.SilkS', width=lw_slk))\r\n        kicad_mod.append(Text(type='user', text=\"K\", at=[0,-pady/2-1], layer='F.Fab'))\r\n        kicad_mod.append(Text(type='user', text=\"K\", at=[0,-pady/2-1], layer='F.SilkS'))\r\n\r\n    # create courtyard\r\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt), roundCrt(t_crt)], end=[roundCrt(l_crt+w_crt), roundCrt(t_crt+h_crt)], layer='F.CrtYd', width=lw_crt))\r\n\r\n    # create pads\r\n    if hasShuntPins:\r\n        kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=pad1style, at=[0, 0], size=[padx, pady], drill=ddrill,layers=['*.Cu', '*.Mask']))\r\n        kicad_mod.append(Pad(number=2, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=[(rm-shuntPinsRM)/2, 0], size=[padx, pady], drill=ddrill,layers=['*.Cu', '*.Mask']))\r\n        kicad_mod.append(Pad(number=3, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=[(rm-shuntPinsRM)/2+shuntPinsRM, 0], size=[padx, pady], drill=ddrill,layers=['*.Cu', '*.Mask']))\r\n        kicad_mod.append(Pad(number=4, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=[rm, 0], size=[padx, pady], drill=ddrill,layers=['*.Cu', '*.Mask']))\r\n    else:\r\n        kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=pad1style, at=[0, 0], size=[padx, pady], drill=ddrill, layers=['*.Cu', '*.Mask']))\r\n        kicad_mod.append(Pad(number=2, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=[rm, 0], size=[padx, pady], drill=ddrill, layers=['*.Cu', '*.Mask']))\r\n\r\n    # add model\r\n    if (has3d!=0):\r\n        kicad_mod.append(Model(filename=lib_name + \".3dshapes/\"+footprint_name+\".wrl\", at=x_3d, scale=s_3d, rotate=[0, 0, 0]))\r\n\r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n\r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(footprint_name+'.kicad_mod')\r\n\r\n\r\n# simple axial round (type=\"cyl\")/ box (type=\"box\") resistor, vertically mounted\r\n# deco=\"none\"/\"elco\"/\"cp\"/\"tantal\"/\"diode\"/\"diode_KUP\"\r\n\r\ndef makeResistorAxialVertical(seriesname,rm, rmdisp, l, d, ddrill, R_POW, type=\"cyl\", d2=0, x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", largepadsx=0, largepadsy=0, specialtags=[], add_description=\"\", classname=\"R\", lib_name=\"Resistor_THT\", name_additions=[],deco=\"none\",script3d=\"\"):\r\n    padx = 2 * ddrill\r\n    if padx>rm-0.3:\r\n        padx=max(ddrill+0.3, rm-0.3)\r\n    pady = padx\r\n    if (largepadsx):\r\n        padx = max(padx, largepadsx)\r\n    if (largepadsy):\r\n        pady = max(pady, largepadsy)\r\n\r\n    pad1style=Pad.SHAPE_CIRCLE\r\n    polsign_slk=[]\r\n\r\n    if deco==\"elco\" or deco==\"cp\" or deco==\"tantal\" or deco==\"diode\" or deco==\"diode_KUP\":\r\n        pad1style=Pad.SHAPE_RECT\r\n\r\n    l_fab = -d / 2\r\n    if deco==\"diode_KUP\":\r\n        l_fab=-padx/2\r\n    t_fab = -d / 2\r\n    d_slk = max(max(padx, pady) + 0.15, d + 2 * slk_offset)\r\n    if pad1style==Pad.SHAPE_RECT:\r\n        d_slk = max(max(padx, pady)*math.sqrt(2) + 0.15, d )+ 2 * slk_offset\r\n    d2_slk = max(max(padx, pady) + 0.15, d2 + 2 * slk_offset)\r\n    w_slk = rm + d / 2 + padx / 2 + 2 * slk_offset\r\n    l_slk = l_fab - slk_offset\r\n    r_slk = l_slk + w_slk\r\n    t_slk = -d_slk / 2\r\n\r\n    w_crt = rm + d / 2 + padx / 2 + 2 * crt_offset\r\n    h_crt = max(pady, d) + 2 * crt_offset\r\n    l_crt = l_fab - crt_offset\r\n    t_crt = t_fab - crt_offset\r\n\r\n\r\n    fabtxt_size=1;\r\n    fabtxt_thick=0.15\r\n    if d<=5:\r\n        fabtxt_size=d/5\r\n        fabtxt_thick=0.15*fabtxt_size\r\n    fabtxt_size=max(0.25,fabtxt_size)\r\n    fabtxt_thick=max(0.15/4,fabtxt_thick)\r\n\r\n    valoffset=0\r\n    if deco==\"diode\" or deco==\"diode_KUP\":\r\n        d_size=min(0.35*rm, padx)\r\n        d_y=0\r\n        d_x=rm/2\r\n        if d_size>rm-padx-slk_offset*2-lw_slk*2:\r\n            d_y=pady/2+slk_offset+lw_slk+d_size/2\r\n            valoffset=d_size\r\n            d_x=rm*2/3\r\n            if d_size+padx/2+2*slk_offset<d_slk/2:\r\n                d_x=d_size*2/3\r\n\r\n\r\n\r\n    snfp = \"\"\r\n    sn = \"\"\r\n    snt = \"\"\r\n    if len(seriesname) > 0:\r\n        snfp = \"_\" + seriesname\r\n        sn = \", \" + seriesname + \" series\"\r\n        snt = \" \" + seriesname + \" series\"\r\n\r\n    pow_rat = getPowRat(R_POW)\r\n\r\n    dimdesc = \"length*diameter={0}*{1}mm^2\".format(l, d)\r\n    dimdesct = \"length {0}mm diameter {1}mm\".format(l, d)\r\n\r\n    classnamefancy = getFancyClassName(classname)\r\n\r\n    if deco==\"diode\":\r\n        footprint_name = classname+\"{1}_P{0:0.2f}mm_Vertical_AnodeUp\".format(rmdisp, snfp)\r\n    elif deco==\"diode_KUP\":\r\n        footprint_name = classname+\"{1}_P{0:0.2f}mm_Vertical_KathodeUp\".format(rmdisp, snfp)\r\n    else:\r\n        footprint_name = classname+\"{3}_L{1:0.1f}mm_D{2:0.1f}mm_P{0:0.2f}mm_Vertical\".format(rmdisp, l, d, snfp)\r\n\r\n    if type == \"box\":\r\n        footprint_name = classname+\"{4}_L{3:0.1f}mm_W{1:0.1f}mm_P{0:0.2f}mm_Vertical\".format(rmdisp, d, d2, l, snfp)\r\n        dimdesc = \"length*width*height={0}*{1}*{1}mm^3\".format(l, d, d2)\r\n        dimdesct = \"length {0}mm width {1}mm height {1}mm\".format(l, d, d2)\r\n\r\n    description = classnamefancy+\"{3}, Axial, Vertical, pin pitch={0}mm, {1}, {2}\".format(rm, pow_rat, dimdesc, sn)\r\n    tags = classnamefancy+\"{3} Axial Vertical pin pitch {0}mm {1} {2}\".format(rm, pow_rat, dimdesct, snt)\r\n\r\n    for t in specialtags:\r\n        description = description + \", \" + t\r\n        tags = tags + \" \" + t\r\n    if (specialfpname != \"\"):\r\n        footprint_name = specialfpname;\r\n\r\n    if len(add_description) > 0:\r\n        description = description + \", \" + add_description\r\n\r\n    for n in name_additions:\r\n        if len(n)>0:\r\n            footprint_name=footprint_name+\"_\"+n\r\n\r\n    print(footprint_name)\r\n\r\n\r\n\r\n    if script3d!=\"\":\r\n        with open(script3d, \"a\") as myfile:\r\n            myfile.write(\"\\n\\n # {0}\\n\".format(footprint_name))\r\n            myfile.write(\"import FreeCAD\\n\")\r\n            myfile.write(\"import os\\n\")\r\n            myfile.write(\"import os.path\\n\\n\")\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B4', '0.02')\\n\")\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"# L\\nApp.ActiveDocument.Spreadsheet.set('B1', '{0}')\\n\".format(l) )\r\n            myfile.write(\"# d\\nApp.ActiveDocument.Spreadsheet.set('B2', '{0}')\\n\".format(d))\r\n            myfile.write(\"# d2\\nApp.ActiveDocument.Spreadsheet.set('C2', '{0}')\\n\".format(d2))\r\n            myfile.write(\"# RM\\nApp.ActiveDocument.Spreadsheet.set('B3', '{0}')\\n\".format(rm))\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B4', '{0}')\\n\".format(ddrill-0.3))\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"doc = FreeCAD.activeDocument()\\n\")\r\n            myfile.write(\"__objs__=[]\\n\")\r\n            myfile.write(\"for obj in doc.Objects:\t\\n\")\r\n            myfile.write(\"    if obj.ViewObject.Visibility:\\n\")\r\n            myfile.write(\"        __objs__.append(obj)\\n\")\r\n            myfile.write(\"\\nFreeCADGui.export(__objs__,os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.wrl\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"doc.saveCopy(os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.FCStd\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"print(\\\"created {0}\\\")\\n\".format(footprint_name))\r\n\r\n\r\n\r\n    # init kicad footprint\r\n    kicad_mod = Footprint(footprint_name)\r\n    kicad_mod.setDescription(description)\r\n    kicad_mod.setTags(tags)\r\n\r\n    # set general values\r\n    kicad_mod.append(Text(type='reference', text='REF**', at=[rm / 2, t_slk - txt_offset], layer='F.SilkS'))\r\n    kicad_mod.append(Text(type='value', text=footprint_name, at=[rm / 2, d_slk / 2 + txt_offset+valoffset], layer='F.Fab'))\r\n    if deco==\"diode_KUP\":\r\n        if d/2-pady/2>1.5*fabtxt_size:\r\n            kicad_mod.append(Text(type='user', text='%R', at=[rm, -pady/2-fabtxt_size/2], layer='F.Fab', size=[fabtxt_size, fabtxt_size], thickness=fabtxt_thick))\r\n        else:\r\n            kicad_mod.append(Text(type='user', text='%R', at=[rm / 2, t_slk - txt_offset], layer='F.Fab'))\r\n    else: # diode, resistor, etc.\r\n        if d/2-pady/2>1.5*fabtxt_size:\r\n            kicad_mod.append(Text(type='user', text='%R', at=[0, -pady/2-fabtxt_size/2], layer='F.Fab', size=[fabtxt_size, fabtxt_size], thickness=fabtxt_thick))\r\n        else:\r\n            kicad_mod.append(Text(type='user', text='%R', at=[rm / 2, t_slk - txt_offset], layer='F.Fab'))\r\n\r\n    # create FAB-layer\r\n    if type==\"cyl\":\r\n        if deco==\"diode_KUP\":\r\n            kicad_mod.append(Circle(center=[rm, 0], radius=d / 2, layer='F.Fab', width=lw_fab))\r\n        else:\r\n            kicad_mod.append(Circle(center=[0, 0], radius=d / 2, layer='F.Fab', width=lw_fab))\r\n    else:\r\n        kicad_mod.append(RectLine(start=[-d/2, -d2/2], end=[d/2,d2/2], layer='F.Fab', width=lw_fab))\r\n    kicad_mod.append(Line(start=[0, 0], end=[rm,0], layer='F.Fab', width=lw_fab))\r\n    if deco==\"diode\":\r\n        if rm>d/2*1.2 and d/2-pady/2<1:\r\n            if rm<3:\r\n                kicad_mod.append(Text(type='user', text=\"A\", at=[rm+padx/2+1,0], layer='F.Fab'))\r\n                kicad_mod.append(Text(type='user', text=\"A\", at=[rm+padx/2+1,0], layer='F.SilkS'))\r\n            else:\r\n                kicad_mod.append(Text(type='user', text=\"A\", at=[rm-padx/2-0.7,(pady/2)], layer='F.Fab'))\r\n                kicad_mod.append(Text(type='user', text=\"A\", at=[rm-padx/2-0.7,(pady/2)], layer='F.SilkS'))\r\n        else:\r\n            kicad_mod.append(Text(type='user', text=\"A\", at=[rm,(pady/2+1)], layer='F.Fab'))\r\n            kicad_mod.append(Text(type='user', text=\"A\", at=[rm,(pady/2+1)], layer='F.SilkS'))\r\n    elif deco==\"diode_KUP\":\r\n        if rm>d/2*1.2 and d/2-pady/2<1:\r\n            if rm<3:\r\n                kicad_mod.append(Text(type='user', text=\"K\", at=[0-padx/2-1,0], layer='F.Fab'))\r\n                kicad_mod.append(Text(type='user', text=\"K\", at=[0-padx/2-1,0], layer='F.SilkS'))\r\n            else:\r\n                kicad_mod.append(Text(type='user', text=\"K\", at=[0+padx/2+0.7,(pady/2)], layer='F.Fab'))\r\n                kicad_mod.append(Text(type='user', text=\"K\", at=[0+padx/2+0.7,(pady/2)], layer='F.SilkS'))\r\n        else:\r\n            kicad_mod.append(Text(type='user', text=\"K\", at=[0,(pady/2+1)], layer='F.Fab'))\r\n            kicad_mod.append(Text(type='user', text=\"K\", at=[0,(pady/2+1)], layer='F.SilkS'))\r\n\r\n    # create SILKSCREEN-layer\r\n    xs1 = d_slk / 2\r\n    xs2 = rm - padx / 2 - 0.3\r\n\r\n    if (xs1 < xs2):\r\n        if type == \"cyl\":\r\n            if deco==\"diode_KUP\":\r\n                xs1 = rm-d_slk / 2\r\n                xs2 = padx / 2 + 0.3\r\n                kicad_mod.append(Circle(center=[rm, 0], radius=d_slk / 2, layer='F.SilkS', width=lw_slk))\r\n            else:\r\n                kicad_mod.append(Circle(center=[0, 0], radius=d_slk / 2, layer='F.SilkS', width=lw_slk))\r\n        else:\r\n            kicad_mod.append(RectLine(start=[-d_slk/2, -d2_slk/2], end=[d_slk/2,d2_slk/2], layer='F.SilkS', width=lw_slk))\r\n        kicad_mod.append(Line(start=[xs1, 0], end=[xs2, 0], layer='F.SilkS', width=lw_slk))\r\n    else:\r\n        yy = (pady+slk_offset+lw_slk)/2\r\n        #I don't know why rectangle pads would allow silk nearer to the pad. -> removed for this reason\r\n        # if pad1style==Pad.SHAPE_RECT:\r\n        #     yy=(pady+slk_offset)/2\r\n\r\n        xx=math.sqrt((d_slk/2)**2-(yy)**2)\r\n\r\n        alpha=360-2*math.degrees(math.acos(xx/(d_slk/2)))\r\n        if type == \"cyl\":\r\n            if deco==\"diode_KUP\":\r\n                kicad_mod.append(Arc(center=[rm, 0], start=[rm-xx, -yy], angle=alpha, layer='F.SilkS', width=lw_slk))\r\n            else:\r\n                kicad_mod.append(Arc(center=[0, 0], start=[xx, -yy], angle=-alpha, layer='F.SilkS', width=lw_slk))\r\n        else:\r\n            kicad_mod.append(PolygoneLine(polygone=[[d_slk/2, -yy],\r\n                                                    [d_slk / 2, -d2_slk / 2],\r\n                                                    [-d_slk / 2, -d2_slk / 2],\r\n                                                    [d_slk / 2, -d2_slk / 2],\r\n                                                    [d_slk / 2, +yy]], layer='F.SilkS', width=lw_slk))\r\n#    if deco==\"diode\" or deco==\"diode_KUP\":\r\n#        kicad_mod.append(Line(start=[d_x-d_size/3, d_y-0.5*d_size], end=[d_x-d_size/3, d_y+0.5*d_size], layer='F.SilkS', width=lw_slk))\r\n#        kicad_mod.append(PolygoneLine(polygone=[[d_x-d_size/3, d_y],\r\n#                                                [d_x+d_size/3, d_y-0.5*d_size],\r\n#                                                [d_x+d_size/3, d_y+0.5*d_size],\r\n#                                                [d_x-d_size/3, d_y]], layer='F.SilkS', width=lw_slk))\r\n\r\n\r\n    # create courtyard\r\n    kicad_mod.append(\r\n        RectLine(start=[roundCrt(l_crt), roundCrt(t_crt)], end=[roundCrt(l_crt + w_crt), roundCrt(t_crt + h_crt)],\r\n                 layer='F.CrtYd', width=lw_crt))\r\n\r\n    # create pads\r\n    kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=pad1style, at=[0, 0], size=[padx, pady], drill=ddrill,\r\n                         layers=['*.Cu', '*.Mask']))\r\n    kicad_mod.append(Pad(number=2, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=[rm, 0], size=[padx, pady], drill=ddrill,\r\n                         layers=['*.Cu', '*.Mask']))\r\n\r\n    # add model\r\n    if (has3d != 0):\r\n        kicad_mod.append(\r\n            Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=[0, 0, 0]))\r\n\r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n\r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(footprint_name + '.kicad_mod')\r\n\r\n\r\n# simple radial rectangular resistor, vertically mounted\r\n#   style options:\r\n#     1. type=\"simple\"\r\n#           +----------------+ ^\r\n#           |                | |\r\n#           |  OO        OO  | h\r\n#           |                | |\r\n#           +----------------+ v\r\n#               <---rm--->\r\n#           <-------w-------->\r\n#     2. type=\"simple\", vlines=True\r\n#           +-+------------+-+ ^\r\n#           | |            | | |\r\n#           | | OO     OO  | | h\r\n#           | |            | | |\r\n#           +-+------------+-+ v\r\n#               <--rm-->\r\n#           <-------w-------->\r\n#             <----w2------>\r\n#     3. type=\"simple45\"\r\n#           +----------------+ ^\r\n#           |            OO  | |  ^rm2\r\n#           |       OO       | h  v\r\n#           |                | |\r\n#           +----------------+ v\r\n#                   <-rm->\r\n#           <-------w-------->\r\n#     4. type=\"simple45\", vlines=True\r\n#           +-+------------+-+ ^\r\n#           | |         OO | | |  ^rm2\r\n#           | |     OO     | | h  v\r\n#           | |            | | |\r\n#           +-+------------+-+ v\r\n#                   <-rm->\r\n#           <-------w-------->\r\n#             <----w2------>\r\n#     5. type=\"round\": ellipse, diameter w/h\r\n#     6. type=\"disc\"\r\n#           +----------------+ ^\r\n#           |                | |\r\n#           |  OO        OO  | h\r\n#           |                | |\r\n#           +----------------+ v\r\n#               <---rm--->\r\n#           <-------w-------->\r\n#     7. type=\"disc45\"\r\n#           +----------------+ ^\r\n#           |  OO            | |  ^\r\n#           |                | h  rm2\r\n#           |            OO  | |  v\r\n#           +----------------+ v\r\n#                   <-rm->\r\n#           <-------w-------->\r\n#     8. type=\"simplesymm45\"\r\n#           +----------------+ ^\r\n#           |            OO  | |  ^\r\n#           |                | h  rm2\r\n#           |  OO            | |  v\r\n#           +----------------+ v\r\n#               <---rm--->\r\n#           <-------w-------->\r\n#     9. type=\"concentric\": ellipse, diameter w + ellipse, diameter w2 h\r\n#     10. type=\"simple90\"\r\n#           +----------------+ ^\r\n#           |       OO       | |  ^\r\n#           |                | h  rm\r\n#           |       OO       | |  v\r\n#           +----------------+ v\r\n#           <-------w-------->\r\n#\r\n#\r\n# deco=\"none\",\"elco\" (round),\"tantal\" (simple),\"chokewire\" (concentric)\r\n\r\ndef makeResistorRadial(seriesname, rm, w, h, ddrill, R_POW, innerw=0,innerh=0,rm2=0, pins=2, vlines=False,w2=0, type=\"simple\", x_3d=[0, 0, 0], s_3d=[1,1,1], has3d=1, specialfpname=\"\", specialtags=[], add_description=\"\", classname=\"R\", lib_name=\"Resistor_THT\", name_additions=[], deco=\"none\",script3d=\"\",height3d=10, additionalPins=[]):\r\n    if innerw<=0:\r\n        innerw=w\r\n    if innerh<=0:\r\n        innerh=h\r\n\r\n    padx = 2 * ddrill\r\n    pady = padx\r\n    txtoffset=txt_offset\r\n    add_pol_sign = False\r\n    pad1style=Pad.SHAPE_CIRCLE\r\n\r\n    if deco==\"elco\" or deco==\"cp\" or deco==\"tantal\":\r\n        pad1style=Pad.SHAPE_RECT\r\n\r\n\r\n    padpos=[]\r\n    offset=[0,0]\r\n    if type==\"simple\" or type==\"disc\" or type==\"round\" or type==\"concentric\":\r\n        if pins == 4 and rm2 > 0:\r\n            padpos.append([1, -rm2 / 2, -rm / 2, ddrill, padx, pady])\r\n            padpos.append([4, rm2 / 2, -rm / 2, ddrill, padx, pady])\r\n            padpos.append([3, rm2 / 2, rm / 2, ddrill, padx, pady])\r\n            padpos.append([2, -rm2 / 2, rm / 2, ddrill, padx, pady])\r\n            offset = [rm2 / 2, rm / 2]\r\n            pad1style = Pad.SHAPE_RECT\r\n        else:\r\n            padpos.append([1,- rm / 2, 0, ddrill,padx,pady])\r\n            padpos.append([2,rm / 2, 0, ddrill,padx,pady])\r\n            offset=[rm/2,0]\r\n    elif type == \"simple45\":\r\n        padpos.append([1,0, 0, ddrill,padx,pady])\r\n        padpos.append([2,rm,-rm2, ddrill,padx,pady])\r\n        offset = [0, 0]\r\n    elif type == \"simplesymm45\":\r\n        padpos.append([1,-rm/2, rm2/2, ddrill,padx,pady])\r\n        padpos.append([2, rm/2, -rm2/2, ddrill,padx,pady])\r\n        offset = [rm/2, -rm2/2]\r\n    elif type == \"simple90\":\r\n        if pins==4 and rm2>0:\r\n            padpos.append([1, -rm2/2, rm/2, ddrill,padx,pady])\r\n            padpos.append([4, rm2/2, rm/2, ddrill,padx,pady])\r\n            padpos.append([3, rm2/2,  -rm/2, ddrill,padx,pady])\r\n            padpos.append([2, -rm2/2,  -rm/2, ddrill,padx,pady])\r\n            offset = [rm2/2, -rm/2]\r\n            pad1style=Pad.SHAPE_RECT\r\n        else:\r\n            padpos.append([1, 0, -rm/2, ddrill,padx,pady])\r\n            padpos.append([2, 0,  rm/2, ddrill,padx,pady])\r\n            offset = [0, rm/2]\r\n        #txtoffset=max(txt_offset,pady*2/3)\r\n    elif type == \"disc45\":\r\n        padpos.append([1,-rm/2, -rm2/2, ddrill,padx,pady])\r\n        padpos.append([2,rm/2,rm2/2, ddrill,padx,pady])\r\n        offset = [rm/2, rm2/2]\r\n\r\n    if deco==\"elco\" or deco==\"cp\" or deco==\"tantal\":\r\n        x=0\r\n        y=0\r\n        for p in padpos:\r\n            if p[0]==1:\r\n                x=min(x, p[1])\r\n                y=min(y, p[2])\r\n        #print(x,y)\r\n        add_pol_sign = True\r\n\r\n    rmm2=0\r\n    secondPitch=False\r\n    if rm2>rm and ( type==\"concentric\" or type==\"round\"):\r\n        secondPitch=True\r\n        rmm2=0\r\n        yy=pady\r\n        xx=math.sqrt(rm2*rm2/4-yy*yy)\r\n        padpos.append([1,-xx, -yy, ddrill,padx,pady])\r\n        padpos.append([2,xx,yy, ddrill,padx,pady])\r\n\r\n    if rm2>rm and type==\"simple\" and pins == 2:\r\n        secondPitch=True\r\n        rmm2=0\r\n        padpos.append([1,-rm2/2, 0, ddrill,padx,pady])\r\n        padpos.append([2,rm2/2,0, ddrill,padx,pady])\r\n        offset=[max(rm2/2,rm/2),0]\r\n    elif rm2>rm and type==\"simple\" and pins == 4:\r\n        rmm2=0\r\n    elif type==\"simple90\":\r\n        rmm2=rm\r\n\r\n\r\n    for ep in additionalPins:\r\n        padpos.append([ep[0],ep[1]-offset[0], ep[2]-offset[1], ep[3],ep[3]*2,ep[3]*2])\r\n\r\n\r\n    #print(polsign_slk)\r\n\r\n    l_fab = -w / 2\r\n    t_fab = -h / 2\r\n    il_fab = -innerw / 2\r\n    it_fab = -innerh / 2\r\n    lvl1_fab = -w2 / 2\r\n    lvl2_fab = w2 / 2\r\n    w_fab = w\r\n    h_fab = h\r\n    iw_fab = innerw\r\n    ih_fab = innerh\r\n    d_fab = max(w, h)\r\n    r_fab = d_fab/2.\r\n    d2_fab=w2\r\n    h_slk = h_fab + 2 * slk_offset\r\n    w_slk = w_fab + 2 * slk_offset\r\n    l_slk = l_fab - slk_offset\r\n    t_slk = t_fab - slk_offset\r\n    lvl1_slk=lvl1_fab\r\n    lvl2_slk = lvl2_fab\r\n    d_slk=d_fab+lw_slk+slk_offset\r\n    r_slk = d_slk/2.\r\n    d2_slk=d2_fab-lw_slk-slk_offset\r\n    w_crt = max(w_fab, rm+padx) + 2 * crt_offset\r\n    h_crt = max(h_fab, rmm2+pady) + 2 * crt_offset\r\n    l_crt = -w_crt/2\r\n    t_crt = -h_crt/2\r\n\r\n    fabtxt_size=1;\r\n    fabtxt_thick=0.15\r\n    if w_fab<=5 or h_fab<=1:\r\n        fabtxt_size=min(h_fab*0.8, w_fab/5)\r\n        fabtxt_thick=0.15*fabtxt_size\r\n    fabtxt_size=max(0.25,fabtxt_size)\r\n    fabtxt_thick=max(0.15/4,fabtxt_thick)\r\n\r\n    snfp = \"\"\r\n    sn = \"\"\r\n    snt = \"\"\r\n    if len(seriesname) > 0:\r\n        snfp = \"_\" + seriesname\r\n        sn = \", \" + seriesname + \" series\"\r\n        snt = \" \" + seriesname + \" series\"\r\n\r\n    pow_rat = getPowRat(R_POW)\r\n\r\n    fnpins = \"_P{0:0.2f}mm\".format(rm)\r\n    pind=\"{0:0.2f}mm\".format(rm)\r\n    if secondPitch:\r\n        fnpins = fnpins+\"_P{0:0.2f}mm\".format(rm2)\r\n        pind=pind+\" {0:0.2f}mm\".format(rm2)\r\n\r\n    if type == \"simple45\" or type==\"disc45\" or type==\"simplesymm45\" or pins==4:\r\n        fnpins = \"_Px{0:0.2f}mm_Py{1:0.2f}mm\".format(rm,rm2)\r\n        pind = \"{0:0.2f}*{1:0.2f}mm^2\".format(rm,rm2)\r\n\r\n    dimdesc = \"length*width={0}*{1}mm^2\".format(w, h)\r\n    dimdesct = \"length {0}mm width {1}mm\".format(w, h)\r\n\r\n    if type == \"disc\" or type == \"disc45\":\r\n        dimdesc = \"diameter*width={0}*{1}mm^2\".format(w, h)\r\n        dimdesct = \"diameter {0}mm width {1}mm\".format(w, h)\r\n\r\n    classnamefancy = getFancyClassName(classname)\r\n\r\n    if type==\"round\" or type == \"concentric\":\r\n        if w==h:\r\n            dimdesc = \"diameter={0}mm, height={1}mm\".format(w, height3d)\r\n            dimdesct = \"diameter {0}mm height {1}mm\".format(w, height3d)\r\n        else:\r\n            dimdesc = \"diameterX*diameterY={0}*{1}mm^2\".format(w, h)\r\n            dimdesct = \"diameterX {0}mm diameterY {1}mm\".format(w, h)\r\n        if classname[0].upper() == \"C\":\r\n            footprint_name = classname + \"{2}_D{1:0.1f}mm_H{3:0.1f}mm{0}\".format(fnpins, w, snfp, height3d) # radial caps\r\n        else:\r\n            footprint_name = classname + \"{2}_D{1:0.1f}mm{0}\".format(fnpins, w, snfp)\r\n    elif type==\"disc\" or type == \"disc45\":\r\n        footprint_name = classname+\"{3}_D{1:0.1f}mm_W{2:0.1f}mm{0}\".format(fnpins, w, h, snfp)\r\n    else:\r\n        if classname[0].upper() == \"C\":\r\n            footprint_name = classname+\"{3}_L{1:0.1f}mm_W{2:0.1f}mm_H{4:0.1f}mm{0}\".format(fnpins, w, h, snfp, height3d) #rect (box) caps\r\n        else:\r\n            footprint_name = classname+\"{3}_L{1:0.1f}mm_W{2:0.1f}mm{0}\".format(fnpins, w, h, snfp)\r\n    \r\n    if classname[0].upper() == \"C\":\r\n        description = classnamefancy+\"{2}, Radial, pin pitch={0}, {1}\".format(pind, dimdesc, sn)\r\n        tags = classnamefancy+\"{2} Radial pin pitch {0} {1}\".format(pind, dimdesct, snt)\r\n    else:\r\n        description = classnamefancy+\"{3}, Radial, pin pitch={0}, {1}, {2}\".format(pind, pow_rat, dimdesc, sn)\r\n        tags = classnamefancy+\"{3} Radial pin pitch {0} {1} {2}\".format(pind, pow_rat, dimdesct, snt)\r\n\r\n\r\n    for t in specialtags:\r\n        description = description + \", \" + t\r\n        tags = tags + \" \" + t\r\n    if (specialfpname != \"\"):\r\n        footprint_name = specialfpname\r\n\r\n    if len(add_description) > 0:\r\n        description = description + \", \" + add_description\r\n\r\n    for n in name_additions:\r\n        if len(n)>0:\r\n            footprint_name=footprint_name+\"_\"+n\r\n\r\n    print(footprint_name)\r\n\r\n\r\n    if script3d!=\"\":\r\n        with open(script3d, \"a\") as myfile:\r\n\r\n            myfile.write(\"\\n    \\\"{0}\\\" : Params(# from Jan Kriege's 3d models\\n\".format(footprint_name))\r\n            if seriesname != \"Disc\" and seriesname !=  \"Radial_Tantal\":\r\n                myfile.write(\"        H = {:0.2f}, # Body Height\\n\".format(height3d))\r\n            myfile.write(\"        L = {:0.2f}, # Body Length\\n\".format(innerw))\r\n            myfile.write(\"        W = {:0.2f}, # Body Width\\n\".format(innerh))\r\n            myfile.write(\"        d = {:0.2f}, # Lead Diameter\\n\".format(ddrill-0.3))\r\n            if secondPitch:\r\n                myfile.write(\"        F = {:0.2f}, # Lead Seperation\\n\".format(rm2))\r\n            else:\r\n                myfile.write(\"        F = {:0.2f}, # Lead Seperation\\n\".format(rm))\r\n            myfile.write(\"        ll = 2.0, # Lead Length\\n\")\r\n            myfile.write(\"        bs = 0.1, # Board Seperation\\n\")\r\n            if seriesname == \"Rect\":\r\n                if len(name_additions) > 0 and name_additions[0] == \"MKT\":\r\n                    myfile.write(\"        series = 'MKT', # 'MKS' or 'MKT'\\n\")\r\n                else:\r\n                    myfile.write(\"        series = 'MKS', # 'MKS' or 'MKT'\\n\")\r\n            myfile.write(\"        modelName = '{0}', # Modelname\\n\".format(footprint_name))\r\n            myfile.write(\"        rotation = 0, # Rotation\\n\")\r\n            myfile.write(\"        dest_dir_prefix = '../Capacitors_THT.3dshapes/', # Destination\\n\")\r\n            myfile.write(\"    ),\\n\")\r\n            # Jan's Script\r\n            '''\r\n            myfile.write(\"\\n\\n # {0}\\n\".format(footprint_name))\r\n            myfile.write(\"import FreeCAD\\n\")\r\n            myfile.write(\"import os\\n\")\r\n            myfile.write(\"import os.path\\n\\n\")\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B4', '0.02')\\n\")\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"# Wx\\nApp.ActiveDocument.Spreadsheet.set('B1', '{0}')\\n\".format(innerw) )\r\n            myfile.write(\"# iWx\\nApp.ActiveDocument.Spreadsheet.set('D1', '{0}')\\n\".format(w) )\r\n            myfile.write(\"# W2\\nApp.ActiveDocument.Spreadsheet.set('C1', '{0}')\\n\".format(w2) )\r\n            myfile.write(\"# Wy\\nApp.ActiveDocument.Spreadsheet.set('B2', '{0}')\\n\".format(innerh) )\r\n            myfile.write(\"# iWy\\nApp.ActiveDocument.Spreadsheet.set('D2', '{0}')\\n\".format(h) )\r\n            myfile.write(\"# RMx\\nApp.ActiveDocument.Spreadsheet.set('B3', '{0}')\\n\".format(rm) )\r\n            myfile.write(\"# RMy\\nApp.ActiveDocument.Spreadsheet.set('C3', '{0}')\\n\".format(rm2) )\r\n            myfile.write(\"# H\\nApp.ActiveDocument.Spreadsheet.set('B5', '{0}')\\n\".format(height3d) )\r\n            myfile.write(\"# offsetx\\nApp.ActiveDocument.Spreadsheet.set('B6', '{0}')\\n\".format(-(l_fab+offset[0])) )\r\n            myfile.write(\"# d_wire\\nApp.ActiveDocument.Spreadsheet.set('B4', '{0}')\\n\".format(ddrill-0.3))\r\n            if len(additionalPins)>0:\r\n                ep=additionalPins[0]\r\n                myfile.write(\"# d_wire_pin3\\nApp.ActiveDocument.Spreadsheet.set('C4', '{0}')\\n\".format(ep[3]-0.3))\r\n                myfile.write(\"# pin3x\\nApp.ActiveDocument.Spreadsheet.set('B5', '{0}')\\n\".format(ep[1]))\r\n                myfile.write(\"# pin3x\\nApp.ActiveDocument.Spreadsheet.set('C5', '{0}')\\n\".format(ep[2]))\r\n            myfile.write(\"App.ActiveDocument.recompute()\\n\")\r\n            myfile.write(\"doc = FreeCAD.activeDocument()\\n\")\r\n            myfile.write(\"__objs__=[]\\n\")\r\n            myfile.write(\"for obj in doc.Objects:  \\n\")\r\n            myfile.write(\"    if obj.ViewObject.Visibility:\\n\")\r\n            myfile.write(\"        __objs__.append(obj)\\n\")\r\n            myfile.write(\"\\nFreeCADGui.export(__objs__,os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.wrl\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"doc.saveCopy(os.path.split(doc.FileName)[0]+os.sep+\\\"{0}.FCStd\\\")\\n\".format(footprint_name))\r\n            myfile.write(\"print(\\\"created {0}\\\")\\n\".format(footprint_name))\r\n            '''\r\n\r\n    # init kicad footprint\r\n    kicad_mod = Footprint(footprint_name)\r\n    kicad_mod.setDescription(description)\r\n    kicad_mod.setTags(tags)\r\n\r\n    kicad_modg = Translation(offset[0], offset[1])\r\n    kicad_mod.append(kicad_modg)\r\n\r\n\r\n    # set general values\r\n    kicad_modg.append(Text(type='reference', text='REF**', at=[0, t_crt - txtoffset], layer='F.SilkS'))\r\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[0, t_crt+h_crt + txtoffset], layer='F.Fab'))\r\n    kicad_mod.append(Text(type='user', text='%R', at=[rm/2, 0], layer='F.Fab', size=[fabtxt_size, fabtxt_size], thickness=fabtxt_thick))\r\n\r\n    # create FAB-layer\r\n    if type==\"round\" or type==\"concentric\":\r\n        kicad_modg.append(Circle(center=[l_fab+w_fab/2, t_fab+h_fab/2], radius=d_fab/2, layer='F.Fab', width=lw_fab))\r\n        if w2>0 and type==\"concentric\":\r\n            kicad_modg.append(Circle(center=[l_fab+w_fab/2, t_fab+h_fab/2], radius=d2_fab/2, layer='F.Fab', width=lw_fab))\r\n            if deco==\"chokewire\":\r\n                alpha1=0\r\n                alpha2=15\r\n                while alpha1<=360:\r\n                    kicad_modg.append(Line(start=[d_slk*0.49*math.cos(alpha1/180*3.1415),d_slk*0.49*math.sin(alpha1/180*3.1415)], end=[d2_slk*0.51*math.cos(alpha2/180*3.1415),d2_slk*0.51*math.sin(alpha2/180*3.1415)], layer='F.Fab', width=lw_fab))\r\n                    alpha1=alpha1+30\r\n                    alpha2=alpha2+30\r\n    else:\r\n        kicad_modg.append(RectLine(start=[l_fab, t_fab], end=[l_fab + w_fab, t_fab + h_fab], layer='F.Fab', width=lw_fab))\r\n        if innerw!=w or innerh!=h:\r\n            kicad_modg.append(RectLine(start=[il_fab, it_fab], end=[il_fab + iw_fab, it_fab + ih_fab], layer='F.Fab', width=lw_fab))\r\n        if vlines:\r\n            kicad_modg.append(Line(start=[lvl1_fab, t_fab], end=[lvl1_fab,t_fab+h_fab], layer='F.Fab', width=lw_fab))\r\n            kicad_modg.append(Line(start=[lvl2_fab, t_fab], end=[lvl2_fab, t_fab + h_fab], layer='F.Fab', width=lw_fab))\r\n        if deco==\"chokewire\":\r\n            ww=w_fab\r\n            tt=t_fab\r\n            hh=h_fab\r\n            ll=l_fab\r\n            if innerw != w or innerh != h:\r\n                ww=iw_fab\r\n                tt=it_fab\r\n                hh=ih_fab\r\n                ll=il_fab\r\n            x1=ll\r\n            x2=ll+0.05*ww\r\n            while x2<ll+ww:\r\n                kicad_modg.append(Line(start=[x1,tt], end=[x2,tt+hh], layer='F.Fab', width=lw_fab))\r\n                x1=x1+0.1*ww\r\n                x2=x2+0.1*ww\r\n\r\n\r\n    if add_pol_sign:\r\n        polsign_size = d_fab/10.0\r\n        # (((d_fab-polsign_size)/2.0-polsign_size/10.0)\r\n        polsign_pos_x = -(((d_fab-lw_fab/2.-polsign_size)/2.0-polsign_size/10.0)*math.cos(math.radians(30)))\r\n        polsign_pos_y = -(((d_fab-lw_fab/2.-polsign_size)/2.0-polsign_size/10.0)*math.sin(math.radians(30)))\r\n        kicad_modg.append(Line(start=[polsign_pos_x-polsign_size/2., polsign_pos_y], end=[polsign_pos_x+polsign_size/2.,polsign_pos_y], layer='F.Fab', width=lw_fab))\r\n        kicad_modg.append(Line(start=[polsign_pos_x, polsign_pos_y-polsign_size/2.], end=[polsign_pos_x,polsign_pos_y+polsign_size/2.], layer='F.Fab', width=lw_fab))\r\n\r\n\r\n    # build keepeout for SilkScreen\r\n    keepouts=[]\r\n    for p in padpos:\r\n        if deco==\"elco\":\r\n            keepouts=keepouts+addKeepoutRect(p[1],p[2],p[4]+2*lw_slk+2*slk_offset,p[5]+2*lw_slk+2*slk_offset)\r\n        else:\r\n            keepouts=keepouts+addKeepoutRound(p[1],p[2],p[4]+2*lw_slk+2*slk_offset,p[5]+2*lw_slk+2*slk_offset)\r\n\r\n    # create SILKSCREEN-layer\r\n    if type==\"round\" or type==\"concentric\":\r\n        sq_pad_x_max = rm/2+padx/2.+min_pad_distance+lw_slk/2.\r\n        sq_pad_y_min = pady/2.+min_pad_distance+lw_slk/2\r\n        if rm2 > 0:\r\n            pad_pos_x_max= 0\r\n            pad_pos_y_max= 0\r\n            for p in padpos:\r\n                pad_pos_x_max=max(pad_pos_x_max, abs(p[1]))\r\n                pad_pos_y_max=max(pad_pos_y_max, abs(p[2]))\r\n            sq_pad_x_max = pad_pos_x_max+padx/2.+min_pad_distance+lw_slk/2.\r\n            sq_pad_y_min = pad_pos_y_max+pady/2.+min_pad_distance+lw_slk/2\r\n\r\n        #check if silkscreen will hit the pad or pad clearance\r\n        slk_x_test = math.sqrt((r_slk*r_slk)-(sq_pad_y_min * sq_pad_y_min))\r\n        if sq_pad_x_max > slk_x_test:\r\n            #test circular pad clearance\r\n            round_pad_x_max = sq_pad_x_max\r\n            if round_pad_x_max < r_slk:\r\n                if rm2 == 0:\r\n                    start_angle = math.degrees(math.asin(sq_pad_y_min/r_slk))\r\n                    arc_angle = 360-(start_angle*2.)\r\n                else:\r\n                    arc_angle = 340\r\n                kicad_modg.append(Arc(center=[0,0], start=[-slk_x_test, -sq_pad_y_min], angle=arc_angle, layer='F.SilkS', width=lw_slk))\r\n            else:\r\n                start_angle = math.degrees(math.asin(sq_pad_y_min/r_slk))\r\n                arc_angle = 180-(start_angle*2.)\r\n                kicad_modg.append(Arc(center=[0,0], start=[-slk_x_test, -sq_pad_y_min], angle=arc_angle, layer='F.SilkS', width=lw_slk))\r\n                kicad_modg.append(Arc(center=[0,0], start=[-slk_x_test, sq_pad_y_min], angle=-arc_angle, layer='F.SilkS', width=lw_slk))\r\n\r\n        else:\r\n            kicad_modg.append(Circle(center=[l_slk + w_slk / 2, t_slk + h_slk / 2], radius=d_slk/2, layer='F.SilkS', width=lw_slk))\r\n\r\n        if deco==\"elco\":\r\n            x=0;\r\n            while x<d_slk/2:\r\n                hc=math.sqrt(d_slk*d_slk/4-x*x)-lw_slk/3\r\n                addVLineWithKeepout(kicad_modg, x, -hc,hc, 'F.SilkS', lw_slk, keepouts, 0.001)\r\n                x=x+lw_slk/3\r\n        if type==\"concentric\":\r\n            kicad_modg.append(Circle(center=[l_slk + w_slk / 2, t_slk + h_slk / 2], radius=d2_slk/2, layer='F.SilkS', width=lw_slk))\r\n\r\n\r\n    else:\r\n        addRectWithKeepout(kicad_modg, l_slk, t_slk, w_slk, h_slk, 'F.SilkS', lw_slk, keepouts, 0.001)\r\n        if vlines:\r\n            addVLineWithKeepout(kicad_modg, lvl1_slk, t_slk, t_slk+h_slk, 'F.SilkS', lw_slk, keepouts, 0.001)\r\n            addVLineWithKeepout(kicad_modg, lvl2_slk, t_slk, t_slk + h_slk, 'F.SilkS', lw_slk, keepouts, 0.001)\r\n\r\n    if add_pol_sign:\r\n        polsign_size = d_fab/10.0\r\n        polsign_pos_x = -(((d_slk+lw_slk/2.+polsign_size)/2.0+polsign_size/10.0)*math.cos(math.radians(30)))\r\n        polsign_pos_y = -(((d_slk+lw_slk/2.+polsign_size)/2.0+polsign_size/10.0)*math.sin(math.radians(30)))\r\n        kicad_modg.append(Line(start=[polsign_pos_x-polsign_size/2., polsign_pos_y], end=[polsign_pos_x+polsign_size/2.,polsign_pos_y], layer='F.SilkS', width=lw_slk))\r\n        kicad_modg.append(Line(start=[polsign_pos_x, polsign_pos_y-polsign_size/2.], end=[polsign_pos_x,polsign_pos_y+polsign_size/2.], layer='F.SilkS', width=lw_slk))\r\n\r\n\r\n\r\n    # create courtyard\r\n\r\n    if type==\"round\":\r\n        #check if pads are further out than the calculated courtyard\r\n        sq_pad_x_max = sq_pad_x_max - min_pad_distance\r\n        sq_pad_y_min = sq_pad_y_min - min_pad_distance\r\n        r_crt = max(r_fab+crt_offset, math.sqrt(sq_pad_x_max * sq_pad_x_max + sq_pad_y_min * sq_pad_y_min)+crt_offset)\r\n        kicad_mod.append(Circle(center=[rm/2.,0], radius=roundCrt(r_crt),layer='F.CrtYd', width=lw_crt))\r\n    else:\r\n        kicad_mod.append(RectLine(start=[roundCrt(l_crt+offset[0]), roundCrt(t_crt+offset[1])], end=[roundCrt(l_crt + w_crt+offset[0]), roundCrt(t_crt + h_crt+offset[1])],layer='F.CrtYd', width=lw_crt))\r\n\r\n    # create pads\r\n    pn=1\r\n    for p in padpos:\r\n        ps=Pad.SHAPE_CIRCLE\r\n        if p[0]==1:\r\n            ps=pad1style\r\n        kicad_modg.append(Pad(number=p[0], type=Pad.TYPE_THT, shape=ps, at=[p[1], p[2]], size=[p[4],p[5]], drill=p[3], layers=['*.Cu', '*.Mask']))\r\n\r\n\r\n\r\n\r\n    # add model\r\n    if (has3d != 0):\r\n        kicad_modg.append(Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=x_3d, scale=s_3d, rotate=[0, 0, 0]))\r\n\r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n\r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(footprint_name + '.kicad_mod')\r\n"
  },
  {
    "path": "scripts/tools/footprint_scripts_sip.py",
    "content": "#!/usr/bin/env python\r\n\r\nimport sys\r\nimport os\r\nimport math\r\n\r\n# ensure that the kicad-footprint-generator directory is available\r\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\r\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\r\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\r\n\r\nfrom KicadModTree import *  # NOQA\r\nfrom drawing_tools import *\r\nfrom footprint_global_properties import *\r\n\r\n\r\ndef makeSIPVertical(pins, rm, ddrill, pad, package_size, left_offset, top_offset, footprint_name, description, tags, lib_name, missing_pins=[]):\r\n    padx=pad[0]\r\n    pady=pad[1]\r\n    \r\n    w_fab=package_size[0]\r\n    h_fab=package_size[1]\r\n    l_fab=-left_offset\r\n    t_fab=-top_offset\r\n    \r\n    h_slk = h_fab + 2 * slk_offset\r\n    w_slk = w_fab + 2 * slk_offset\r\n    l_slk = l_fab - slk_offset\r\n    t_slk = t_fab - slk_offset\r\n    w_crt = w_fab + 2 * crt_offset\r\n    h_crt = h_fab + 2 * crt_offset\r\n    l_crt = min(l_fab, -padx / 2) - crt_offset\r\n    t_crt = t_fab  - crt_offset\r\n    if (-pady/2<t_fab):\r\n        t_crt=-(pady / 2) - crt_offset\r\n        h_crt=h_fab+(pady/2-math.fabs(t_fab))+2*crt_offset\r\n    if (pady/2>t_fab+h_fab):\r\n        t_crt = t_fab  - crt_offset\r\n        h_crt=h_fab+(pady/2-math.fabs(t_fab))+2*crt_offset\r\n    \r\n    \r\n    print(footprint_name)\r\n    \r\n    # init kicad footprint\r\n    kicad_mod = Footprint(footprint_name)\r\n    kicad_mod.setDescription(description)\r\n    kicad_mod.setTags(tags)\r\n   \r\n    # create pads\r\n    keepout=[]\r\n    if not 1 in missing_pins:\r\n        kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=[0, 0], size=pad, drill=ddrill,\r\n                             layers=['*.Cu', '*.Mask']))\r\n        keepout=keepout+addKeepoutRect(0,0,pad[0]+2*min_pad_distance+2*lw_slk, pad[1]+2*min_pad_distance+2*lw_slk)\r\n    for x in range(2, pins + 1):\r\n        if not x in missing_pins:\r\n            kicad_mod.append(Pad(number=x, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=[(x - 1) * rm, 0], size=pad,\r\n                                 drill=ddrill, layers=['*.Cu', '*.Mask']))\r\n            if (padx/pady)<1.05 and (padx/pady)>.95:\r\n                keepout=keepout+addKeepoutRect((x - 1) * rm,0,pad[0]+2*min_pad_distance+2*lw_slk, pad[1]+2*min_pad_distance+2*lw_slk)\r\n            else:\r\n                keepout=keepout+addKeepoutRound((x - 1) * rm,0,pad[0]+2*min_pad_distance+2*lw_slk, pad[1]+2*min_pad_distance+2*lw_slk)\r\n    # set general values\r\n    kicad_mod.append(Text(type='reference', text='REF**', at=[(pins-1) / 2 * rm, min(-pady/2,t_slk) - txt_offset], layer='F.SilkS'))\r\n    kicad_mod.append(Text(type='user', text='%R', at=[(pins-1) / 2 * rm, t_fab +h_fab/2], layer='F.Fab'))\r\n    kicad_mod.append(Text(type='value', text=footprint_name, at=[(pins-1) / 2 * rm, t_fab+h_fab + txt_offset], layer='F.Fab'))\r\n    \r\n    # create FAB-layer\r\n    pin1TL=True\r\n    pin1size=min(1, h_fab/2)\r\n    if top_offset>h_fab/2:\r\n        bevelRectBL(kicad_mod, x=[l_fab, t_fab], size=[w_fab, h_fab], bevel_size=pin1size, layer='F.Fab', width=lw_fab)\r\n        pin1TL=False\r\n    else:\r\n        bevelRectTL(kicad_mod, x=[l_fab, t_fab], size=[w_fab, h_fab], bevel_size=pin1size, layer='F.Fab', width=lw_fab)\r\n        pin1TL=True\r\n    \r\n    # create SILKSCREEN-layer\r\n    addRectWithKeepout(kicad_mod, l_slk, t_slk, w_slk, h_slk, keepouts=keepout, layer='F.SilkS', width=lw_slk)\r\n    if pin1TL:\r\n        addPolyLineWithKeepout(kicad_mod, [\r\n                                            [l_slk-2*lw_slk, t_slk+pin1size], \r\n                                            [l_slk-2*lw_slk, t_slk-2*lw_slk], \r\n                                            [l_slk+pin1size, t_slk-2*lw_slk], \r\n                                            ], keepouts=keepout, layer='F.SilkS', width=lw_slk)\r\n    else:\r\n        addPolyLineWithKeepout(kicad_mod, [\r\n                                            [l_slk-2*lw_slk, t_slk+h_slk-pin1size], \r\n                                            [l_slk-2*lw_slk, t_slk+h_slk+2*lw_slk], \r\n                                            [l_slk+pin1size, t_slk+h_slk+2*lw_slk], \r\n                                            ], keepouts=keepout, layer='F.SilkS', width=lw_slk)\r\n    \r\n    # create courtyard\r\n    kicad_mod.append(\r\n        RectLine(start=[roundCrt(l_crt), roundCrt(t_crt)], end=[roundCrt(l_crt + w_crt), roundCrt(t_crt + h_crt)],\r\n                 layer='F.CrtYd', width=lw_crt))\r\n     \r\n    # add model\r\n    kicad_mod.append(Model(filename=\"${KISYS3DMOD}/\"+lib_name + \".3dshapes/\" + footprint_name + \".wrl\",\r\n                           at=[0, 0, 0], scale=[1,1,1], rotate=[0, 0, 0]))\r\n    \r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(footprint_name + '.kicad_mod')\r\n\r\n    \r\n\r\n\r\ndef makeSIPHorizontal(pins, rm, ddrill, pad, package_size, left_offset, pin_bottom_offset, footprint_name, description, tags, lib_name, missing_pins=[]):\r\n    padx=pad[0]\r\n    pady=pad[1]\r\n    \r\n    w_fab=package_size[0]\r\n    h_fab=package_size[2]\r\n    l_fab=-left_offset\r\n    t_fab=-pin_bottom_offset-h_fab\r\n    \r\n    h_slk = h_fab + 2 * slk_offset\r\n    w_slk = w_fab + 2 * slk_offset\r\n    l_slk = l_fab - slk_offset\r\n    t_slk = t_fab-slk_offset\r\n    \r\n    w_crt = w_fab + 2 * crt_offset\r\n    h_crt = h_fab+pin_bottom_offset+pad[1]/2 + 2 * crt_offset\r\n    l_crt = min(l_fab, -padx / 2) - crt_offset\r\n    t_crt = t_fab  - crt_offset\r\n\r\n    # Pin 1 maker\r\n    l_pin1 = l_slk + left_offset - padx / 2 - 2 * lw_slk\r\n    h_pin1 = pin_bottom_offset + pady / 2 - lw_slk\r\n    \r\n    print(footprint_name)\r\n    \r\n    # init kicad footprint\r\n    kicad_mod = Footprint(footprint_name)\r\n    kicad_mod.setDescription(description)\r\n    kicad_mod.setTags(tags)\r\n   \r\n    # create pads\r\n    keepout=[]\r\n    if not 1 in missing_pins:\r\n        kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=[0, 0], size=pad, drill=ddrill,\r\n                             layers=['*.Cu', '*.Mask']))\r\n        keepout=keepout+addKeepoutRect(0,0,pad[0]+2*min_pad_distance+2*lw_slk, pad[1]+2*min_pad_distance+2*lw_slk)\r\n        kicad_mod.append(Line(start=[-lw_fab/2, 0], end=[-lw_fab/2,-pin_bottom_offset], layer='F.Fab', width=lw_fab))\r\n        kicad_mod.append(Line(start=[lw_fab/2, 0], end=[lw_fab/2,-pin_bottom_offset], layer='F.Fab', width=lw_fab))\r\n    for x in range(2, pins + 1):\r\n        if not x in missing_pins:\r\n            kicad_mod.append(Pad(number=x, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=[(x - 1) * rm, 0], size=pad,\r\n                                 drill=ddrill, layers=['*.Cu', '*.Mask']))\r\n            kicad_mod.append(Line(start=[(x - 1) * rm-lw_fab/2, 0], end=[(x - 1) * rm-lw_fab/2,-pin_bottom_offset], layer='F.Fab', width=lw_fab))\r\n            kicad_mod.append(Line(start=[(x - 1) * rm+lw_fab/2, 0], end=[(x - 1) * rm+lw_fab/2,-pin_bottom_offset], layer='F.Fab', width=lw_fab))\r\n            if (padx/pady)<1.05 and (padx/pady)>.95:\r\n                keepout=keepout+addKeepoutRect((x - 1) * rm,0,pad[0]+2*min_pad_distance+2*lw_slk, pad[1]+2*min_pad_distance+2*lw_slk)\r\n            else:\r\n                keepout=keepout+addKeepoutRound((x - 1) * rm,0,pad[0]+2*min_pad_distance+2*lw_slk, pad[1]+2*min_pad_distance+2*lw_slk)\r\n    # set general values\r\n    kicad_mod.append(Text(type='reference', text='REF**', at=[(pins-1) / 2 * rm, min(-pady/2,t_slk) - txt_offset], layer='F.SilkS'))\r\n    kicad_mod.append(Text(type='user', text='%R', at=[(pins-1) / 2 * rm, t_fab +h_fab/2], layer='F.Fab'))\r\n    kicad_mod.append(Text(type='value', text=footprint_name, at=[(pins-1) / 2 * rm, pady/2 + txt_offset], layer='F.Fab'))\r\n    \r\n    # create FAB-layer\r\n    pin1size=min(1, h_fab/2)\r\n    bevelRectBL(kicad_mod, x=[l_fab, t_fab], size=[w_fab, h_fab], bevel_size=pin1size, layer='F.Fab', width=lw_fab)\r\n    \r\n    # create SILKSCREEN-layer\r\n    addRectWithKeepout(kicad_mod, l_slk, t_slk, w_slk, h_slk, keepouts=keepout, layer='F.SilkS', width=lw_slk)\r\n    addPolyLineWithKeepout(kicad_mod, [\r\n                                        [l_pin1, t_slk + h_slk],\r\n                                        [l_pin1, t_slk + h_slk + h_pin1]\r\n                                        ], layer='F.SilkS', width=lw_slk)\r\n\r\n    # create courtyard\r\n    kicad_mod.append(\r\n        RectLine(start=[roundCrt(l_crt), roundCrt(t_crt)], end=[roundCrt(l_crt + w_crt), roundCrt(t_crt + h_crt)],\r\n                 layer='F.CrtYd', width=lw_crt))\r\n     \r\n    # add model\r\n    kicad_mod.append(Model(filename=\"${KISYS3DMOD}/\"+lib_name + \".3dshapes/\" + footprint_name + \".wrl\",\r\n                           at=[0, 0, 0], scale=[1,1,1], rotate=[0, 0, 0]))\r\n    \r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(footprint_name + '.kicad_mod')\r\n\r\n\r\ndef makeResistorSIP(pins, footprint_name, description):\r\n    rm = 2.54\r\n    h = 2.5\r\n    leftw = 1.29\r\n    ddrill = 0.8\r\n    padx = 1.6\r\n    pady = 1.6\r\n    \r\n    w = (pins - 1) * rm + 2 * leftw\r\n    left = -leftw\r\n    top = -h / 2\r\n    h_slk = max(h, pady) + 2 * slk_offset\r\n    w_slk = w + 2 * slk_offset\r\n    l_slk = -leftw - slk_offset\r\n    r_slk = l_slk + w_slk\r\n    t_slk = -h_slk / 2\r\n    w_crt = w_slk + 2 * crt_offset\r\n    h_crt = max(h_slk, pady) + 2 * crt_offset\r\n    l_crt = min(l_slk, -padx / 2) - crt_offset\r\n    t_crt = min(t_slk, -pady / 2) - crt_offset\r\n    \r\n    lib_name = \"Resistors_ThroughHole\"\r\n    \r\n    print(footprint_name)\r\n    \r\n    # init kicad footprint\r\n    kicad_mod = Footprint(footprint_name)\r\n    kicad_mod.setDescription(description)\r\n    kicad_mod.setTags(\"R\")\r\n    \r\n    # set general values\r\n    kicad_mod.append(Text(type='reference', text='REF**', at=[pins / 2 * rm, t_slk - txt_offset], layer='F.SilkS'))\r\n    kicad_mod.append(Text(type='value', text=footprint_name, at=[pins / 2 * rm, h_slk / 2 + txt_offset], layer='F.Fab'))\r\n    \r\n    # create FAB-layer\r\n    kicad_mod.append(RectLine(start=[left, top], end=[left + w, top + h], layer='F.Fab', width=lw_fab))\r\n    kicad_mod.append(Line(start=[0.5 * rm, top], end=[0.5 * rm, top + h], layer='F.Fab', width=lw_fab))\r\n    \r\n    # create SILKSCREEN-layer\r\n    kicad_mod.append(RectLine(start=[l_slk, t_slk], end=[l_slk + w_slk, t_slk + h_slk], layer='F.SilkS'))\r\n    kicad_mod.append(Line(start=[0.5 * rm, t_slk], end=[0.5 * rm, t_slk + h_slk], layer='F.SilkS'))\r\n    \r\n    # create courtyard\r\n    kicad_mod.append(\r\n        RectLine(start=[roundCrt(l_crt), roundCrt(t_crt)], end=[roundCrt(l_crt + w_crt), roundCrt(t_crt + h_crt)],\r\n                 layer='F.CrtYd', width=lw_crt))\r\n    \r\n    # create pads\r\n    kicad_mod.append(Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=[0, 0], size=[padx, pady], drill=ddrill,\r\n                         layers=['*.Cu', '*.Mask']))\r\n    for x in range(2, pins + 1):\r\n        kicad_mod.append(Pad(number=x, type=Pad.TYPE_THT, shape=Pad.SHAPE_OVAL, at=[(x - 1) * rm, 0], size=[padx, pady],\r\n                             drill=ddrill, layers=['*.Cu', '*.Mask']))\r\n    \r\n    # add model\r\n    kicad_mod.append(Model(filename=\"${KISYS3DMOD}/\"+lib_name + \".3dshapes/\" + footprint_name + \".wrl\",\r\n                           at=[0, 0, 0], scale=[1 / 2.54, 1 / 2.54, 1 / 2.54], rotate=[0, 0, 0]))\r\n    \r\n    # print render tree\r\n    # print(kicad_mod.getRenderTree())\r\n    # print(kicad_mod.getCompleteRenderTree())\r\n    \r\n    # write file\r\n    file_handler = KicadFileHandler(kicad_mod)\r\n    file_handler.writeFile(footprint_name + '.kicad_mod')\r\n"
  },
  {
    "path": "scripts/tools/footprint_scripts_terminal_blocks.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport math\n\n# ensure that the kicad-footprint-generator directory is available\n#sys.path.append(os.environ.get('KIFOOTPRINTGENERATOR'))  # enable package import from parent directory\n#sys.path.append(\"D:\\hardware\\KiCAD\\kicad-footprint-generator\")  # enable package import from parent directory\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\",\"kicad_mod\")) # load kicad_mod path\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\n\nfrom KicadModTree import *  # NOQA\nfrom drawing_tools import *  # NOQA\nfrom math import sqrt\n\ncrt_offset = 0.5 # different for connectors\nslk_offset = lw_slk\n\n#\n#  +----------------------------------------+                      ^\n#  |       H           H           H        | ^                    |\n#  |                                        | |                    |\n#  |      OOO         OOO         OOO       | |secondHoleOffset    | package_height\n#  |     OOOOO       OOOOO       OOOOO      | v                    |                  ^\n#  |      OOO         OOO         OOO       |                      |                  |\n#  +----------------------------------------+ ^                    |                  | leftbottom_offset\n#  |                                        | | bevel_height       |                  |\n#  +----------------------------------------+ v                    v                  v\n#          <--- rm ---->\n#  <------>leftbottom_offset[0]     <------->leftbottom_offset[2] (or leftbottom_offset[0]  if len(leftbottom_offset)==2)\n#\n#\n#\ndef makeTerminalBlockStd(footprint_name, pins, rm, package_height, leftbottom_offset, ddrill, pad, screw_diameter, bevel_height, slit_screw=True, screw_pin_offset=[0,0], secondHoleDiameter=0, secondHoleOffset=[0,0], thirdHoleDiameter=0, thirdHoleOffset=[0,0], fourthHoleDiameter=0, fourthHoleOffset=[0,0],secondDrillDiameter=0,secondDrillOffset=[0,0],secondDrillPad=[0,0],nibbleSize=[],nibblePos=[], fabref_offset=[0,0],\n                        stackable=False,\n                        tags_additional=[], lib_name=\"${{KISYS3DMOD}}/Connectors_Terminal_Blocks\", classname=\"Connectors_Terminal_Blocks\", classname_description=\"terminal block\", webpage=\"\", script_generated_note=\"\"):\n\n    package_size=[2*leftbottom_offset[0]+(pins-1)*rm, package_height];\n    if len(leftbottom_offset)==3:\n        package_size=[leftbottom_offset[0]+leftbottom_offset[2]+(pins-1)*rm, package_height];\n\n    h_fab = package_size[1]\n    w_fab = package_size[0]\n    l_fab = -leftbottom_offset[0]\n    t_fab = -(h_fab-leftbottom_offset[1])\n\n    h_slk = h_fab + 2 * slk_offset\n    w_slk = w_fab + 2 * slk_offset\n    l_slk = l_fab - slk_offset\n    t_slk = t_fab - slk_offset\n\n    h_crt = h_fab + 2 * crt_offset\n    w_crt = w_fab + (0 if stackable else 2 * crt_offset)\n    l_crt = l_fab - (0 if stackable else crt_offset)\n    t_crt = t_fab - crt_offset\n\n\n    text_size = w_fab*0.6\n    fab_text_size_max = 1.0\n    if text_size < fab_text_size_min:\n        text_size = fab_text_size_min\n    elif text_size > fab_text_size_max:\n        text_size = fab_text_size_max\n    text_size = round(text_size, 2)\n    text_size = [text_size,text_size]\n    text_t = text_size[0] * 0.15\n\n\n    description = \"{2}, {0:d} pins, pitch {1:.3g}mm, size {3:.3g}x{4:.3g}mm^2, drill diamater {5:.3g}mm, pad diameter {6:.3g}mm, see {7:s}\"\\\n        .format(pins, rm, classname_description, package_size[0], package_size[1], ddrill, max(pad), webpage)\n    tags = \"THT {2} pitch {1:.3g}mm size {3:.3g}x{4:.3g}mm^2 drill {5:.3g}mm pad {6:.3g}mm\"\\\n        .format(pins, rm, classname_description, package_size[0], package_size[1], ddrill, max(pad))\n\n    if len(script_generated_note)>0:\n        description=description+\", \"+script_generated_note\n\n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n\n    print(footprint_name)\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n\n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    offset=[0,0]\n    kicad_modg = Translation(offset[0], offset[1])\n    kicad_mod.append(kicad_modg)\n\n    # set general values\n    kicad_modg.append(Text(type='reference', text='REF**', at=[l_fab+w_fab/2, t_slk - txt_offset], layer='F.SilkS'))\n    if (type(fabref_offset) in (tuple, list)):\n        kicad_modg.append(Text(type='user', text='%R', at=[l_fab+w_fab/2+fabref_offset[0], t_fab+h_fab/2+fabref_offset[1]], layer='F.Fab', size=text_size ,thickness=text_t))\n    else:\n        kicad_modg.append(Text(type='user', text='%R', at=[l_fab+w_fab/2,  t_slk - txt_offset], layer='F.Fab', size=text_size ,thickness=text_t))\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[l_fab+w_fab/2, t_slk + h_slk + txt_offset], layer='F.Fab'))\n\n\n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0\n\n    pad_type = Pad.TYPE_THT\n    pad_shape1 = Pad.SHAPE_RECT\n    pad_shapeother = Pad.SHAPE_CIRCLE\n    if pad[0] != pad[1]:\n        pad_shapeother = Pad.SHAPE_OVAL\n\n    extradrill1_type = Pad.TYPE_NPTH\n    if secondDrillPad[0] > secondDrillDiameter or secondDrillPad[1] > secondDrillDiameter:\n        extradrill1_type = Pad.TYPE_THT\n\n    if secondDrillDiameter>0:\n        if secondDrillPad[0] < secondDrillDiameter:\n            secondDrillPad[0] = secondDrillDiameter\n        if secondDrillPad[1] < secondDrillDiameter:\n            secondDrillPad[1] = secondDrillDiameter\n\n    pad_shape_extra = Pad.SHAPE_CIRCLE\n    if secondDrillPad[0] != secondDrillPad[1]:\n        pad_shape_extra = Pad.SHAPE_OVAL\n\n    pad_layers = Pad.LAYERS_THT\n    keepouts=[];\n    for p in range(1, pins + 1):\n        pextra=0\n        if secondDrillPad[0]>0:\n            pextra=p\n        if p == 1:\n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=ddrill, layers=pad_layers))\n            keepouts=keepouts+addKeepoutRect(x1, y1, pad[0]+8*slk_offset, pad[1]+8*slk_offset)\n            if secondDrillDiameter>0:\n                if extradrill1_type == Pad.TYPE_NPTH:\n                    num = \"\"\n                    extra_shape = pad_shape_extra\n                else:\n                    num = p\n                    extra_shape = Pad.SHAPE_RECT\n                kicad_modg.append(Pad(number=num, type=extradrill1_type, shape=extra_shape, at=[x1+secondDrillOffset[0], y1+secondDrillOffset[1]], size=secondDrillPad, drill=secondDrillDiameter, layers=pad_layers))\n                keepouts=keepouts+addKeepoutRect(x1+secondDrillOffset[0], y1+secondDrillOffset[1], max(secondDrillPad[0],secondDrillDiameter)+8*slk_offset, max(secondDrillPad[0],secondDrillDiameter)+8*slk_offset)\n        else:\n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=ddrill, layers=pad_layers))\n            if secondDrillPad[0]!=secondDrillPad[1]:\n                keepouts=keepouts+addKeepoutRect(x1, y1, pad[0]+8*slk_offset, pad[1]+8*slk_offset)\n            else:\n                keepouts=keepouts+addKeepoutRound(x1, y1, pad[0]+8*slk_offset, pad[0]+8*slk_offset)\n            if secondDrillDiameter>0:\n                if extradrill1_type == Pad.TYPE_NPTH:\n                    num = \"\"\n                else:\n                    num = p\n                kicad_modg.append(Pad(number=num, type=extradrill1_type, shape=pad_shape_extra, at=[x1+secondDrillOffset[0], y1+secondDrillOffset[1]], size=secondDrillPad, drill=secondDrillDiameter, layers=pad_layers))\n                keepouts=keepouts+addKeepoutRect(x1+secondDrillOffset[0], y1+secondDrillOffset[1], max(secondDrillPad[0],secondDrillDiameter)+8*slk_offset, max(secondDrillPad[0],secondDrillDiameter)+8*slk_offset)\n\n        x1=x1+rm\n\n    # create Body\n    if len(bevel_height)>0:\n        chamfer = min(h_fab/4, 2, bevel_height[0])\n    else:\n        chamfer = min(h_fab/4, 2)\n    bevelRectBL(kicad_modg,  [l_fab,t_fab], [w_fab,h_fab], 'F.Fab', lw_fab, bevel_size=chamfer)\n    for bh in bevel_height:\n        kicad_modg.append(Line(start=[l_fab, t_fab + h_fab-bh], end=[l_fab+w_fab, t_fab + h_fab-bh], layer='F.Fab', width=lw_fab))\n        addHLineWithKeepout(kicad_modg,l_slk, l_slk+w_slk, t_fab + h_fab-bh, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n    addRectWithKeepout(kicad_modg, l_slk, t_slk, w_slk, h_slk, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n    # screws + other repeated features\n    if screw_diameter>0:\n        for p in range(1,pins+1):\n            if screw_diameter>0:\n                if slit_screw:\n                    addSlitScrew(kicad_modg, (p-1)*rm+screw_pin_offset[0], 0+screw_pin_offset[1], screw_diameter/2, 'F.Fab', lw_fab, roun=0.001)\n                    addSlitScrewWithKeepouts(kicad_modg, (p-1)*rm+screw_pin_offset[0], 0+screw_pin_offset[1], screw_diameter/2+3*slk_offset, 'F.SilkS', lw_slk, keepouts, roun=0.001)\n                else:\n                    addCrossScrew(kicad_modg, (p-1)*rm+screw_pin_offset[0], 0+screw_pin_offset[1], screw_diameter/2, 'F.Fab', lw_fab, roun=0.001)\n                    addCrossScrewWithKeepouts(kicad_modg, (p-1)*rm+screw_pin_offset[0], 0+screw_pin_offset[1], screw_diameter/2+3*slk_offset, 'F.SilkS', lw_slk, keepouts, roun=0.001)\n\n            if not (type(secondHoleDiameter) in (tuple, list)) and secondHoleDiameter>0 and (p-1)*rm+secondHoleOffset[0]<l_fab+w_fab:\n                kicad_modg.append(Circle(center=[(p-1)*rm+secondHoleOffset[0], 0+secondHoleOffset[1]], radius=secondHoleDiameter/2, layer='F.Fab', width=lw_fab))\n                addCircleWithKeepout(kicad_modg, (p-1)*rm+secondHoleOffset[0], 0+secondHoleOffset[1], secondHoleDiameter/2, 'F.SilkS', lw_slk, keepouts)\n            if not (type(thirdHoleDiameter) in (tuple, list)) and thirdHoleDiameter>0 and (p-1)*rm+thirdHoleOffset[0]<l_fab+w_fab:\n                kicad_modg.append(Circle(center=[(p-1)*rm+thirdHoleOffset[0], 0+thirdHoleOffset[1]], radius=thirdHoleDiameter/2, layer='F.Fab', width=lw_fab))\n                addCircleWithKeepout(kicad_modg, (p-1)*rm+thirdHoleOffset[0], 0+thirdHoleOffset[1], thirdHoleDiameter/2, 'F.SilkS', lw_slk, keepouts)\n            if not (type(fourthHoleDiameter) in (tuple, list)) and fourthHoleDiameter>0 and (p-1)*rm+fourthHoleOffset[0]<l_fab+w_fab:\n                kicad_modg.append(Circle(center=[(p-1)*rm+fourthHoleOffset[0], 0+fourthHoleOffset[1]], radius=fourthHoleDiameter/2, layer='F.Fab', width=lw_fab))\n                addCircleWithKeepout(kicad_modg, (p-1)*rm+fourthHoleOffset[0], 0+fourthHoleOffset[1], fourthHoleDiameter/2, 'F.SilkS', lw_slk, keepouts)\n            if (type(secondHoleDiameter) in (tuple, list)) and (p-1)*rm+secondHoleOffset[0]<l_fab+w_fab:\n                kicad_modg.append(RectLine(start=[(p-1)*rm+secondHoleOffset[0]-secondHoleDiameter[0]/2, 0+secondHoleOffset[1]-secondHoleDiameter[1]/2], end=[(p-1)*rm+secondHoleOffset[0]+secondHoleDiameter[0]/2, 0+secondHoleOffset[1]+secondHoleDiameter[1]/2], layer='F.Fab', width=lw_fab))\n                addRectWithKeepout(kicad_modg, (p-1)*rm+secondHoleOffset[0]-secondHoleDiameter[0]/2, 0+secondHoleOffset[1]-secondHoleDiameter[1]/2, secondHoleDiameter[0],secondHoleDiameter[1], 'F.SilkS', lw_slk, keepouts)\n            if (type(thirdHoleDiameter) in (tuple, list)) and (p-1)*rm+thirdHoleOffset[0]<l_fab+w_fab:\n                kicad_modg.append(RectLine(start=[(p-1)*rm+thirdHoleOffset[0]-thirdHoleDiameter[0]/2, 0+thirdHoleOffset[1]-thirdHoleDiameter[1]/2], end=[(p-1)*rm+thirdHoleOffset[0]+thirdHoleDiameter[0]/2, 0+thirdHoleOffset[1]+thirdHoleDiameter[1]/2], layer='F.Fab', width=lw_fab))\n                addRectWithKeepout(kicad_modg, (p-1)*rm+thirdHoleOffset[0]-thirdHoleDiameter[0]/2, 0+thirdHoleOffset[1]-thirdHoleDiameter[1]/2, thirdHoleDiameter[0],thirdHoleDiameter[1], 'F.SilkS', lw_slk, keepouts)\n            if (type(fourthHoleDiameter) in (tuple, list)) and (p-1)*rm+fourthHoleOffset[0]<l_fab+w_fab:\n                kicad_modg.append(RectLine(start=[(p-1)*rm+fourthHoleOffset[0]-fourthHoleDiameter[0]/2, 0+fourthHoleOffset[1]-fourthHoleDiameter[1]/2], end=[(p-1)*rm+fourthHoleOffset[0]+fourthHoleDiameter[0]/2, 0+fourthHoleOffset[1]+fourthHoleDiameter[1]/2], layer='F.Fab', width=lw_fab))\n                addRectWithKeepout(kicad_modg, (p-1)*rm+fourthHoleOffset[0]-fourthHoleDiameter[0]/2, 0+fourthHoleOffset[1]-fourthHoleDiameter[1]/2, fourthHoleDiameter[0],fourthHoleDiameter[1], 'F.SilkS', lw_slk, keepouts)\n\n    #nibble\n    if len(nibbleSize)==2 and len(nibblePos)==2:\n        kicad_modg.append(RectLine(start=[l_fab+nibblePos[0], t_fab+nibblePos[1]], end=[l_fab+nibblePos[0]+nibbleSize[0], t_fab+nibblePos[1]+nibbleSize[1]], layer='F.Fab', width=lw_fab))\n        addRectWithKeepout(kicad_modg, l_fab+nibblePos[0]-slk_offset, t_fab+nibblePos[1]-slk_offset, nibbleSize[0],nibbleSize[1]+2*slk_offset, 'F.SilkS', lw_slk, keepouts)\n\n\n\n    # create SILKSCREEN-pin1-marker\n    kicad_modg.append(Line(start=[l_slk-2*lw_slk, t_slk + h_slk-chamfer], end=[l_slk-2*lw_slk, t_slk + h_slk+2*lw_slk], layer='F.SilkS', width=lw_slk))\n    kicad_modg.append(Line(start=[l_slk-2*lw_slk, t_slk + h_slk+2*lw_slk], end=[l_slk-2*lw_slk+chamfer, t_slk + h_slk+2*lw_slk], layer='F.SilkS', width=lw_slk))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\n                              end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\n                              layer='F.CrtYd', width=lw_crt))\n\n\n    # add model\n    kicad_modg.append(\n        Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=[0,0,0], scale=[1,1,1], rotate=[0,0,0]))\n\n    #debug_draw_keepouts(kicad_modg,keepouts)\n\n    # write file\n    if \"/\" in lib_name:\n        fp_lib_name = lib_name.split('/')[-1]\n    elif \"\\\\\" in lib_name:\n        fp_lib_name = lib_name.split('\\\\')[-1]\n\n    output_dir = fp_lib_name + '.pretty' + os.sep\n    if not os.path.isdir(output_dir):\n        os.makedirs(output_dir)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(output_dir + footprint_name + '.kicad_mod')\n\n\n#\n#  +----------------------------------------+                      ^\n#  |       H           H           H        | ^                    |\n#  |  -----------                           | |                    |                                       ^\n#  |  |   OOO   |     OOO         OOO       | |secondHoleOffset    | package_height                        |\n#  |  |  OOOOO  |    OOOOO       OOOOO      | v                    |                  ^                    | opening[1]\n#  |  |   OOO   |     OOO         OOO       |                      |                  |                    |\n#  +----------------------------------------+ ^                    |                  | leftbottom_offset  x\n#  |                                        | | bevel_height       |                  |                    | opening_yoffset\n#  +----------------------------------------+ v                    v                  v                    v\n#          <--- rm ---->\n#  <------>leftbottom_offset[0]     <------->leftbottom_offset[2] (or leftbottom_offset[0]  if len(leftbottom_offset)==2)\n#     <---------> opening[0]\n#\n#\ndef makeTerminalBlockVertical(footprint_name, pins, rm, package_height, leftbottom_offset, ddrill, pad, opening, opening_yoffset, bevel_height, opening_xoffset=0, secondHoleDiameter=0, secondHoleOffset=[0,0], thirdHoleDiameter=0, thirdHoleOffset=[0,0], fourthHoleDiameter=0, fourthHoleOffset=[0,0],secondDrillDiameter=0,secondDrillOffset=[0,0],secondDrillPad=[0,0],nibbleSize=[],nibblePos=[], fabref_offset=[0,0],\n                        stackable=False,\n                        tags_additional=[], lib_name=\"${{KISYS3DMOD}}/Connectors_Terminal_Blocks\", classname=\"Connectors_Terminal_Blocks\", classname_description=\"terminal block\", webpage=\"\", script_generated_note=\"\"):\n\n    package_size=[2*leftbottom_offset[0]+(pins-1)*rm, package_height];\n    if len(leftbottom_offset)==3:\n        package_size=[leftbottom_offset[0]+leftbottom_offset[2]+(pins-1)*rm, package_height];\n\n    h_fab = package_size[1]\n    w_fab = package_size[0]\n    l_fab = -leftbottom_offset[0]\n    t_fab = -(h_fab-leftbottom_offset[1])\n\n    h_slk = h_fab + 2 * slk_offset\n    w_slk = w_fab + 2 * slk_offset\n    l_slk = l_fab - slk_offset\n    t_slk = t_fab - slk_offset\n\n    h_crt = h_fab + 2 * crt_offset\n    w_crt = w_fab + (0 if stackable else 2 * crt_offset)\n    l_crt = l_fab - (0 if stackable else crt_offset)\n    t_crt = t_fab - crt_offset\n\n\n    text_size = w_fab*0.6\n    fab_text_size_max = 1.0\n    if text_size < fab_text_size_min:\n        text_size = fab_text_size_min\n    elif text_size > fab_text_size_max:\n        text_size = fab_text_size_max\n    text_size = round(text_size, 2)\n    text_size = [text_size,text_size]\n    text_t = text_size[0] * 0.15\n\n\n    description = \"{2}, vertical (cable from top), {0:d} pins, pitch {1:.3g}mm, size {3:.3g}x{4:.3g}mm^2, drill diamater {5:.3g}mm, pad diameter {6:.3g}mm, see {7}, script-generated with \"\\\n        .format(pins, rm, classname_description, package_size[0], package_size[1], ddrill, max(pad), webpage)\n    tags = \"THT {2} vertical pitch {1:.3g}mm size {3:.3g}x{4:.3g}mm^2 drill {5:.3g}mm pad {6:.3g}mm\"\\\n        .format(pins, rm, classname_description, package_size[0], package_size[1], ddrill, max(pad))\n\n    if len(script_generated_note)>0:\n        description=description+\", \"+script_generated_note\n\n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n\n    print(footprint_name)\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n\n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    offset=[0,0]\n    kicad_modg = Translation(offset[0], offset[1])\n    kicad_mod.append(kicad_modg)\n\n    # set general values\n    kicad_modg.append(Text(type='reference', text='REF**', at=[l_fab+w_fab/2, t_slk - txt_offset], layer='F.SilkS'))\n    if (type(fabref_offset) in (tuple, list)):\n        kicad_modg.append(Text(type='user', text='%R', at=[l_fab+w_fab/2+fabref_offset[0], t_fab+h_fab/2+fabref_offset[1]], layer='F.Fab', size=text_size ,thickness=text_t))\n    else:\n        kicad_modg.append(Text(type='user', text='%R', at=[l_fab+w_fab/2,  t_slk - txt_offset], layer='F.Fab', size=text_size ,thickness=text_t))\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[l_fab+w_fab/2, t_slk + h_slk + txt_offset], layer='F.Fab'))\n\n\n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0\n\n    pad_type = Pad.TYPE_THT\n    pad_shape1 = Pad.SHAPE_RECT\n    pad_shapeother = Pad.SHAPE_CIRCLE\n    if pad[0] != pad[1]:\n        pad_shapeother = Pad.SHAPE_OVAL\n\n    extradrill1_type = Pad.TYPE_NPTH\n    if secondDrillPad[0] > secondDrillDiameter or secondDrillPad[1] > secondDrillDiameter:\n        extradrill1_type = Pad.TYPE_THT\n\n    if secondDrillDiameter>0:\n        if secondDrillPad[0] < secondDrillDiameter:\n            secondDrillPad[0] = secondDrillDiameter\n        if secondDrillPad[1] < secondDrillDiameter:\n            secondDrillPad[1] = secondDrillDiameter\n\n    pad_shape_extra = Pad.SHAPE_CIRCLE\n    if secondDrillPad[0] != secondDrillPad[1]:\n        pad_shape_extra = Pad.SHAPE_OVAL\n\n    pad_layers = Pad.LAYERS_THT\n    keepouts=[];\n\n    for p in range(1, pins + 1):\n\n        if p == 1:\n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=ddrill, layers=pad_layers))\n            keepouts=keepouts+addKeepoutRect(x1, y1, pad[0]+8*slk_offset, pad[1]+8*slk_offset)\n            if secondDrillDiameter>0:\n                if extradrill1_type == Pad.TYPE_NPTH:\n                    num = \"\"\n                    extra_shape = pad_shape_extra\n                else:\n                    num = p\n                    extra_shape = Pad.SHAPE_RECT\n                kicad_modg.append(Pad(number=num, type=extradrill1_type, shape=extra_shape, at=[x1+secondDrillOffset[0], y1+secondDrillOffset[1]], size=secondDrillPad, drill=secondDrillDiameter, layers=pad_layers))\n                keepouts=keepouts+addKeepoutRect(x1+secondDrillOffset[0], y1+secondDrillOffset[1], max(secondDrillPad[0],secondDrillDiameter)+8*slk_offset, max(secondDrillPad[0],secondDrillDiameter)+8*slk_offset)\n        else:\n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=ddrill, layers=pad_layers))\n            if pad[0]!=pad[1]:\n                keepouts=keepouts+addKeepoutRect(x1, y1, pad[0]+8*slk_offset, pad[1]+8*slk_offset)\n            else:\n                keepouts=keepouts+addKeepoutRound(x1, y1, pad[0]+8*slk_offset, pad[0]+8*slk_offset)\n            if secondDrillDiameter>0:\n                if extradrill1_type == Pad.TYPE_NPTH:\n                    num = \"\"\n                else:\n                    num = p\n                kicad_modg.append(Pad(number=num, type=extradrill1_type, shape=pad_shape_extra, at=[x1+secondDrillOffset[0], y1+secondDrillOffset[1]], size=secondDrillPad, drill=secondDrillDiameter, layers=pad_layers))\n                if secondDrillPad[0]!=secondDrillPad[1]:\n                    keepouts=keepouts+addKeepoutRect(x1+secondDrillOffset[0], y1+secondDrillOffset[1], max(secondDrillPad[0],secondDrillDiameter)+8*slk_offset, max(secondDrillPad[0],secondDrillDiameter)+8*slk_offset)\n                else:\n                    keepouts=keepouts+addKeepoutRound(x1+secondDrillOffset[0], y1+secondDrillOffset[1], max(secondDrillPad[0],secondDrillDiameter)+8*slk_offset, max(secondDrillPad[0],secondDrillDiameter)+8*slk_offset)\n\n        x1=x1+rm\n\n    # create Body\n    if len(bevel_height)>0:\n        chamfer = min(h_fab/4, 2, bevel_height[0])\n    else:\n        chamfer = min(h_fab/4, 2)\n    bevelRectBL(kicad_modg,  [l_fab,t_fab], [w_fab,h_fab], 'F.Fab', lw_fab, bevel_size=chamfer)\n    for bh in bevel_height:\n        kicad_modg.append(Line(start=[l_fab, t_fab + h_fab-bh], end=[l_fab+w_fab, t_fab + h_fab-bh], layer='F.Fab', width=lw_fab))\n        addHLineWithKeepout(kicad_modg,l_slk, l_slk+w_slk, t_fab + h_fab-bh, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n    addRectWithKeepout(kicad_modg, l_slk, t_slk, w_slk, h_slk, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n\n    # opening + other repeated features\n    for p in range(1,pins+1):\n        addRectWithKeepout(kicad_modg, (p-1)*rm-opening[0]/2-opening_xoffset, t_fab+h_fab-opening_yoffset-opening[1], opening[0], opening[1], 'F.SilkS', lw_slk, keepouts)\n        addRectWith(kicad_modg, (p-1)*rm-opening[0]/2-opening_xoffset, t_fab+h_fab-opening_yoffset-opening[1], opening[0], opening[1], 'F.Fab', lw_fab)\n\n        if not (type(secondHoleDiameter) in (tuple, list)) and secondHoleDiameter>0 and (p-1)*rm+secondHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(Circle(center=[(p-1)*rm+secondHoleOffset[0], 0+secondHoleOffset[1]], radius=secondHoleDiameter/2, layer='F.Fab', width=lw_fab))\n            addCircleWithKeepout(kicad_modg, (p-1)*rm+secondHoleOffset[0], 0+secondHoleOffset[1], secondHoleDiameter/2, 'F.SilkS', lw_slk, keepouts)\n        if not (type(thirdHoleDiameter) in (tuple, list)) and thirdHoleDiameter>0 and (p-1)*rm+thirdHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(Circle(center=[(p-1)*rm+thirdHoleOffset[0], 0+thirdHoleOffset[1]], radius=thirdHoleDiameter/2, layer='F.Fab', width=lw_fab))\n            addCircleWithKeepout(kicad_modg, (p-1)*rm+thirdHoleOffset[0], 0+thirdHoleOffset[1], thirdHoleDiameter/2, 'F.SilkS', lw_slk, keepouts)\n        if not (type(fourthHoleDiameter) in (tuple, list)) and fourthHoleDiameter>0 and (p-1)*rm+fourthHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(Circle(center=[(p-1)*rm+fourthHoleOffset[0], 0+fourthHoleOffset[1]], radius=fourthHoleDiameter/2, layer='F.Fab', width=lw_fab))\n            addCircleWithKeepout(kicad_modg, (p-1)*rm+fourthHoleOffset[0], 0+fourthHoleOffset[1], fourthHoleDiameter/2, 'F.SilkS', lw_slk, keepouts)\n        if (type(secondHoleDiameter) in (tuple, list)) and (p-1)*rm+secondHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(RectLine(start=[(p-1)*rm+secondHoleOffset[0]-secondHoleDiameter[0]/2, 0+secondHoleOffset[1]-secondHoleDiameter[1]/2], end=[(p-1)*rm+secondHoleOffset[0]+secondHoleDiameter[0]/2, 0+secondHoleOffset[1]+secondHoleDiameter[1]/2], layer='F.Fab', width=lw_fab))\n            addRectWithKeepout(kicad_modg, (p-1)*rm+secondHoleOffset[0]-secondHoleDiameter[0]/2, 0+secondHoleOffset[1]-secondHoleDiameter[1]/2, secondHoleDiameter[0],secondHoleDiameter[1], 'F.SilkS', lw_slk, keepouts)\n        if (type(thirdHoleDiameter) in (tuple, list)) and (p-1)*rm+thirdHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(RectLine(start=[(p-1)*rm+thirdHoleOffset[0]-thirdHoleDiameter[0]/2, 0+thirdHoleOffset[1]-thirdHoleDiameter[1]/2], end=[(p-1)*rm+thirdHoleOffset[0]+thirdHoleDiameter[0]/2, 0+thirdHoleOffset[1]+thirdHoleDiameter[1]/2], layer='F.Fab', width=lw_fab))\n            addRectWithKeepout(kicad_modg, (p-1)*rm+thirdHoleOffset[0]-thirdHoleDiameter[0]/2, 0+thirdHoleOffset[1]-thirdHoleDiameter[1]/2, thirdHoleDiameter[0],thirdHoleDiameter[1], 'F.SilkS', lw_slk, keepouts)\n        if (type(fourthHoleDiameter) in (tuple, list)) and (p-1)*rm+fourthHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(RectLine(start=[(p-1)*rm+fourthHoleOffset[0]-fourthHoleDiameter[0]/2, 0+fourthHoleOffset[1]-fourthHoleDiameter[1]/2], end=[(p-1)*rm+fourthHoleOffset[0]+fourthHoleDiameter[0]/2, 0+fourthHoleOffset[1]+fourthHoleDiameter[1]/2], layer='F.Fab', width=lw_fab))\n            addRectWithKeepout(kicad_modg, (p-1)*rm+fourthHoleOffset[0]-fourthHoleDiameter[0]/2, 0+fourthHoleOffset[1]-fourthHoleDiameter[1]/2, fourthHoleDiameter[0],fourthHoleDiameter[1], 'F.SilkS', lw_slk, keepouts)\n\n    #nibble\n    if len(nibbleSize)==2 and len(nibblePos)==2:\n        kicad_modg.append(RectLine(start=[l_fab+nibblePos[0], t_fab+nibblePos[1]], end=[l_fab+nibblePos[0]+nibbleSize[0], t_fab+nibblePos[1]+nibbleSize[1]], layer='F.Fab', width=lw_fab))\n        addRectWithKeepout(kicad_modg, l_fab+nibblePos[0]-slk_offset, t_fab+nibblePos[1]-slk_offset, nibbleSize[0],nibbleSize[1]+2*slk_offset, 'F.SilkS', lw_slk, keepouts)\n\n\n\n    # create SILKSCREEN-pin1-marker\n    kicad_modg.append(Line(start=[l_slk-2*lw_slk, t_slk + h_slk-chamfer], end=[l_slk-2*lw_slk, t_slk + h_slk+2*lw_slk], layer='F.SilkS', width=lw_slk))\n    kicad_modg.append(Line(start=[l_slk-2*lw_slk, t_slk + h_slk+2*lw_slk], end=[l_slk-2*lw_slk+chamfer, t_slk + h_slk+2*lw_slk], layer='F.SilkS', width=lw_slk))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\n                              end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\n                              layer='F.CrtYd', width=lw_crt))\n\n\n    # add model\n    kicad_modg.append(\n        Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=[0,0,0], scale=[1,1,1], rotate=[0,0,0]))\n\n    #debug_draw_keepouts(kicad_modg,keepouts)\n\n    # write file\n    if \"/\" in lib_name:\n        fp_lib_name = lib_name.split('/')[-1]\n    elif \"\\\\\" in lib_name:\n        fp_lib_name = lib_name.split('\\\\')[-1]\n\n    output_dir = fp_lib_name + '.pretty' + os.sep\n    if not os.path.isdir(output_dir):\n        os.makedirs(output_dir)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(output_dir + footprint_name + '.kicad_mod')\n\n\n\n\n\n\n\n#    <-----> vsegment_lines_offset\n#  +-+------------+-----------+-------------+                      ^\n#  | |     H      |    H      |    H        | ^                    |\n#  | |----------- |           |             | |                    |                                       ^\n#  | ||   OOO   | |   OOO     |   OOO       | |secondHoleOffset    | package_height                        |\n#  | ||  OOOOO  | |  OOOOO    |  OOOOO      | v                    |                  ^                    | opening[1]\n#  | ||   OOO   | |   OOO     |   OOO       |                      |                  |                    |\n#  +-+------------+-----------+-------------+ ^                    |                  | leftbottom_offset  x\n#  | |            |           |             | | bevel_height       |                  |                    | opening_yoffset\n#  +-+------------+-----------+-------------+ v                    v                  v                    v\n#          <--- rm ---->\n#  <------>leftbottom_offset[0]     <------->leftbottom_offset[2] (or leftbottom_offset[0]  if len(leftbottom_offset)==2)\n#     <---------> opening[0]\n#\n#\ndef makeTerminalBlock45Degree(footprint_name, pins, rm, package_height, leftbottom_offset, ddrill, pad, opening, opening_xoffset, opening_yoffset, opening_elliptic=False, bevel_height=[], vsegment_lines_offset=[], secondHoleDiameter=0, secondHoleOffset=[0,0], thirdHoleDiameter=0, thirdHoleOffset=[0,0], fourthHoleDiameter=0, fourthHoleOffset=[0,0], fifthHoleDiameter=0, fifthHoleOffset=[0,0],secondDrillDiameter=0,secondDrillOffset=[0,0],secondDrillPad=[0,0],nibbleSize=[],nibblePos=[], fabref_offset=[0,0],secondEllipseSize=[0,0],secondEllipseOffset=[0,0],\n                        stackable=False,\n                        tags_additional=[], lib_name=\"${{KISYS3DMOD}}/Connectors_Terminal_Blocks\", classname=\"Connectors_Terminal_Blocks\", classname_description=\"terminal block\", webpage=\"\", script_generated_note=\"\"):\n\n    package_size=[2*leftbottom_offset[0]+(pins-1)*rm, package_height];\n    if len(leftbottom_offset)==3:\n        package_size=[leftbottom_offset[0]+leftbottom_offset[2]+(pins-1)*rm, package_height];\n\n    h_fab = package_size[1]\n    w_fab = package_size[0]\n    l_fab = -leftbottom_offset[0]\n    t_fab = -(h_fab-leftbottom_offset[1])\n\n    h_slk = h_fab + 2 * slk_offset\n    w_slk = w_fab + 2 * slk_offset\n    l_slk = l_fab - slk_offset\n    t_slk = t_fab - slk_offset\n\n    h_crt = h_fab + 2 * crt_offset\n    w_crt = w_fab + (0 if stackable else 2 * crt_offset)\n    l_crt = l_fab - (0 if stackable else crt_offset)\n    t_crt = t_fab - crt_offset\n\n\n    text_size = w_fab*0.6\n    fab_text_size_max = 1.0\n    if text_size < fab_text_size_min:\n        text_size = fab_text_size_min\n    elif text_size > fab_text_size_max:\n        text_size = fab_text_size_max\n    text_size = round(text_size, 2)\n    text_size = [text_size,text_size]\n    text_t = text_size[0] * 0.15\n\n\n    description = \"{2}, 45Degree (cable under 45degree), {0:d} pins, pitch {1:.3g}mm, size {3:.3g}x{4:.3g}mm^2, drill diamater {5:.3g}mm, pad diameter {6:.3g}mm, see {7}, script-generated with \"\\\n        .format(pins, rm,classname_description, package_size[0], package_size[1], ddrill, max(pad), webpage)\n    tags = \"THT {2} 45Degree pitch {1:.3g}mm size {3:.3g}x{4:.3g}mm^2 drill {5:.3g}mm pad {6:.3g}mm\"\\\n        .format(pins, rm,classname_description, package_size[0], package_size[1], ddrill, max(pad))\n\n    if len(script_generated_note)>0:\n        description=description+\", \"+script_generated_note\n\n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n\n    print(footprint_name)\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n\n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    offset=[0,0]\n    kicad_modg = Translation(offset[0], offset[1])\n    kicad_mod.append(kicad_modg)\n\n    # set general values\n    kicad_modg.append(Text(type='reference', text='REF**', at=[l_fab+w_fab/2, t_slk - txt_offset], layer='F.SilkS'))\n    if (type(fabref_offset) in (tuple, list)):\n        kicad_modg.append(Text(type='user', text='%R', at=[l_fab+w_fab/2+fabref_offset[0], t_fab+h_fab/2+fabref_offset[1]], layer='F.Fab', size=text_size ,thickness=text_t))\n    else:\n        kicad_modg.append(Text(type='user', text='%R', at=[l_fab+w_fab/2,  t_slk - txt_offset], layer='F.Fab', size=text_size ,thickness=text_t))\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[l_fab+w_fab/2, t_slk + h_slk + txt_offset], layer='F.Fab'))\n\n\n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0\n\n    pad_type = Pad.TYPE_THT\n    pad_shape1 = Pad.SHAPE_RECT\n    pad_shapeother = Pad.SHAPE_CIRCLE\n    if pad[0] != pad[1]:\n        pad_shapeother = Pad.SHAPE_OVAL\n\n    extradrill1_type = Pad.TYPE_NPTH\n    if secondDrillPad[0] > secondDrillDiameter or secondDrillPad[1] > secondDrillDiameter:\n        extradrill1_type = Pad.TYPE_THT\n\n    if secondDrillDiameter>0:\n        if secondDrillPad[0] < secondDrillDiameter:\n            secondDrillPad[0] = secondDrillDiameter\n        if secondDrillPad[1] < secondDrillDiameter:\n            secondDrillPad[1] = secondDrillDiameter\n\n    pad_shape_extra = Pad.SHAPE_CIRCLE\n    if secondDrillPad[0] != secondDrillPad[1]:\n        pad_shape_extra = Pad.SHAPE_OVAL\n\n    pad_layers = Pad.LAYERS_THT\n    keepouts=[];\n\n    for p in range(1, pins + 1):\n        pextra=0\n        if secondDrillPad[0]>0:\n            pextra=p\n        if p == 1:\n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shape1, at=[x1, y1], size=pad, drill=ddrill, layers=pad_layers))\n            keepouts=keepouts+addKeepoutRect(x1, y1, pad[0]+8*slk_offset, pad[1]+8*slk_offset)\n            if secondDrillDiameter>0:\n                if extradrill1_type == Pad.TYPE_NPTH:\n                    num = \"\"\n                    extra_shape = pad_shape_extra\n                else:\n                    num = p\n                    extra_shape = Pad.SHAPE_RECT\n                kicad_modg.append(Pad(number=num, type=extradrill1_type, shape=extra_shape, at=[x1+secondDrillOffset[0], y1+secondDrillOffset[1]], size=secondDrillPad, drill=secondDrillDiameter, layers=pad_layers))\n                keepouts=keepouts+addKeepoutRect(x1+secondDrillOffset[0], y1+secondDrillOffset[1], max(secondDrillPad[0],secondDrillDiameter)+8*slk_offset, max(secondDrillPad[1],secondDrillDiameter)+8*slk_offset)\n        else:\n            kicad_modg.append(Pad(number=p, type=pad_type, shape=pad_shapeother, at=[x1, y1], size=pad, drill=ddrill, layers=pad_layers))\n            if pad[0]!=pad[1]:\n                keepouts=keepouts+addKeepoutRect(x1, y1, pad[0]+8*slk_offset, pad[1]+8*slk_offset)\n            else:\n                keepouts=keepouts+addKeepoutRound(x1, y1, pad[0]+8*slk_offset, pad[0]+8*slk_offset)\n            if secondDrillDiameter>0:\n                if extradrill1_type == Pad.TYPE_NPTH:\n                    num = \"\"\n                else:\n                    num = p\n                kicad_modg.append(Pad(number=num, type=extradrill1_type, shape=pad_shape_extra, at=[x1+secondDrillOffset[0], y1+secondDrillOffset[1]], size=secondDrillPad, drill=secondDrillDiameter, layers=pad_layers))\n                keepouts=keepouts+addKeepoutRect(x1+secondDrillOffset[0], y1+secondDrillOffset[1], max(secondDrillPad[0],secondDrillDiameter)+8*slk_offset, max(secondDrillPad[1],secondDrillDiameter)+8*slk_offset)\n\n        x1=x1+rm\n\n\n\n    # create Body\n    if len(bevel_height)>0:\n        chamfer = min(h_fab/4, 2, bevel_height[0])\n    else:\n        chamfer = min(h_fab/4, 2)\n    bevelRectBL(kicad_modg,  [l_fab,t_fab], [w_fab,h_fab], 'F.Fab', lw_fab, bevel_size=chamfer)\n    for bh in bevel_height:\n        kicad_modg.append(Line(start=[l_fab, t_fab + h_fab-bh], end=[l_fab+w_fab, t_fab + h_fab-bh], layer='F.Fab', width=lw_fab))\n        addHLineWithKeepout(kicad_modg,l_slk, l_slk+w_slk, t_fab + h_fab-bh, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n    addRectWithKeepout(kicad_modg, l_slk, t_slk, w_slk, h_slk, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n\n    # opening + other repeated features\n    for p in range(1,pins+1):\n        if opening[0]>0 and opening[1]>0:\n            if opening_elliptic:\n                addEllipse(kicad_modg, (p-1)*rm+opening_xoffset, t_fab+h_fab-opening_yoffset, opening[0], opening[1], layer='F.Fab', width=lw_fab)\n                addEllipseWithKeepout(kicad_modg, (p-1)*rm+opening_xoffset, t_fab+h_fab-opening_yoffset, opening[0], opening[1], layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n            else:\n                addRectWithKeepout(kicad_modg, (p-1)*rm-opening[0]/2+opening_xoffset, t_fab+h_fab-opening_yoffset-opening[1], opening[0], opening[1], 'F.SilkS', lw_slk, keepouts)\n                addRectWith(kicad_modg, (p-1)*rm-opening[0]/2+opening_xoffset, t_fab+h_fab-opening_yoffset-opening[1], opening[0], opening[1], 'F.Fab', lw_fab)\n\n        # vertical segment separation lines\n        for seg_offset in vsegment_lines_offset:\n            if seg_offset>=l_fab and seg_offset<=l_fab+w_fab:\n                addVLineWithKeepout(kicad_modg, x=(p-1)*rm+seg_offset, y0=t_fab, y1=t_fab+h_fab, layer='F.Fab', width=lw_fab, keepouts=[])\n                addVLineWithKeepout(kicad_modg, x=(p-1)*rm+seg_offset, y0=t_slk, y1=t_slk+h_slk, layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n\n        if not (type(secondHoleDiameter) in (tuple, list)) and secondHoleDiameter>0 and (p-1)*rm+secondHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(Circle(center=[(p-1)*rm+secondHoleOffset[0], 0+secondHoleOffset[1]], radius=secondHoleDiameter/2, layer='F.Fab', width=lw_fab))\n            addCircleWithKeepout(kicad_modg, (p-1)*rm+secondHoleOffset[0], 0+secondHoleOffset[1], secondHoleDiameter/2, 'F.SilkS', lw_slk, keepouts)\n        if not (type(thirdHoleDiameter) in (tuple, list)) and thirdHoleDiameter>0 and (p-1)*rm+thirdHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(Circle(center=[(p-1)*rm+thirdHoleOffset[0], 0+thirdHoleOffset[1]], radius=thirdHoleDiameter/2, layer='F.Fab', width=lw_fab))\n            addCircleWithKeepout(kicad_modg, (p-1)*rm+thirdHoleOffset[0], 0+thirdHoleOffset[1], thirdHoleDiameter/2, 'F.SilkS', lw_slk, keepouts)\n        if not (type(fourthHoleDiameter) in (tuple, list)) and fourthHoleDiameter>0 and (p-1)*rm+fourthHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(Circle(center=[(p-1)*rm+fourthHoleOffset[0], 0+fourthHoleOffset[1]], radius=fourthHoleDiameter/2, layer='F.Fab', width=lw_fab))\n            addCircleWithKeepout(kicad_modg, (p-1)*rm+fourthHoleOffset[0], 0+fourthHoleOffset[1], fourthHoleDiameter/2, 'F.SilkS', lw_slk, keepouts)\n        if not (type(fifthHoleDiameter) in (tuple, list)) and fifthHoleDiameter>0 and (p-1)*rm+fifthHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(Circle(center=[(p-1)*rm+fifthHoleOffset[0], 0+fifthHoleOffset[1]], radius=fifthHoleDiameter/2, layer='F.Fab', width=lw_fab))\n            addCircleWithKeepout(kicad_modg, (p-1)*rm+fifthHoleOffset[0], 0+fifthHoleOffset[1], fifthHoleDiameter/2, 'F.SilkS', lw_slk, keepouts)\n        if (type(secondHoleDiameter) in (tuple, list)) and (p-1)*rm+secondHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(RectLine(start=[(p-1)*rm+secondHoleOffset[0]-secondHoleDiameter[0]/2, 0+secondHoleOffset[1]-secondHoleDiameter[1]/2], end=[(p-1)*rm+secondHoleOffset[0]+secondHoleDiameter[0]/2, 0+secondHoleOffset[1]+secondHoleDiameter[1]/2], layer='F.Fab', width=lw_fab))\n            addRectWithKeepout(kicad_modg, (p-1)*rm+secondHoleOffset[0]-secondHoleDiameter[0]/2, 0+secondHoleOffset[1]-secondHoleDiameter[1]/2, secondHoleDiameter[0],secondHoleDiameter[1], 'F.SilkS', lw_slk, keepouts)\n        if (type(thirdHoleDiameter) in (tuple, list)) and (p-1)*rm+thirdHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(RectLine(start=[(p-1)*rm+thirdHoleOffset[0]-thirdHoleDiameter[0]/2, 0+thirdHoleOffset[1]-thirdHoleDiameter[1]/2], end=[(p-1)*rm+thirdHoleOffset[0]+thirdHoleDiameter[0]/2, 0+thirdHoleOffset[1]+thirdHoleDiameter[1]/2], layer='F.Fab', width=lw_fab))\n            addRectWithKeepout(kicad_modg, (p-1)*rm+thirdHoleOffset[0]-thirdHoleDiameter[0]/2, 0+thirdHoleOffset[1]-thirdHoleDiameter[1]/2, thirdHoleDiameter[0],thirdHoleDiameter[1], 'F.SilkS', lw_slk, keepouts)\n        if (type(fourthHoleDiameter) in (tuple, list)) and (p-1)*rm+fourthHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(RectLine(start=[(p-1)*rm+fourthHoleOffset[0]-fourthHoleDiameter[0]/2, 0+fourthHoleOffset[1]-fourthHoleDiameter[1]/2], end=[(p-1)*rm+fourthHoleOffset[0]+fourthHoleDiameter[0]/2, 0+fourthHoleOffset[1]+fourthHoleDiameter[1]/2], layer='F.Fab', width=lw_fab))\n            addRectWithKeepout(kicad_modg, (p-1)*rm+fourthHoleOffset[0]-fourthHoleDiameter[0]/2, 0+fourthHoleOffset[1]-fourthHoleDiameter[1]/2, fourthHoleDiameter[0],fourthHoleDiameter[1], 'F.SilkS', lw_slk, keepouts)\n        if (type(fifthHoleDiameter) in (tuple, list)) and (p-1)*rm+fifthHoleOffset[0]<l_fab+w_fab:\n            kicad_modg.append(RectLine(start=[(p-1)*rm+fifthHoleOffset[0]-fifthHoleDiameter[0]/2, 0+fifthHoleOffset[1]-fifthHoleDiameter[1]/2], end=[(p-1)*rm+fifthHoleOffset[0]+fifthHoleDiameter[0]/2, 0+fifthHoleOffset[1]+fifthHoleDiameter[1]/2], layer='F.Fab', width=lw_fab))\n            addRectWithKeepout(kicad_modg, (p-1)*rm+fifthHoleOffset[0]-fifthHoleDiameter[0]/2, 0+fifthHoleOffset[1]-fifthHoleDiameter[1]/2, fifthHoleDiameter[0],fifthHoleDiameter[1], 'F.SilkS', lw_slk, keepouts)\n        if secondEllipseSize[0]>0 and secondEllipseSize[1]>0:\n            addEllipse(kicad_modg, (p-1)*rm+secondEllipseOffset[0], 0+secondEllipseOffset[1], secondEllipseSize[0], secondEllipseSize[1], layer='F.Fab', width=lw_fab)\n            addEllipseWithKeepout(kicad_modg, (p-1)*rm+secondEllipseOffset[0], 0+secondEllipseOffset[1], secondEllipseSize[0], secondEllipseSize[1], layer='F.SilkS', width=lw_slk, keepouts=keepouts)\n\n    #nibble\n    if len(nibbleSize)==2 and len(nibblePos)==2:\n        kicad_modg.append(RectLine(start=[l_fab+nibblePos[0], t_fab+nibblePos[1]], end=[l_fab+nibblePos[0]+nibbleSize[0], t_fab+nibblePos[1]+nibbleSize[1]], layer='F.Fab', width=lw_fab))\n        addRectWithKeepout(kicad_modg, l_fab+nibblePos[0]-slk_offset, t_fab+nibblePos[1]-slk_offset, nibbleSize[0],nibbleSize[1]+2*slk_offset, 'F.SilkS', lw_slk, keepouts)\n\n\n\n    # create SILKSCREEN-pin1-marker\n    kicad_modg.append(Line(start=[l_slk-2*lw_slk, t_slk + h_slk-chamfer], end=[l_slk-2*lw_slk, t_slk + h_slk+2*lw_slk], layer='F.SilkS', width=lw_slk))\n    kicad_modg.append(Line(start=[l_slk-2*lw_slk, t_slk + h_slk+2*lw_slk], end=[l_slk-2*lw_slk+chamfer, t_slk + h_slk+2*lw_slk], layer='F.SilkS', width=lw_slk))\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\n                              end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\n                              layer='F.CrtYd', width=lw_crt))\n\n\n    # add model\n    kicad_modg.append(\n        Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=[0,0,0], scale=[1,1,1], rotate=[0,0,0]))\n\n    #debug_draw_keepouts(kicad_modg,keepouts)\n\n    # write file\n    if \"/\" in lib_name:\n        fp_lib_name = lib_name.split('/')[-1]\n    elif \"\\\\\" in lib_name:\n        fp_lib_name = lib_name.split('\\\\')[-1]\n\n    output_dir = fp_lib_name + '.pretty' + os.sep\n    if not os.path.isdir(output_dir):\n        os.makedirs(output_dir)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(output_dir + footprint_name + '.kicad_mod')\n\n\n\n\n\n\n# pins [[x,y], [x,y], ...] location of pins (relative to center of block)\n# ddrill: drill diameter for pins\n# pad [padx,pady]:  size of pin-pad\n# screw_diameter: diameter of screw\n# screw_offset: offset of screw from package center\n# slit_screw=true|False: type of screw\n# block_size [w,h]: size of block\ndef makeScrewTerminalSingleStd(footprint_name, block_size, block_offset, pins, ddrill, pad, screw_diameter, screw_offset, slit_screw=True,\n                        tags_additional=[], lib_name=\"${{KISYS3DMOD}}/Connectors_Terminal_Blocks\", classname=\"Connectors_Terminal_Blocks\", classname_description=\"single screw terminal terminal block\", webpage=\"\", script_generated_note=\"\"):\n\n\n    h_fab = block_size[1]\n    w_fab = block_size[0]\n    l_fab = -block_size[0]/2+block_offset[0]\n    t_fab = -block_size[1]/2+block_offset[1]\n\n    h_slk = h_fab + 2 * slk_offset\n    w_slk = w_fab + 2 * slk_offset\n    l_slk = l_fab - slk_offset\n    t_slk = t_fab - slk_offset\n\n    h_crt = h_fab + 2 * crt_offset\n    w_crt = w_fab + 2 * crt_offset\n    l_crt = l_fab - crt_offset\n    t_crt = t_fab - crt_offset\n\n\n    text_size = w_fab*0.6\n    fab_text_size_max = 1.0\n    if text_size < fab_text_size_min:\n        text_size = fab_text_size_min\n    elif text_size > fab_text_size_max:\n        text_size = fab_text_size_max\n    text_size = round(text_size, 2)\n    text_size = [text_size,text_size]\n    text_t = text_size[0] * 0.15\n    txt_offset=text_size[1]\n\n\n    description = \"{2}, block size {3:.3g}x{4:.3g}mm^2, drill diamater {5:.3g}mm, {1:d} pads, pad diameter {6:.3g}mm, see {7}\"\\\n        .format(0, len(pins), classname_description, block_size[0], block_size[1], ddrill, max(pad), webpage)\n    tags = \"THT {2} size {3:.3g}x{4:.3g}mm^2 drill {5:.3g}mm pad {6:.3g}mm\"\\\n        .format(0, len(pins), classname_description, block_size[0], block_size[1], ddrill, max(pad))\n\n    if len(script_generated_note)>0:\n        description=description+\", \"+script_generated_note\n\n    if (len(tags_additional) > 0):\n        for t in tags_additional:\n            footprint_name = footprint_name + \"_\" + t\n            description = description + \", \" + t\n            tags = tags + \" \" + t\n\n    print(footprint_name)\n\n    # init kicad footprint\n    kicad_mod = Footprint(footprint_name)\n    kicad_mod.setDescription(description)\n    kicad_mod.setTags(tags)\n\n    # anchor for SMD-symbols is in the center, for THT-sybols at pin1\n    offset=pins[0]\n    kicad_modg = Translation(offset[0], offset[1])\n    kicad_mod.append(kicad_modg)\n\n    # set general values\n    kicad_modg.append(Text(type='reference', text='REF**', at=[l_fab+w_fab/2, t_slk - txt_offset], layer='F.SilkS'))\n    kicad_modg.append(Text(type='user', text='%R', at=[l_fab+w_fab/2, t_slk - txt_offset], layer='F.Fab'))\n    kicad_modg.append(Text(type='value', text=footprint_name, at=[l_fab+w_fab/2, t_slk + h_slk + txt_offset], layer='F.Fab'))\n\n\n    # create pads\n    p1 = int(1)\n    x1 = 0\n    y1 = 0\n\n     # pins/pads\n    pad_type = Pad.TYPE_THT\n    pad_shapeother = Pad.SHAPE_CIRCLE\n    pad_layers = Pad.LAYERS_THT\n    keepouts=[];\n    for p in pins:\n        kicad_modg.append(Pad(number=1, type=pad_type, shape=pad_shapeother, at=p, size=pad, drill=ddrill, layers=pad_layers))\n        keepouts=keepouts+addKeepoutRound(p[0], p[1], pad[0]+8*slk_offset, pad[0]+8*slk_offset)\n\n    # screw\n    keepouts_screw=[];\n    if screw_diameter>0:\n        keepouts_screw=keepouts_screw+addKeepoutRound(screw_offset[0], screw_offset[1], screw_diameter, screw_diameter)\n        if slit_screw:\n            addSlitScrew(kicad_modg, screw_offset[0], screw_offset[1], screw_diameter/2, 'F.Fab', lw_fab)\n            addSlitScrewWithKeepouts(kicad_modg, screw_offset[0], screw_offset[1], screw_diameter/2+1*slk_offset, 'F.SilkS', lw_slk, keepouts)\n        else:\n            addCrossScrew(kicad_modg, screw_offset[0], screw_offset[1], screw_diameter/2, 'F.Fab', lw_fab)\n            addCrossScrewWithKeepouts(kicad_modg, screw_offset[0], screw_offset[1], screw_diameter/2+1*slk_offset, 'F.SilkS', lw_slk, keepouts)\n\n    # create Body\n    addRectWithKeepout(kicad_modg, l_fab, t_fab, w_fab, h_fab, layer='F.Fab', width=lw_fab, keepouts=keepouts_screw)\n    addRectWithKeepout(kicad_modg, l_slk, t_slk, w_slk, h_slk, layer='F.SilkS', width=lw_slk, keepouts=keepouts+keepouts_screw)\n\n    # create courtyard\n    kicad_mod.append(RectLine(start=[roundCrt(l_crt + offset[0]), roundCrt(t_crt + offset[1])],\n                              end=[roundCrt(l_crt + offset[0] + w_crt), roundCrt(t_crt + offset[1] + h_crt)],\n                              layer='F.CrtYd', width=lw_crt))\n\n\n    # add model\n    kicad_modg.append(\n        Model(filename=lib_name + \".3dshapes/\" + footprint_name + \".wrl\", at=[0,0,0], scale=[1,1,1], rotate=[0,0,0]))\n\n    #debug_draw_keepouts(kicad_modg,keepouts)\n\n    # write file\n    if \"/\" in lib_name:\n        fp_lib_name = lib_name.split('/')[-1]\n    elif \"\\\\\" in lib_name:\n        fp_lib_name = lib_name.split('\\\\')[-1]\n\n    output_dir = fp_lib_name + '.pretty' + os.sep\n    if not os.path.isdir(output_dir):\n        os.makedirs(output_dir)\n\n    file_handler = KicadFileHandler(kicad_mod)\n    file_handler.writeFile(output_dir + footprint_name + '.kicad_mod')\n"
  },
  {
    "path": "scripts/tools/footprint_text_fields.py",
    "content": "import sys, os\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nfrom KicadModTree import *  # NOQA\n\ndef _roundToBase(value, base):\n    return round(value/base) * base\n\ndef _getTextFieldDetails(field_definition, body_edges, courtyard, text_y_inside_position = 'center', allow_rotation = False):\n    body_size = [body_edges['right'] - body_edges['left'], body_edges['bottom'] - body_edges['top']]\n    body_center = [(body_edges['right'] + body_edges['left'])/2, (body_edges['bottom'] + body_edges['top'])/2]\n\n    position_y = field_definition['position_y']\n    at = body_center.copy()\n\n\n    if body_size[0] < body_size[1] and allow_rotation and position_y == 'inside':\n        rotation = 1\n    else:\n        rotation = 0\n\n    if 'size' in field_definition:\n        size = field_definition['size']\n        fontwidth = field_definition['fontwidth']\n    elif 'size_min' in field_definition and 'size_max' in field_definition:\n        # We want at least 3 char reference designators space. If we can't fit these we move the reverence to the outside.\n        size_max = field_definition['size_max']\n        size_min = field_definition['size_min']\n        if body_size[rotation] >= 4*size_max[1]:\n            if body_size[0] >= 4*size_max[1]:\n                rotation = 0\n            size = size_max\n        elif body_size[rotation] < 4*size_min[1]:\n            size = size_min\n            if body_size[rotation] < 3*size_min[1]:\n                if position_y == 'inside':\n                    rotation = 0\n                    position_y = 'outside_top'\n        else:\n            fs = _roundToBase(body_size[rotation]/4, 0.01)\n            size = [fs, fs]\n\n        if size[1] > body_size[(rotation+1)%2]-0.2:\n            fs = max(body_size[(rotation+1)%2]-0.2, size_min[1])\n            size = [fs, fs]\n\n        fontwidth = _roundToBase(field_definition['thickness_factor']*size[0], 0.01)\n    else:\n        rotation = 0\n        position_y = 'outside_top'\n        size = [1,1]\n        fontwidth = 0.15\n\n    if position_y == 'inside':\n        if text_y_inside_position == 'top':\n            position_y = 'inside_top'\n        elif text_y_inside_position == 'bottom':\n            position_y = 'inside_bottom'\n        elif text_y_inside_position == 'left':\n            position_y = 'inside_left'\n        elif text_y_inside_position == 'right':\n            position_y = 'inside_right'\n        elif isinstance(text_y_inside_position,int) or isinstance(text_y_inside_position,float):\n            at[1] = text_y_inside_position\n\n    text_edge_offset = size[0]/2+0.2\n    if position_y == 'outside_top':\n        at = [body_center[0], courtyard['top']-text_edge_offset]\n    elif position_y == 'inside_top':\n        at = [body_center[0], body_edges['top']+text_edge_offset]\n    elif position_y == 'inside_left':\n        at = [body_edges['left'] + text_edge_offset, body_center[1]]\n        rotation = 1\n    elif position_y == 'inside_right':\n        at = [body_edges['right'] - text_edge_offset, body_center[1]]\n        rotation = 1\n    elif position_y == 'outside_bottom':\n        at = [body_center[0], courtyard['bottom']+text_edge_offset]\n    elif position_y == 'inside_bottom':\n        at = [body_center[0], body_edges['bottom']-text_edge_offset]\n\n\n    at = [_roundToBase(at[0],0.01), _roundToBase(at[1],0.01)]\n    return {'at': at, 'size': size, 'layer': field_definition['layer'], 'thickness': fontwidth, 'rotation': rotation*90}\n\ndef addTextFields(kicad_mod, configuration, body_edges, courtyard, fp_name, text_y_inside_position = 'center', allow_rotation = False):\n    reference_fields = configuration['references']\n    kicad_mod.append(Text(type='reference', text='REF**',\n        **_getTextFieldDetails(reference_fields[0], body_edges, courtyard, text_y_inside_position, allow_rotation)))\n\n    for additional_ref in reference_fields[1:]:\n        kicad_mod.append(Text(type='user', text='%R',\n        **_getTextFieldDetails(additional_ref, body_edges, courtyard, text_y_inside_position, allow_rotation)))\n\n    value_fields = configuration['values']\n    kicad_mod.append(Text(type='value', text=fp_name,\n        **_getTextFieldDetails(value_fields[0], body_edges, courtyard, text_y_inside_position, allow_rotation)))\n\n    for additional_value in value_fields[1:]:\n        kicad_mod.append(Text(type='user', text='%V',\n            **_getTextFieldDetails(additional_value, body_edges, courtyard, text_y_inside_position, allow_rotation)))\n"
  },
  {
    "path": "scripts/tools/global_config_files/config_KLCv1.0.yaml",
    "content": "3d_model_prefix: '${KISYS3DMOD}/'\n\nsilk_line_width: 0.15\nsilk_pad_clearance: 0.2\nsilk_fab_offset: 0.15\nsilk_line_lenght_min: 0.4\nallow_silk_below_part: 'tht' # tht | smd | all | none\n\nfab_line_width: 0.15\nfab_pin1_marker_length: 1\n\ncourtyard_line_width: 0.05\ncourtyard_grid: 0.01\ncourtyard_offset:\n    default: 0.25\n    connector: 0.5\n    bga: 1\n\nedge_cuts_line_width: 0.12\n\nreferences:\n    -\n          layer: 'F.Fab'\n          position_y: 'top' # outside_top | inside | outside_bottom\n          size: [2,2]\n          fontwidth: 0.15\nvalues:\n    -\n          layer: 'F.Fab'\n          position_y: 'bottom' # outside_top | inside | outside_bottom\n          size: [1,1]\n          fontwidth: 0.15\n"
  },
  {
    "path": "scripts/tools/global_config_files/config_KLCv2.0.yaml",
    "content": "3d_model_prefix: '${KISYS3DMOD}/'\n\nsilk_line_width: 0.12\nsilk_pad_clearance: 0.2\nsilk_fab_offset: 0.11\nsilk_line_lenght_min: 0.4\nallow_silk_below_part: 'tht' # tht | smd | all | none\n\nfab_line_width: 0.1\nfab_pin1_marker_length: 1\n\ncourtyard_line_width: 0.05\ncourtyard_grid: 0.01\ncourtyard_offset:\n    default: 0.25\n    connector: 0.5\n    bga: 1\n\nedge_cuts_line_width: 0.12\n\nreferences:\n    -\n          layer: 'F.SilkS'\n          position_y: 'top' # outside_top | inside | outside_bottom\n          size: [1,1]\n          fontwidth: 0.15\n    -\n          layer: 'F.Fab'\n          position_y: 'inside' # outside_top | inside | outside_bottom\n          size_max: [1,1]\n          size_min: [0.25, 0.25]\n          thickness_factor: 0.15\n          # size: [1,1]\n          # fontwidth: 0.15\nvalues:\n    -\n          layer: 'F.Fab'\n          position_y: 'bottom' # outside_top | inside | outside_bottom\n          size: [1,1]\n          fontwidth: 0.15\n"
  },
  {
    "path": "scripts/tools/global_config_files/config_KLCv3.0.yaml",
    "content": "3d_model_prefix: '${KISYS3DMOD}/'\n\nsilk_line_width: 0.12\nsilk_pad_clearance: 0.2\nsilk_fab_offset: 0.11\nsilk_line_lenght_min: 0.2\nallow_silk_below_part: 'tht' # tht | smd | all | none\n\nfab_line_width: 0.1\nfab_pin1_marker_length: 1\nfab_bevel_size_absolute: 1 # Bevel size of footprints in mm\nfab_bevel_size_relative: 0.25 # Bevel size of footprints relative to package size\n\ncourtyard_line_width: 0.05\ncourtyard_grid: 0.01\ncourtyard_offset:\n    default: 0.25\n    connector: 0.5\n    bga: 1\n\nedge_cuts_line_width: 0.12\n\n# IPC-7351C will most likely suggest the use of rounded rectangle pads\n# with 25% radius ratio but at a maximum of 0.25mm\nround_rect_max_radius: 0.25\nround_rect_radius_ratio: 0.25\n\nreferences:\n    -\n          layer: 'F.SilkS'\n          position_y: 'outside_top' # outside_top | inside | outside_bottom\n          size: [1,1]\n          fontwidth: 0.15\n    -\n          layer: 'F.Fab'\n          position_y: 'inside' # outside_top | inside | outside_bottom\n          size_max: [1,1]\n          size_min: [0.25, 0.25]\n          thickness_factor: 0.15\n          # size: [1,1]\n          # fontwidth: 0.15\nvalues:\n    -\n          layer: 'F.Fab'\n          position_y: 'outside_bottom' # outside_top | inside | outside_bottom\n          size: [1,1]\n          fontwidth: 0.15\n"
  },
  {
    "path": "scripts/tools/global_config_files/config_Tera.yaml",
    "content": "3d_model_prefix: '${KISYS3DMOD}/'\n\nsilk_line_width: 0.15\nsilk_pad_clearance: 0.2\nsilk_fab_offset: 0.11\nsilk_line_lenght_min: 0.4\nallow_silk_below_part: 'tht' # tht | smd | all | none\n\nfab_line_width: 0.05\nfab_pin1_marker_length: 1\n\ncourtyard_line_width: 0.05\ncourtyard_grid: 0.01\ncourtyard_offset:\n    default: 0.25\n    connector: 0.5\n    bga: 1\n\nedge_cuts_line_width: 0.12\n\nreferences:\n    -\n          layer: 'F.Fab'\n          position_y: 'inside' # outside_top | inside | outside_bottom\n          # size: [1,1]\n          # fontwidth: 0.15\n          size_max: [1,1]\n          size_min: [0.5, 0.5]\n          thickness_factor: 0.15\n    -\n          layer: 'F.SilkS'\n          position_y: 'outside_top' # outside_top | inside | outside_bottom\n          size: [1,1]\n          fontwidth: 0.15\nvalues:\n    -\n          layer: 'F.Fab'\n          position_y: 'outside_bottom' # outside_top | inside | outside_bottom\n          size: [0.6, 0.6]\n          fontwidth: 0.1\n"
  },
  {
    "path": "scripts/tools/ipc_pad_size_calculators.py",
    "content": "from __future__ import division\nimport math\nimport re\n\ndef roundToBase(value, base):\n    return round(value/base) * base\n\nclass TolerancedSize():\n    def to_metric(value, unit):\n        if unit == \"inch\":\n            factor = 25.4\n        elif unit == \"mil\":\n            factor = 25.4/1000\n        else:\n            factor = 1\n        return value * factor\n\n    def __init__(self, minimum=None, nominal=None, maximum=None, tolerance=None, unit=None):\n\n\n        if nominal is not None:\n            self.nominal = nominal\n        else:\n            if minimum is None or maximum is None:\n                raise KeyError(\"Either nominal or minimum and maximum must be given\")\n            self.nominal = (minimum + maximum)/2\n\n        if minimum is not None and maximum is not None:\n            self.minimum = minimum\n            self.maximum = maximum\n        elif tolerance is not None:\n            if type(tolerance) in [int, float]:\n                self.minimum = self.nominal - tolerance\n                self.maximum = self.nominal + tolerance\n            elif len(tolerance) == 2:\n                if tolerance[0] < 0:\n                    self.minimum = self.nominal + tolerance[0]\n                    self.maximum = self.nominal + tolerance[1]\n                elif tolerance[1] < 0:\n                    self.minimum = self.nominal + tolerance[1]\n                    self.maximum = self.nominal + tolerance[0]\n                else:\n                    self.minimum = self.nominal - tolerance[0]\n                    self.maximum = self.nominal + tolerance[1]\n        else:\n            self.minimum = self.nominal\n            self.maximum = self.nominal\n\n        if self.maximum < self.minimum:\n            raise ValueError(\"Maximum is smaller than minimum. Tolerance ranges given wrong or parameters confused.\")\n\n        self.minimum = TolerancedSize.to_metric(self.minimum, unit)\n        self.nominal = TolerancedSize.to_metric(self.nominal, unit)\n        self.maximum = TolerancedSize.to_metric(self.maximum, unit)\n\n        self.ipc_tol = self.maximum - self.minimum\n        self.ipc_tol_RMS = self.ipc_tol\n        self.maximum_RMS = self.maximum\n        self.minimum_RMS = self.minimum\n\n    def updateRMS(self, tolerances):\n        ipc_tol_RMS = 0\n        for t in tolerances:\n            ipc_tol_RMS += t**2\n\n        self.ipc_tol_RMS = math.sqrt(ipc_tol_RMS)\n        if self.ipc_tol_RMS > self.ipc_tol:\n            if roundToBase(self.ipc_tol_RMS, 1e-6) > roundToBase(self.ipc_tol, 1e-6):\n                raise ValueError(\n                    \"RMS tolerance larger than normal tolerance. Did you give the wrong tolerances?\\ntol(RMS): {} tol: {}\"\\\n                    .format(self.ipc_tol_RMS, self.ipc_tol))\n            # the discrepancy most likely comes from floating point errors. Ignore it.\n            self.ipc_tol_RMS = self.ipc_tol\n\n        self.maximum_RMS = self.maximum - (self.ipc_tol - self.ipc_tol_RMS)/2\n        self.minimum_RMS = self.minimum + (self.ipc_tol - self.ipc_tol_RMS)/2\n\n    def __add__(self, other):\n        if type(other) in [int, float]:\n            result = TolerancedSize(\n                minimum = self.minimum + other,\n                maximum = self.maximum + other\n                )\n            return result\n\n        result = TolerancedSize(\n            minimum = self.minimum + other.minimum,\n            maximum = self.maximum + other.maximum\n            )\n        result.updateRMS([self.ipc_tol_RMS, other.ipc_tol_RMS])\n        return result\n\n    def __sub__(self, other):\n        if type(other) in [int, float]:\n            result = TolerancedSize(\n                minimum = self.minimum - other,\n                maximum = self.maximum - other\n                )\n            return result\n\n        result = TolerancedSize(\n            minimum = self.minimum - other.maximum,\n            maximum = self.maximum - other.minimum\n            )\n        result.updateRMS([self.ipc_tol_RMS, other.ipc_tol_RMS])\n        return result\n\n    def __mul__(self, other):\n        if type(other) not in [int, float]:\n            raise NotImplementedError(\"Only multiplication with int and float is implemented right now.\")\n        result = TolerancedSize(\n            minimum = self.minimum*other,\n            maximum = self.maximum*other\n            )\n        result.updateRMS([self.ipc_tol_RMS*math.sqrt(other)])\n        return result\n\n    def __div__(self, other):\n        return self.__truediv__(other)\n\n    def __truediv__(self, other):\n        if type(other) not in [int, float]:\n            raise NotImplementedError(\"Only multiplication with int and float is implemented right now.\")\n        result = TolerancedSize(\n            minimum = self.minimum/other,\n            maximum = self.maximum/other\n            )\n        result.updateRMS([self.ipc_tol_RMS/math.sqrt(other)])\n        return result\n\n    def __floordiv__(self, other):\n        if type(other) not in [int, float]:\n            raise NotImplementedError(\"Only multiplication with int and float is implemented right now.\")\n        result = TolerancedSize(\n            minimum = self.minimum//other,\n            maximum = self.maximum//other\n            )\n        result.updateRMS([self.ipc_tol_RMS//math.sqrt(other)])\n        return result\n\n    @staticmethod\n    def fromString(input, unit=None):\n        minimum = None\n        nominal = None\n        maximum = None\n        tolerance = None\n\n        s = re.sub(r'\\s+', '', str(input))\n        if type(input) in [int, float]:\n            nominal = input\n        elif \"+/-\" in s:\n            tokens = s.split(\"+/-\")\n            nominal = float(tokens[0])\n            tolerance = float(tokens[1])\n        elif '+' in s and '-' in s:\n            if s.count('+') > 1 or s.count('-') > 1:\n                raise ValueError(\"Illegal dimension specifier: {}\\n\\tToo many tolerance specifiers. Expected nom+tolp-toln\".format(input))\n            idxp = s.find('+')\n            idxn = s.find('-')\n\n            nominal = float(s[0:min(idxp, idxn)])\n            tolerance=[\n                float(s[idxn : idxp if idxn<idxp else None]),\n                float(s[idxp : idxn if idxn>idxp else None])]\n        elif '...' in s or '..' in s:\n            s = s.replace('...', '..')\n            tokens = s.split('..')\n            if len(tokens) > 3:\n                raise ValueError(\"Illegal dimension specifier: {}\\n\\tToo many tokens seperated by '...' (Valid options are min...max or min...nom...max)\".format(input))\n            minimum = float(tokens[0])\n            maximum = float(tokens[-1])\n            if len(tokens) == 3:\n                nominal = float(tokens[1])\n        else:\n            try:\n                nominal = float(s)\n            except Exception as e:\n                raise ValueError(\"Dimension specifier not recogniced: {}\\n\\t Valid options are nom, nom+/-tol, nom+tolp-toln, min...max or min...nom...max\".format(input)) from e\n\n        return TolerancedSize(\n            minimum=minimum,\n            nominal=nominal,\n            maximum=maximum,\n            tolerance=tolerance,\n            unit=unit\n            )\n\n    @staticmethod\n    def fromYaml(yaml, base_name=None, unit=None):\n        if base_name is not None:\n            if base_name+\"_min\" in yaml or base_name+\"_max\" in yaml or base_name+\"_tol\" in yaml:\n                return TolerancedSize(\n                    minimum=yaml.get(base_name+\"_min\"),\n                    nominal=yaml.get(base_name),\n                    maximum=yaml.get(base_name+\"_max\"),\n                    tolerance=yaml.get(base_name+\"_tol\")\n                    )\n            return TolerancedSize.fromYaml(yaml.get(base_name), unit=unit)\n\n        elif type(yaml) is dict:\n            return TolerancedSize(\n                minimum=yaml.get(\"minimum\"),\n                nominal=yaml.get(\"nominal\"),\n                maximum=yaml.get(\"maximum\"),\n                tolerance=yaml.get(\"tolerance\"),\n                unit=unit\n                )\n        else:\n            return TolerancedSize.fromString(yaml, unit)\n\n    def __str__(self):\n        return 'nom: {}, min: {}, max: {}  | min_rms: {}, max_rms: {}'.format(self.nominal, self.minimum, self.maximum, self.minimum_RMS, self.maximum_RMS)\n\ndef ipc_body_edge_inside(ipc_data, ipc_round_base, manf_tol, body_size, lead_width,\n        lead_len=None, lead_inside=None, heel_reduction=0):\n    pull_back = TolerancedSize(nominal=0)\n\n    return ipc_body_edge_inside_pull_back(\n                ipc_data, ipc_round_base, manf_tol, body_size, lead_width,\n                lead_len=lead_len, lead_inside=lead_inside, pull_back=pull_back,\n                heel_reduction=heel_reduction\n                )\n\ndef ipc_body_edge_inside_pull_back(ipc_data, ipc_round_base, manf_tol, body_size, lead_width,\n        lead_len=None, lead_inside=None, body_to_inside_lead_edge=None, pull_back=None, lead_outside=None, heel_reduction=0):\n    # Zmax = Lmin + 2JT + √(CL^2 + F^2 + P^2)\n    # Gmin = Smax − 2JH − √(CS^2 + F^2 + P^2)\n    # Xmax = Wmin + 2JS + √(CW^2 + F^2 + P^2)\n\n    # Some manufacturers do not list the terminal spacing (S) in their datasheet but list the terminal lenght (T)\n    # Then one can calculate\n    # Stol(RMS) = √(Ltol^2 + 2*^2)\n    # Smin = Lmin - 2*Tmax\n    # Smax(RMS) = Smin + Stol(RMS)\n\n    F = manf_tol.get('manufacturing_tolerance', 0.1)\n    P = manf_tol.get('placement_tolerance', 0.05)\n\n    if lead_outside is None:\n        if pull_back is None:\n            raise KeyError(\"Either lead outside or pull back distance must be given\")\n        lead_outside = body_size - pull_back*2\n\n    if lead_inside is not None:\n        S = lead_inside\n    elif lead_len is not None:\n        S = lead_outside - lead_len*2\n    elif body_to_inside_lead_edge is not None:\n        S = body_size - body_to_inside_lead_edge*2\n    else:\n        raise KeyError(\"either lead inside distance, lead to body edge or lead lenght must be given\")\n\n    Gmin = S.maximum_RMS - 2*ipc_data['heel'] + 2*heel_reduction - math.sqrt(S.ipc_tol_RMS**2 + F**2 + P**2)\n\n    Zmax = lead_outside.minimum_RMS + 2*ipc_data['toe'] + math.sqrt(lead_outside.ipc_tol_RMS**2 + F**2 + P**2)\n    Xmax = lead_width.minimum_RMS + 2*ipc_data['side'] + math.sqrt(lead_width.ipc_tol_RMS**2 + F**2 + P**2)\n\n    Zmax = roundToBase(Zmax, ipc_round_base['toe'])\n    Gmin = roundToBase(Gmin, ipc_round_base['heel'])\n    Xmax = roundToBase(Xmax, ipc_round_base['side'])\n\n    return Gmin, Zmax, Xmax\n\ndef ipc_gull_wing(ipc_data, ipc_round_base, manf_tol, lead_width, lead_outside,\n        lead_len=None, lead_inside=None, heel_reduction=0):\n    # Zmax = Lmin + 2JT + √(CL^2 + F^2 + P^2)\n    # Gmin = Smax − 2JH − √(CS^2 + F^2 + P^2)\n    # Xmax = Wmin + 2JS + √(CW^2 + F^2 + P^2)\n\n    # Some manufacturers do not list the terminal spacing (S) in their datasheet but list the terminal lenght (T)\n    # Then one can calculate\n    # Stol(RMS) = √(Ltol^2 + 2*^2)\n    # Smin = Lmin - 2*Tmax\n    # Smax(RMS) = Smin + Stol(RMS)\n\n    F = manf_tol.get('manufacturing_tolerance', 0.1)\n    P = manf_tol.get('placement_tolerance', 0.05)\n\n    if lead_inside is not None:\n        S = lead_inside\n    elif lead_len is not None:\n        S = lead_outside - lead_len*2\n    else:\n        raise KeyError(\"either lead inside distance or lead lenght must be given\")\n\n    Gmin = S.maximum_RMS - 2*ipc_data['heel'] + 2*heel_reduction - math.sqrt(S.ipc_tol_RMS**2 + F**2 + P**2)\n\n    Zmax = lead_outside.minimum_RMS + 2*ipc_data['toe'] + math.sqrt(lead_outside.ipc_tol_RMS**2 + F**2 + P**2)\n    Xmax = lead_width.minimum_RMS + 2*ipc_data['side'] + math.sqrt(lead_width.ipc_tol_RMS**2 + F**2 + P**2)\n\n    Zmax = roundToBase(Zmax, ipc_round_base['toe'])\n    Gmin = roundToBase(Gmin, ipc_round_base['heel'])\n    Xmax = roundToBase(Xmax, ipc_round_base['side'])\n\n    return Gmin, Zmax, Xmax\n\ndef ipc_pad_center_plus_size(ipc_data, ipc_round_base, manf_tol,\n        center_position, lead_length, lead_width):\n    F = manf_tol.get('manufacturing_tolerance', 0.1)\n    P = manf_tol.get('placement_tolerance', 0.05)\n\n    S = center_position*2 - lead_length\n    lead_outside = center_position*2 + lead_length\n\n    Gmin = S.maximum_RMS - 2*ipc_data['heel'] - math.sqrt(S.ipc_tol_RMS**2 + F**2 + P**2)\n    Zmax = lead_outside.minimum_RMS + 2*ipc_data['toe'] + math.sqrt(lead_outside.ipc_tol_RMS**2 + F**2 + P**2)\n\n    Xmax = lead_width.minimum_RMS + 2*ipc_data['side'] + math.sqrt(lead_width.ipc_tol_RMS**2 + F**2 + P**2)\n\n    Zmax = roundToBase(Zmax, ipc_round_base['toe'])\n    Gmin = roundToBase(Gmin, ipc_round_base['heel'])\n    Xmax = roundToBase(Xmax, ipc_round_base['side'])\n\n    return Gmin, Zmax, Xmax\n"
  },
  {
    "path": "scripts/tools/pad_number_generators.py",
    "content": "\"\"\"\nPad number generator functions.\n\nSome ICs have a non-standard pin numbering scheme.\nUsing the generators an iterable is generated following the scheme.\n\nAvailable generators:\n----------------------\n- increment: Generates pin numbers increasing by one and supports skipping pin numbers\n            using the deleted_pins kwarg (skipped pins return a bogus value of -1)\n- cw_dual: Generates pin numbers counting clockwise from the starting position\n- ccw_dual: Generates pin numbers counting counter-clockwise from the starting position\n\nExamples:\n---------\nTo use a generator add the following to the device config:\n\n  pad_numbers:\n    generator: 'ccw_dual'\n    axis: 'x'\n\n\"\"\"\n\n\ndef increment(pincount, init=1, **kwargs):\n    i = init\n    j = init # pad number for deleted pins\n\n    if kwargs.get(\"deleted_pins\"):\n        skip_pins = kwargs[\"deleted_pins\"]\n\n    while i <= pincount:\n        if kwargs.get(\"deleted_pins\"):\n            if i in skip_pins:\n                yield None\n            else:\n                yield j\n                j += 1\n            i += 1 # i acts like pin location for deleted pins\n        else:\n            yield i\n            i += 1\n\n\ndef _get_pin_cw(pincount, loc):\n    \"\"\"Helper function to locate pin number for cw_dual.\n\n    Args:\n        pincount: Total number of pins\n        loc: Starting location\n\n    Returns:\n        pin_number: Starting pin number\n    \"\"\"\n    pins_per_side = pincount // 2\n    if loc == \"top_left\":\n        return 0\n    elif loc == \"bottom_left\":\n        return pins_per_side * 2 + 1\n    elif loc == \"bottom_right\":\n        return pins_per_side\n    elif loc == \"top_right\":\n        return pins_per_side + 1\n    return 0\n\n\ndef _get_pin_ccw(pincount, loc):\n    \"\"\"Helper function to locate pin number for ccw_dual.\n\n        Args:\n            pincount: Total number of pins\n            loc: Starting location\n\n        Returns:\n            pin_number: Starting pin number\n    \"\"\"\n    pins_per_side = pincount // 2\n    if loc == \"top_left\":\n        return 0\n    elif loc == \"bottom_left\":\n        return pins_per_side + 1\n    elif loc == \"bottom_right\":\n        return pins_per_side\n    elif loc == \"top_right\":\n        return pins_per_side * 2 + 1\n    return 0\n\n\ndef clockwise_dual(pincount, init=1, start=\"top_left\", axis=\"x\", **kwargs):\n    \"\"\"Generator for dual row packages counting clockwise.\n\n    Args:\n        pincount: Total number of pins\n        init: Initial starting count (default: 1)\n        start: The starting corner, top/bottom - left/right\n        axis: Pin axis, either x or y. Is depended on num_pins_{x,y}\n        **kwargs: Other keyword arguments\n\n    Returns:\n        Iterator\n    \"\"\"\n    i = _get_pin_cw(pincount, start)\n\n    if axis == \"y\":\n        pins = iter(range(pincount, 0, -1))\n    else:\n        pins = iter(range(pincount))\n\n    for ind in pins:\n        yield ((i + ind) % pincount) + init\n\n\ndef counter_clockwise_dual(pincount, init=1, start=\"top_left\", axis=\"x\", **kwargs):\n    \"\"\"Generator for dual row packages counting counter clockwise.\n\n     Args:\n         pincount: Total number of pins\n         init: Initial starting count (default: 1)\n         start: The starting corner, top/bottom - left/right\n         axis: Pin axis, either x or y. Is depended on num_pins_{x,y}\n         **kwargs: Other keyword arguments\n\n     Returns:\n         Iterator\n     \"\"\"\n    i = _get_pin_ccw(pincount, start)\n\n    if axis == \"x\":\n        pins = iter(range(pincount, 0, -1))\n    else:\n        pins = iter(range(pincount))\n\n    for ind in pins:\n        yield ((i + ind) % pincount) + init\n\n\n# Add available generators to the dictionary\ngenerators = {\n    \"increment\": increment,\n    \"cw_dual\": clockwise_dual,\n    \"ccw_dual\": counter_clockwise_dual,\n}\n\n\ndef get_generator(device_params):\n    \"\"\"Returns a pad number iterator based on device_params and selected generator.\n    Fallback to plain increment.\n\n    Args:\n        device_params: Device parameters dictionary \n\n    Returns:\n        Pad number iterator\n\n    Raises:\n        KeyError: If generator not available\n    \"\"\"\n    # Fallback to plain increment\n    pincount = device_params[\"num_pins_x\"] * 2 + device_params[\"num_pins_y\"] * 2\n    pad_nums = device_params.get(\"pad_numbers\")\n\n    if not pad_nums:\n        return generators[\"increment\"](pincount, **device_params)\n\n    init = pad_nums.get(\"init\", 1)\n\n    gen = generators.get(pad_nums.get(\"generator\"))\n    if not gen:\n        gens = \", \".join(generators.keys())\n        pad_generator = pad_nums.get(\"generator\")\n        raise KeyError(\"{}: Use one of [{}]\".format(pad_generator, gens))\n\n    iterator = gen(pincount, init, **pad_nums)\n    return iterator\n"
  },
  {
    "path": "scripts/tools/quad_dual_pad_border.py",
    "content": "from __future__ import division\n\nimport sys, os\nsys.path.append(os.path.join(sys.path[0],\"..\",\"..\")) # load kicad_mod path\nfrom KicadModTree import *  # NOQA\nfrom pad_number_generators import get_generator\n\ndef add_dual_or_quad_pad_border(kicad_mod, configuration, pad_details, device_params):\n    pad_shape_details = {}\n    pad_shape_details['shape'] = Pad.SHAPE_ROUNDRECT\n    pad_shape_details['radius_ratio'] = configuration.get('round_rect_radius_ratio', 0)\n    if 'round_rect_max_radius' in configuration:\n        pad_shape_details['maximum_radius'] = configuration['round_rect_max_radius']\n\n    if 'hidden_pins' in device_params:\n        pad_shape_details['hidden_pins'] = device_params['hidden_pins']\n    if 'deleted_pins' in device_params:\n        pad_shape_details['deleted_pins'] = device_params['deleted_pins']\n\n    if device_params['num_pins_x'] == 0:\n        radius = add_dual_pad_border_y(kicad_mod, pad_details, device_params, pad_shape_details)\n    elif device_params['num_pins_y'] == 0:\n        radius = add_dual_pad_border_x(kicad_mod, pad_details, device_params, pad_shape_details)\n    else:\n        radius = add_quad_pad_border(\n            kicad_mod, pad_details, device_params, pad_shape_details,\n            configuration.get('kicad4_compatible', False))\n\n    return radius\n\n\ndef add_dual_pad_border_y(kicad_mod, pad_details, device_params, pad_shape_details):\n    init = 1\n    increment = get_generator(device_params)\n\n    pa = PadArray(\n            initial= init,\n            type=Pad.TYPE_SMT,\n            layers=Pad.LAYERS_SMT,\n            pincount=device_params['num_pins_y'],\n            x_spacing=0, y_spacing=device_params['pitch'],\n            increment=increment,\n            **pad_details['left'], **pad_shape_details,\n            )\n    kicad_mod.append(pa)\n    init += device_params['num_pins_y']\n    kicad_mod.append(PadArray(\n        initial= init,\n        type=Pad.TYPE_SMT,\n        layers=Pad.LAYERS_SMT,\n        pincount=device_params['num_pins_y'],\n        x_spacing=0, y_spacing=-device_params['pitch'],\n        increment=increment,\n        **pad_details['right'], **pad_shape_details,\n        )\n    )\n\n    pads = pa.getVirtualChilds()\n    pad = pads[0]\n    return pad.getRoundRadius()\n\n\ndef add_dual_pad_border_x(kicad_mod, pad_details, device_params, pad_shape_details):\n    #for devices with clockwise numbering\n    init = 1\n    increment = get_generator(device_params)\n\n    pa = PadArray(\n            initial= init,\n            type=Pad.TYPE_SMT,\n            layers=Pad.LAYERS_SMT,\n            pincount=device_params['num_pins_x'],\n            y_spacing=0, x_spacing=device_params['pitch'],\n            increment=increment,\n            **pad_details['top'], **pad_shape_details,\n    )\n    kicad_mod.append(pa)\n    init += device_params['num_pins_x']\n    kicad_mod.append(PadArray(\n        initial= init,\n        type=Pad.TYPE_SMT,\n        layers=Pad.LAYERS_SMT,\n        pincount=device_params['num_pins_x'],\n        y_spacing=0, x_spacing=-device_params['pitch'],\n        increment=increment,\n        **pad_details['bottom'], **pad_shape_details,\n        )\n    )\n\n    pads = pa.getVirtualChilds()\n    pad = pads[0]\n    return pad.getRoundRadius()\n\ndef add_quad_pad_border(kicad_mod, pad_details, device_params, pad_shape_details, kicad4_compatible):\n\n    chamfer_size = device_params.get('chamfer_edge_pins', 0)\n\n    pad_size_red = device_params.get('edge_heel_reduction', 0)\n    if kicad4_compatible:\n        chamfer_size = 0\n        pad_size_red += device_params.get('chamfer_edge_pins', 0)\n\n\n    init = 1\n    corner_first = CornerSelection({CornerSelection.TOP_RIGHT: True})\n    corner_last = CornerSelection({CornerSelection.BOTTOM_RIGHT: True})\n    pad_size_reduction = {'x+': pad_size_red} if pad_size_red > 0 else None\n    increment = get_generator(device_params)\n\n    pa = PadArray(\n            initial= init,\n            type=Pad.TYPE_SMT,\n            layers=Pad.LAYERS_SMT,\n            pincount=device_params['num_pins_y'],\n            x_spacing=0, y_spacing=device_params['pitch'],\n            chamfer_size=chamfer_size,\n            chamfer_corner_selection_first=corner_first,\n            chamfer_corner_selection_last=corner_last,\n            end_pads_size_reduction = pad_size_reduction,\n            increment=increment,\n            **pad_details['left'], **pad_shape_details,\n            )\n    kicad_mod.append(pa)\n\n    init += device_params['num_pins_y']\n    corner_first = copy(corner_first).rotateCCW()\n    corner_last = copy(corner_last).rotateCCW()\n    pad_size_reduction = {'y-': pad_size_red} if pad_size_red > 0 else None\n\n    kicad_mod.append(PadArray(\n        initial= init,\n        type=Pad.TYPE_SMT,\n        layers=Pad.LAYERS_SMT,\n        pincount=device_params['num_pins_x'],\n        y_spacing=0, x_spacing=device_params['pitch'],\n        chamfer_size=chamfer_size,\n        chamfer_corner_selection_first=corner_first,\n        chamfer_corner_selection_last=corner_last,\n        end_pads_size_reduction = pad_size_reduction,\n        increment=increment,\n        **pad_details['bottom'], **pad_shape_details,\n        )\n    )\n\n    init += device_params['num_pins_x']\n    corner_first = copy(corner_first).rotateCCW()\n    corner_last = copy(corner_last).rotateCCW()\n    pad_size_reduction = {'x-': pad_size_red} if pad_size_red > 0 else None\n\n    kicad_mod.append(PadArray(\n        initial= init,\n        type=Pad.TYPE_SMT,\n        layers=Pad.LAYERS_SMT,\n        pincount=device_params['num_pins_y'],\n        x_spacing=0, y_spacing=-device_params['pitch'],\n        chamfer_size=chamfer_size,\n        chamfer_corner_selection_first=corner_first,\n        chamfer_corner_selection_last=corner_last,\n        end_pads_size_reduction = pad_size_reduction,\n        increment=increment,\n        **pad_details['right'], **pad_shape_details,\n        )\n    )\n\n    init += device_params['num_pins_y']\n    corner_first = copy(corner_first).rotateCCW()\n    corner_last = copy(corner_last).rotateCCW()\n    pad_size_reduction = {'y+': pad_size_red} if pad_size_red > 0 else None\n\n    kicad_mod.append(PadArray(\n        initial= init,\n        type=Pad.TYPE_SMT,\n        layers=Pad.LAYERS_SMT,\n        pincount=device_params['num_pins_x'],\n        y_spacing=0, x_spacing=-device_params['pitch'],\n        chamfer_size=chamfer_size,\n        chamfer_corner_selection_first=corner_first,\n        chamfer_corner_selection_last=corner_last,\n        end_pads_size_reduction = pad_size_reduction,\n        increment=increment,\n        **pad_details['top'], **pad_shape_details,\n        )\n    )\n\n    pads = pa.getVirtualChilds()\n    pad = pads[0]\n    return pad.getRoundRadius()\n"
  },
  {
    "path": "setup.py",
    "content": "#!/usr/bin/env python3\n\nimport os\nimport sys\n\nfrom setuptools import setup\nfrom setuptools import find_packages\n\n\nlong_description = open(os.path.join(sys.path[0], 'README.md')).read()\n\nsetup(\n    name='KicadModTree',\n    version='1.1.2',\n    author='Thomas Pointhuber',\n    author_email='thomas.pointhuber@gmx.at',\n    url='https://github.com/pointhi/kicad-footprint-generator',\n    description=\"creating kicad footprints using python scripts\",\n    long_description=long_description,\n    long_description_content_type='text/markdown',\n    license=\"GPL3+\",\n\n    install_requires=[\n        'future',\n        'pyyaml'\n    ],\n    extras_require={\n        'test': [\n            'pep8',\n            'flake8',\n            'unittest2',\n            'nose2',\n            'nose2-cov'\n        ]\n    },\n    packages=find_packages('.', exclude=[\"*tests*\", \"*examples*\"]),\n    test_suite='tests',\n\n    classifiers=[\n        'Development Status :: 5 - Production/Stable',\n        'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',\n        'Programming Language :: Python',\n        'Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)'\n    ],\n)\n"
  },
  {
    "path": "tox.ini",
    "content": "[pep8]\nmax-line-length = 120\n[flake8]\nmax-line-length = 120\n\n"
  }
]