pax_global_header00006660000000000000000000000064147700524740014524gustar00rootroot0000000000000052 comment=15741995791512509c297b960d8ed9f1545a0bf3 sailcut-1.5.0/000077500000000000000000000000001477005247400131735ustar00rootroot00000000000000sailcut-1.5.0/.addcopyright000066400000000000000000000016311477005247400156560ustar00rootroot00000000000000{ 'directories': [ 'src', 'src/geocpp', 'src/sailcpp', 'tests/geocpp', 'tests/sailcpp', ], 'files': [], 'license': """Copyright (C) Robert Lainé & Jeremy Lainé See AUTHORS file for a full list of contributors. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA """, } sailcut-1.5.0/.github/000077500000000000000000000000001477005247400145335ustar00rootroot00000000000000sailcut-1.5.0/.github/workflows/000077500000000000000000000000001477005247400165705ustar00rootroot00000000000000sailcut-1.5.0/.github/workflows/tests.yml000066400000000000000000000017671477005247400204700ustar00rootroot00000000000000name: tests on: [push, pull_request] jobs: build: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - os: ubuntu-latest - os: macos-latest - os: windows-latest arch: win64_mingw steps: - uses: actions/checkout@v4 - uses: jurplel/install-qt-action@v4 with: arch: ${{ matrix.arch }} version: 6.5.* - uses: msys2/setup-msys2@v2 if: matrix.os == 'windows-latest' with: install: mingw-w64-x86_64-nsis - name: Compile run: | qmake make shell: bash - name: Test run: make check --keep-going shell: bash - name: Build package if: matrix.os != 'ubuntu-latest' run: make package - name: Upload package if: matrix.os != 'ubuntu-latest' uses: actions/upload-artifact@v4 with: name: dist-${{ matrix.os }} path: sailcut-* sailcut-1.5.0/AUTHORS000066400000000000000000000015401477005247400142430ustar00rootroot00000000000000Authors of Sailcut CAD Jeremy Lainé * GeoCpp linear algebra library * Graphics and file I/O code Robert Lainé alias sailcuter * Original Sailcut software and owner of Sailcut name * Sail layout and profile algorithms and implementation Contributors: Stephan Paternotte * Dutch translation * Sailcut CAD icons Peter G. Meuse * Modification of Mitre layout code for laying panels parallel to leech and foot Massimo Cislaghi * Italian translation Stein Strandmoe * Norwegian translation Rolf Nilsen * Norvegian translation update Heinz Wartenburg * German translation Miguel Porfirio * Portuguese translation Cees van Duin * Dutch translation fix Lasse Skjalm * Danish translation Peo Grenholm * Swedish translation Vyacheslav Shvidky * Russian translation sailcut-1.5.0/ChangeLog000066400000000000000000000200361477005247400147460ustar00rootroot00000000000000Sailcut CAD 1.4.1 * improved - Computed area is displayed with 2 more digits to show down to cm2 Sailcut CAD 1.4.0 * improved - Switch to a Single Document Interface. * improved - Open online Sailcut CAD Handbook if it does not exist locally. * improved - Fully port to Qt 5. * improved - Make it easy to compile Sailcut from Qt Creator. Sailcut CAD 1.3.6 * improved - use QMdiArea instead of deprecated QWorkspace * improved - make it possible to compile with Qt 5 Sailcut CAD 1.3.5 * improved - mitre cut2 panels near mitre to luff interrsection * improved - relaxed constraint on jib luff to 20% round to accommodate code zero * improved - relaxed constraint maximum number of radial gores to 12 in radial cut * improved - integration of manual in various operating systems Sailcut CAD 1.3.4 * improved - make it possible to specify a scale when printing drawings * improved - switch to CMake, makes native Windows builds possible Sailcut CAD 1.3.3 * added - saving sail in 3d DXF one panel per file, option DXF(split) * added - saving developed sail in 2d DXF one panel per file, option DXF(split) * added - print preview dialog for previewing text or drawing output * improved - make it possible to select which pages to print * added - Mitre2 layout with panels parallel to leech and foot (contribution from Peter Meuse) * added - foot hem width is now distinct from other hems width * added - make it possible to export to one panel per DXF file * fixed - crash in rare case of perfectly straight luff or leech (indetermined intersection of lower and upper segments) * fixed - crash in case SVG is not present on Linux system * fixed - offset of boat components can now be positive or negative value Sailcut CAD 1.3.2 * added - export sail to SVG vector graphics format * improved - doubled the width of seams between horizontal sections in radial layout * improved - Dutch translation by Stephan Paternote * improved - increased range for mould depth and shaping coefficients * improved - key points printing format * fixed - undersized printing on Windows by using Qt 4.3.4 Sailcut CAD 1.3.1 * fixed - fix a crash on startup (seen on Linux 64-bit) * fixed - save all the type of boat elements (fixes display of saved boats) * improved - manual in French * improved - manual in English * improved - use 3 colors grading for sail panels * improved - use red color for rig and blue color for hull * added - file save and open for rig and hull Sailcut CAD 1.3.0 * added - mast definition : fully operational * added - hull definition : preliminary version not fully operational * improved - redesign user interface as a multiple document interface * improved - add shaded view to the boat viewer * improved - code readability is sailworker * fixed - bug in leech length condition resulting in a crash * fixed - bug in initialisation of shaded view (should fix empty view) * fixed - bug in rounding of profile data * fixed - compilation on MacOS/X with Qt 4.3 (added -framework Cocoa) * fixed - icon for MacOS/X Sailcut CAD 1.2.4 * fixed - remove offset at tack and clew in radial cut * improved - add a stylesheet for the Sailcut CAD Handbook * improved - when possible, use default browser to view the Handbook * added - the Windows version of Sailcut CAD comes with an installer Sailcut CAD 1.2.3 * added - position of max depth, entry and exit angles in mould screen * improved - extend range of sails dimensions and round limits Sailcut CAD 1.2.2 * improved - better layout of coordinates in print developed panels * fixed - fix bug on Jib tack height Sailcut CAD 1.2.1 * improved - increased range of luff and leech shape factor * fixed - fix bug reported by Rob Harms and cleaned up add hems code * added - add a deck to the sail display * improved - make printing of sail drawing consistent with viewer * fixed - fix the display of the 'language' menu entries * fixed - vertical slider of mould inverted * added - add draft French and Spanish versions of the Handbook Sailcut CAD 1.2.0 * added - key points coordinates in printout of developed panels similar to Sailcut4 * added - a drawing describing the radial cut layout in handbook * added - a descrition of developed panel drawing in handbook * added - a description of TXT file formats in the Handbook * improved - switch to Qt version 4 * improved - better handling of non-ASCII characters * improved - use icon for Sailcut CAD window * fixed - correct "Open recent" characterset issue report by Miguel * fixed - correct bug with radial luff gore number Sailcut CAD 1.1.1 * fixed - correct VC++ project files in source distribution * improved - update Dutch translation (thanks Stephan) * improved - update Norwegian translation (thanks Rolf) * improved - update Danish translation (thanks Lasse) * improved - update Portuguese translation (thanks Miguel) * improved - update Russian translation (thanks Slava) * added - document compilation instructions for MacOS/X * added - icons for Sailcut CAD and its files (thanks Stephan) Sailcut CAD 1.1 * added - Russian translation (thanks Slava) * added - wing style of sail for kites (half a kite is displayed) * added - various sail width data displayed when pressing "Compute" button * improved - add support for per-language Handbook * improved - auto-redimension profile views in mould window * added - Danish translation (thanks Peo) Sailcut CAD 1.0 * added - printing of sail data sheet * added - print of developed sail * added - Portugese translation (thanks Miguel) * improved - updated translations Sailcut CAD 0.8.0 * improved - better checks on input data * added - radial cut code * added - calculation of sail area and of diagonal head-clew Sailcut CAD 0.7.0 * improved - use a tabbed view in the main window * added - wireframe view even when OpenGL is enabled * added - Carlson plotter export of developed panels * added - preliminary rig viewer * added - user preferences are stored to file * added - most recently used file list * improved - different file extension for each file type * added - labels for the sail panels * fixed - compiles with Qt 3.3 Sailcut CAD 0.6.1 * added checks on sail dimensions * improved sail mould equations for racing users * fixed compilation/linking problems reported by Torsten Eberhardt * fixed compilation issues on MacOS/X * added Norwegian translation (takk Stein) * added German translation (danke Heinz) * improved the Sailcut CAD Handbook with explanatory figures * added m4 routine to find lrelease and lupdate Sailcut CAD 0.6.0 * seam width is now operational * added facility for hem width around sail edges the leech hem width is twice the hem width on other sides * development screen shows the above material allowance * DXF of developed panel show draw line in blue and cut line in red * cross, twist, horizontal, vertical and mitre cut are all working * added Dutch translation (bedankt Stephan!) * added Italian translation (thanks to Massimo) Sailcut CAD 0.5.5 * big performance gains (4x for sail creation) * internationalisation support * added horizontal layout * added DXF export * added viewer for the Handbook Sailcut CAD 0.5.0 * updated admin/* (KDE build system) * added export of developped panels to file * added plaintext export of sails * added basic twist foot layout * finished mould view * fixed various GUI glitchs (overlapping widgets) * fixed some some GCC warnings * fixed some bugs in the gaff area Sailcut CAD 0.4.0 * added flat panel development * added doxygen comments to the code Sailcut CAD 0.3.10 * added twist to the surface of the sail * added zoom in/out buttons * added OpenGL shading Sailcut CAD 0.3.9 * added pan and zoom * added OpenGL rendering support * fixed "breaks" in the depth calculations * all panels now follow the curved sides of the sail Sailcut CAD 0.3.8 * depth calculation for the sail points * sail mould gets saved and read from file Sailcut CAD 0.3.6 * XML file input/output of sail definition * XML output of sail points * updated docs Sailcut CAD 0.3 * simple flat cross-cut layout sailcut-1.5.0/Doxyfile000066400000000000000000000200761477005247400147060ustar00rootroot00000000000000#--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = "Sailcut CAD" PROJECT_NUMBER = OUTPUT_DIRECTORY = apidocs CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English USE_WINDOWS_ENCODING = NO BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = NO STRIP_FROM_PATH = STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES DISTRIBUTE_GROUP_DOC = NO TAB_SIZE = 8 ALIASES = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = NO EXTRACT_PRIVATE = NO EXTRACT_STATIC = NO EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_DIRECTORIES = YES FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = src FILE_PATTERNS = RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXAMPLE_PATH = EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = YES INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = YES TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = YES TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = YES LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = NO USE_PDFLATEX = NO LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml XML_SCHEMA = XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = MAX_DOT_GRAPH_WIDTH = 1024 MAX_DOT_GRAPH_HEIGHT = 1024 MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO sailcut-1.5.0/LICENSE000066400000000000000000000431361477005247400142070ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. sailcut-1.5.0/README.md000066400000000000000000000016261477005247400144570ustar00rootroot00000000000000# Sailcut CAD - sail designer ## About Sailcut CAD is a software for designing boat sails and developing them into flat panels. Sailcut CAD screenshot It is distributed under the [GNU General Public License v2.0](LICENSE). See the [AUTHORS](AUTHORS) file for a full list of contributors. ## Documentation The Sailcut CAD Handbook is available in 3 languages at [sailcut.com](https://www.sailcut.com/handbook/en/). ## Building Sailcut CAD is built using the [Qt 6](https://www.qt.io) development framework. To build Sailcut CAD yourself, get the source code, [install Qt](https://www.qt.io/download-qt-installer-oss) then run: ```shell qmake make ``` This will produce the following binaries: - Linux: `bin/sailcut` - macOS: `bin/Sailcut CAD.app` - Windows: `bin/sailcut.exe` sailcut-1.5.0/doc/000077500000000000000000000000001477005247400137405ustar00rootroot00000000000000sailcut-1.5.0/doc/en/000077500000000000000000000000001477005247400143425ustar00rootroot00000000000000sailcut-1.5.0/doc/en/coordinates_system.fig000066400000000000000000000030441477005247400207500ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 3 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 630 9000 1755 8055 8235 8055 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 1755 8055 1755 1080 2 3 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 6 2250 7560 4095 1845 5355 1350 6660 7200 2205 7560 2250 7560 2 3 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 6390 4275 5805 5040 2070 5040 2925 4275 6390 4275 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 3330 4275 2880 4815 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 6390 4275 6660 4275 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 4284 4282 3956 4676 3 2 0 1 4 7 50 -1 -1 0.000 0 0 0 3 3330 4275 4005 4680 6030 4275 0.000 -1.000 0.000 3 2 0 1 0 7 50 -1 -1 0.000 0 0 0 3 3915 2520 4635 2700 5580 2475 0.000 -1.000 0.000 3 2 0 1 0 7 50 -1 -1 0.000 0 0 0 3 2745 6030 3510 6345 6390 5940 0.000 -1.000 0.000 4 0 0 50 -1 0 12 0.0000 4 150 510 1035 1035 Y axis\001 4 0 0 50 -1 0 12 0.0000 4 150 495 900 9135 Z axis\001 4 0 0 50 -1 0 12 0.0000 4 150 510 7875 8370 X axis\001 4 0 0 50 -1 0 12 0.0000 4 90 105 6570 4185 x\001 4 0 0 50 -1 0 12 0.0000 4 150 330 4095 7590 foot\001 4 0 0 50 -1 0 12 0.0000 4 150 285 3195 3465 luff\001 4 0 0 50 -1 0 12 0.0000 4 150 435 5985 3510 leech\001 4 0 0 50 -1 0 12 0.0000 4 195 1050 3780 4860 profile depth\001 4 0 0 50 -1 0 12 0.0000 4 195 1395 4005 4185 profile local cord\001 4 0 0 50 -1 0 12 0.0000 4 90 90 2745 4860 z\001 sailcut-1.5.0/doc/en/develop_panel_drawing.fig000066400000000000000000000071631477005247400213700ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 3 6705 3510 7155 5040 7245 6615 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 3 1215 6750 1620 5085 2565 3375 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 3 900 6930 1350 5085 2430 3105 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 3 6885 3285 7425 5040 7515 6975 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 1 3 0 0 1.00 120.00 240.00 0 0 1.00 120.00 240.00 900 1350 900 7290 9900 7290 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1710 2385 2565 3375 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 4230 2655 3960 3285 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 6390 2745 6120 3600 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 7965 2385 6705 3510 2 1 0 1 9 7 50 -1 -1 0.000 0 0 -1 1 1 3 0 0 1.00 90.00 180.00 0 0 1.00 90.00 180.00 1170 4500 1215 6750 8595 6570 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2880 7785 3240 7020 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 900 8100 1215 6750 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 6525 6525 6165 7875 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 7245 6615 7605 8055 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1575 6345 1215 6750 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 3 0 0 1.00 90.00 180.00 0 0 1.00 90.00 180.00 2610 1530 2565 3375 8955 3600 2 2 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 5 900 7290 7515 7290 7515 2970 900 2970 900 7290 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 2790 2745 2565 3375 2610 3375 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 900 7290 810 7380 3 2 0 2 1 7 50 -1 -1 0.000 0 0 0 4 1215 6750 3735 7020 6075 6570 7245 6615 0.000 -1.000 -1.000 0.000 3 2 0 2 1 7 50 -1 -1 0.000 0 0 0 4 2565 3375 4185 3285 6030 3555 6705 3510 0.000 -1.000 -1.000 0.000 3 2 0 2 4 7 50 -1 -1 0.000 0 0 0 4 900 6930 3690 7290 6030 6840 7515 6975 0.000 -1.000 -1.000 0.000 3 2 0 2 4 7 50 -1 -1 0.000 0 0 0 4 2430 3105 4185 3015 6030 3285 6885 3285 0.000 -1.000 -1.000 0.000 4 0 0 50 -1 0 12 0.0000 4 135 705 2115 8055 dY = -10\001 4 0 0 50 -1 0 12 0.0000 4 135 750 2115 7830 dX = 321\001 4 0 1 50 -1 0 12 0.0000 4 135 540 1665 6210 dX = 0\001 4 0 1 50 -1 0 12 0.0000 4 135 540 1665 6435 dY = 0\001 4 0 0 50 -1 0 12 0.0000 4 135 750 7785 2025 X = 1789\001 4 0 0 50 -1 0 12 0.0000 4 135 645 7785 2295 Y = 678\001 4 0 0 50 -1 0 12 0.0000 4 135 645 1395 2070 X = 234 \001 4 0 0 50 -1 0 12 0.0000 4 135 645 1395 2340 Y = 789\001 4 0 0 50 -1 0 12 0.0000 4 135 540 5265 8145 dY = 2\001 4 0 0 50 -1 0 12 0.0000 4 135 855 5265 7875 dX = 1345\001 4 0 9 50 -1 0 12 0.0000 4 135 240 1215 4500 dY\001 4 0 0 50 -1 0 12 0.0000 4 135 750 7740 7965 X = 1890\001 4 0 0 50 -1 0 12 0.0000 4 135 540 7740 8235 Y = 35\001 4 0 0 50 -1 0 18 0.0000 4 195 645 3600 5040 Panel\001 4 0 0 50 -1 0 12 0.0000 4 135 750 4050 2340 dX = 345\001 4 0 0 50 -1 0 12 0.0000 4 135 540 4050 2565 dY = 5\001 4 0 0 50 -1 0 12 0.0000 4 135 600 6075 2700 dY = -2\001 4 0 0 50 -1 0 12 0.0000 4 135 855 6075 2475 dX = 1234\001 4 0 1 50 -1 0 12 0.0000 4 135 540 2835 2520 dX = 0\001 4 0 1 50 -1 0 12 0.0000 4 135 540 2835 2700 dY = 0\001 4 0 1 50 -1 0 12 0.0000 4 180 1185 8145 3420 dX upper edge\001 4 0 9 50 -1 0 12 0.0000 4 180 1170 8145 6435 dX lower edge\001 4 0 1 90 -1 0 12 0.0000 4 135 1740 5130 5040 DRAW line is in blue\001 4 0 1 50 -1 0 12 0.0000 4 180 1185 2745 1710 dY upper edge\001 4 0 4 50 -1 0 12 0.0000 4 135 435 315 7335 X = 0\001 4 0 4 50 -1 0 12 0.0000 4 135 435 315 7560 Y = 0\001 4 0 4 50 -1 0 18 0.0000 4 195 210 9540 7155 Y\001 4 0 4 50 -1 0 18 0.0000 4 195 210 585 1845 X\001 4 0 0 50 -1 0 12 0.0000 4 135 540 270 8145 X = 15\001 4 0 0 50 -1 0 12 0.0000 4 135 540 270 8370 Y = 25\001 4 0 4 50 -1 0 12 0.0000 4 135 1440 5445 5445 CUT line is in red\001 sailcut-1.5.0/doc/en/head_gores_definition.fig000066400000000000000000000034411477005247400213430ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 1350 8685 3555 7245 6075 8595 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 3690 3735 4230 5985 6075 8595 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 4 3510 675 3105 3735 2430 6030 1350 8685 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 3690 675 4230 3735 4905 5985 6075 8595 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2610 3735 4905 3735 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 4 3600 675 3566 3738 2981 6033 1350 8685 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2025 6005 5535 5985 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3602 5985 3510 8730 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 1350 8685 3600 5985 6075 8595 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3420 675 3825 675 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 3420 675 1350 8685 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 2 1 1.00 60.00 120.00 5175 2700 4590 2700 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 2 1 1.00 60.00 120.00 2295 2700 2880 2700 3 0 0 1 0 7 50 -1 -1 0.000 0 0 0 3 1350 8685 3510 8820 6075 8595 0.000 1.000 0.000 3 0 0 1 0 7 50 -1 -1 0.000 0 0 0 4 3825 675 4950 3735 5535 5940 6075 8595 0.000 1.000 1.000 0.000 4 0 0 50 -1 0 16 0.0000 4 195 570 2700 810 Head\001 4 0 0 50 -1 0 14 0.0000 4 210 2070 4860 2520 4 Radial gores in total\001 4 0 1 50 -1 0 14 0.0000 4 165 1815 855 2925 from Head to Tack\001 4 0 1 50 -1 0 14 0.0000 4 195 1470 990 2610 2 Luff gores go\001 4 0 0 50 -1 0 16 0.0000 4 195 555 810 8955 Tack\001 4 0 0 50 -1 0 16 0.0000 4 195 555 6165 8820 Clew\001 4 0 0 50 -1 0 14 0.0000 4 150 435 3330 9045 Foot\001 4 0 0 50 -1 0 14 0.0000 4 150 585 5760 6435 Leech\001 4 0 1 50 -1 0 14 0.0000 4 150 480 1440 6300 Luff \001 4 0 0 50 -1 0 14 0.0000 4 165 2160 5400 4590 This sail has 3 sections\001 sailcut-1.5.0/doc/en/index.docbook000066400000000000000000001726251477005247400170300ustar00rootroot00000000000000
The Sailcut CAD Handbook Robert Lainé Jeremy Lainé Sailcut CAD 1.5.0 - 23 March 2025 Introduction About Sailcut CAD Sailcut is a software for designing boat sails and developing then into flat panels. Sails can be either 4 sided sails like for old timer gaff rig or 3 sided sails like jibs or main sails for Marconi rig. The first version of Sailcut was developed in 1978 and used by Robert Lainé for making the sails of his IOR 1/4 ton named "Flying Sheep III". Sailcut has been available on the web since 1994 and is used by many professional and amateur sail makers for offshore racing, cruising and recently for model yacht. Sailcut uses a unique mathematical definition of the surface of the sail which ensure that the sail profile is smooth and aerodynamic. How to obtain Sailcut CAD? You can download the latest version of Sailcut CAD from the project's home page at . Technical information on the code Sailcut CAD is written with portability in mind. As such it is written in C++ and uses the Qt library from Trolltech for the graphical user interface. Sailcut CAD uses OpenGL to display the 3D view of the sail. Sailcut CAD is known to compile and run on GNU/Linux, Microsoft Windows and MacOS/X. Using Sailcut CAD Upgrade notes As of release 0.6.5, Sailcut CAD uses different extensions for each file type instead of ending all files with ".xml". If you wish to open sails created with a previous version of Sailcut CAD you should rename your sail definition file so that it ends with ".saildef". When opening the resulting old file, all dimensions data except for the mould will be preserved. Redefine your sail mould, then save the file. User preferences Preferences file Your preferences are stored in a file called .sailcutrc. On UNIX-like platforms, this file is located in your HOME directory. On Windows this file is located in your Documents and Settings\USER directory. Internationalisation As of release 0.5.5, Sailcut CAD has support for internationalisation. Translations of the user interface in various languages are currently provided. On startup, Sailcut selects the language corresponding to your locale. You can use the Language submenu of the View menu to switch to another language. Creating a sail When you start Sailcut CAD, you are presented with a default sail. At the top of the window you will find a number of roll down menus. The File menu is used for loading an existing sail, saving the parameters of the sail and Export the developed panels. You can modify the dimensions of the sail by using the Dimensions entry of the View menu. You can modify the profile of the sail through the Mould entry of the View menu. You can display several sails on the same rig through the Rig entry of the View menu. Dimensions dialog screen You can access the sail dimensions dialog from the Dimensions entry of the View menu. The program is tailored to design either triangular or quadrangular boat sails. A classical triangular sail is essentially a quadrangular sail with a very small top edge. The surface of the sail is generated from a single set of equations defining the profile of the sail at all levels. The profiles rest on the edges of the sails which are defined by their length and the amount of round (also called roach) in each side and the twist of the sail. The Definition window is divided into a number of boxes which group the parameters defining the sail. You can use the Compute button to compute and display ancillary data like IRC width. This can result in some text box color being changed. Red color indicate that the value exceed the upper limit and yellow indicate that it is below the lower limit. The value itself will be changed to the acceptable limit. When you have finished entering the dimensions, press OK to display the sail in 3D. Rig geometry The first step is to select the type of sail you are going to work on, then enter the data defining the correspônding rig geometry and sail plan such that the sail will have the proper orientation. Select the type of sail by pressing the corresponding Radio Button: Jib for any sail which will be set on a stay, Mainsail for any sail set on a mast, Wing for any type of kite symetrical about the foot. The rig data are used for displaying the sails in their proper relative position with the rig.
Sailcut plan definition
Sail identifier You enter there a text describing the sail you are working on (maximum 40 characters spaces included). Sail dimensions This is where the dimensions of the sail are entered. On a main sail the minimum value for the gaff length (headboard) is constrained to 5 mm. Value smaller than that will default back to 5 mm. The gaff angle is constrained to 90 degrees maximum between the gaff and the luff. Positive round (roach) of the luff, foot, leech and gaff extend the sail outside of the straight edge line. Negative round is equivalent to hollowing that edge of the sail. The position of the round or roach is expressed in percentage of the side length starting from the lower or most leftward end of that edge.
Sailcut edges definition
Dimensions and angles defining the sail plan are expressed in millimetre and degrees. Length of the sail sides and diagonal are the 3D straight line distance between the corners of the sail. The actual length on the finished sail lais on the floor can be slightly longer depending on the shape of the sail. For example, the foot length entered in the screen below is 3600 mm. If the foot camber is null then that will be the actual distance between clew and tack (straight foot) of the finished sail. If a 10% camber is entered for the foot depth, then the actual foot will be the length of the arc which has 10% camber, that is 2.7% longer than the straight line foot length. Having entered the sail main dimensions you can press on the Compute button to obtain additional informations on the sail, like the X-Y coordinates of the corners of the sail, the perpendicular length LP measured from the clew to the luff as well as IRC racing rules width. The X-Y coordinates of the sail corners are usefull to quickly adjust the data entered. For example if you find that the clew height (Y) is way below or above the height of the tack when you would like it to be leveled, then you can substract or add the difference to the leech length.
Layout Click on the radio button corresponding to the desired layout of the sail. The layout of the panels does not affect the shape of the sail which is defined by its dimensions and its mould. Except for the Radial cut layout, the number of panels is determined by the cloth width and seam width entered in the Cloth box. The most commonly used layout is the Crosscut. The panels are laid perpendicular to the straight line joining the peak to the clew of the sail. The Twist foot layout is similar to the cross cut except that the lower panels are rotated such that they do not intersect the foot of the sail. The Horizontal cut layout lay the seams in the horizontal plane. This option can be used to visualise the profile of the sail at various levels and to output files with the 3D coordinates of the sails for use by CFD tools. The Vertical cut layout places the panels parrallel to the straight line joining the peak to the clew of the sail. This is the favorite layout for the old timer's main sail. The Mitre cut layout is the favorite for the old timer's genoa. The sail is divided in two parts by a line joining the clew to the mid point on the luff and the panels organised to be perpendicular to the foot in the lower part of the sail and perpendicular to the leech in its upper part. The Radial cut is used mostly for competition as the cloth is mostly aligned with the directions of maximum strain. When using the Radial cut option it is important to understand the definition of the number of sections, number of radial gores and number of luff gores (see ).
Radial cut gores definition
Sail shape You enter there the depth of the sail at 3 levels, near the foot, in the middle of the sail(the exact position being defined in the mould screen) and near the top of the sail. The twist angle is the angle expressed in degrees by which the top of the sail is rotated with respect to the foot. The twist is globally determined by the amount by which the apparent wind at the top of the mast is rotated with respect to the apparent wind at deck level. For a jib the twist is sometime driven by the need to have the upper part of the leech sufficiently open to clear the spreaders. For a mainsail the twist is also driven by the ability of the rig to carry the tension in the leech, in particular a gaff rig will have more twist in its main sail than a Bermuda rig. It is important that the twist angle entered in Sailcut reflects the reality of the shape of the leech when sailing in an average wind. The sheeting angle value is the actual sheeting angle measured from the boat centerline when the sail is set on the boat. For a jib the minimum value is 5 degrees. The value is of importance to ensure that the sail is properly positioned when displayed in the rig viewer. You can then visualise for example the slot between a jib and the main sail as set on the boat. Cloth Enter there the width of cloth used, the width of the seams between adjacent panels, the width of material to be added to the leech to make the leech hem and the width of material for the foot hem and for other edges hems. describes the location of the various hems and seam width. Sailcut will compute the panels such that they fit within the declared cloth width including the seam and hems width as appropriate, except for a radial cut sail for which the width of each panels is computed from the number of radial panels entered. Note that when using the radial layout, the seam width between horizontal sections will be twice the width of the seams between adjacent panels of the same section.
Sailcut seams and hems definition
Mould dialog screen You can access the mould dialog from the Mould entry of the View menu. The depth and the shape of the sail can be entered at three levels located at the bottom (foot) the middle (sail's maximum depth height can be adjusted) and at the top of the sail. The position of the point of maximum depth of a profile is shown under the depth value. This position which depend of the luff and leech shape factors is expressed in relation to the cord of the profile. For exemple: 0.34 means that the point of maximum depth is at 34% of the local cord counting from the luff end of the profile. The luff shape and the leech shape can be adjusted for the Top profile and Middle profile only. The foot profile is always an arc of circle. Under the luff shape factor, the corresponding value of the angle of entry of the profile is provided in degree. The angle under the leech shape factor is the exit angle of the profile. These angles are refered to the local cord and if you want to know for exemple the real entry angle of a profile with respect to the axis of the boat you have to add to the entry angle the twist at the level of the profile plus the sheeting angle. The vertical position of the sail's maximum depth profile is controled by the vertical slide bar to the right of the left vertical frame. In order to avoid that the leech makes a hook in the upper part of the sail when the wind increases, it is recommended that the Top profile luff shape value be higher than that of the middle profile and that the leech shape value at the top be lower than the middle value. View controls It is possible to zoom, pan and rotate the sail in the view window: Rotation : you can control the rotation that is applied to the sail by using the elevation and azimuth sliders located at the edges of the graphic pane. Pan : click on a point with the left mouse to center the view on that point. Zoom : to zoom in press CTRL + and to zoom out press CTRL -. You can also use the zoom buttons in the view controls or your mouse wheel to zoom in and out. Sail panels development The developed sail is display by clicking on the Development tab from Sailcut CAD's main window. This presents you with a view of the developed (flat) panels of the sail. The view controls are the same as those of the main window. The blue line represents the edge of the finished panel (draw line) and the red line represents the outer edge taking into account the seam and hems width allowance (cut line). You can export the points which define the edges of the developed panels with the draw line and the cut line to the following file formats from the Export development submenu of the File menu: Carlson Design plotter (.sp4) using the to Carlson plotter menu entry. DXF file using the to DXF menu entry. All the panels will be placed in a single file with one panel per layer. Multiple DXF files using the to DXF (split) menu entry. Each panel will be placed in a separate file on layer 1. The name of the file is the base name entered completed with the number of the panel (0,1,2,...). XML dump of the points using to XML sail menu entry (see for file format details). plain ASCII text dump of the points using the to TXT sail menu entry (see for file format details). Loading and saving sails Once you have customised your sail, you can save it to a file by using the Save or Save As entries in the File. You can reload it by using the Open entry of the File next time you want to work on it. Both the sail's dimensions and the parameters of the mould are saved simultanously. This feature allows you to reload a sail and reuse its mould even if you change the dimensions of the sail to fit a new rig. Sailcut CAD uses XML files to store the sail data. These files are plain text so they can easily be viewed using your favourite text editor. Exporting 3D sails In addition to Sailcut CAD's native file format, it is possible to export all the 3D points located on the edges and seams of the panels that make up a sail. You can export the three dimensional sail to the following file formats from the Export 3D sail submenu of the File menu: DXF file using the to DXF menu entry. All the panels will be placed in a single file with one panel per layer. Multiple DXF files using the to DXF (split) menu entry. Each panel will be placed in a separate file on layer 1. The name of the file is the base name entered completed with the number of the panel. XML dump of the points using the to XML sail menu entry (see for file format details). Plain ASCII text dump of the points using the to TXT sail menu entry (see for file format details). SVG (Scalable Vector Graphics) file using the to SVG menu entry. Printing data and drawings The Print submenu of the File menu offers various printout possibilities: The data menu entry will print the data of the sail. The drawing menu entry will print a drawing of the complete sail. A dialog box allows to preview the printout with a spin box to adjust the scale factor. The scale factor is the factor by which the sail size is multiplied to obtain the drawing size. The scale factor can be as small as 0.001 (1000 mm sail will be printed as 1mm), the default value is such that the sail fits in 80% of the paper size. The develop menu entry will print all the developed panels with key points coordinates (1 panel per page). A dialog box allows to preview the printout with a spin box to adjust the scale factor as for the complete sail. The layout of the paper is set to landscape. The definition of the developed panel key points coordinates is given in . The X,Y coordinates are absolute coordinates referenced to the lower left corner of the box enveloping the contour of the CUT line of the panel (edge of cloth). The dX,dY coordinates are relative to the straight line joining the end of the corresponding edge and it should be remembered that the origin of dX is at the left end of the edge and positive value of dY indicate that the point is left of the straight line joining the origin to the end points of the edge. The printout scaling is such that the sail drawing and the largest developed panel automatically fit in one page. For printing panels to a precise scale it is preferable to export the developed sail in a DXF file and use a CAD package to print the panels.
Developed panels drawing
Creating a rig This module allow the design of a mast with up to 3 levels of spreaders. It is accessed via the Rig entry of the main screen's File New menu. The Dimensions entry of the View menu will display the screen from which you can enter and modify the dimensions of the rig. The definition of the various dimensions is given in . Please note that, in order to allow the design of sails independently from the design of the rig, the definition of the mast rake and mast curve are refered to the full mast length which are different from that of the sail luff rake and curve of the sail design module which are refered to the sail luff length. This rig module provides the data to be used when designing the mainsail which fit on the rig.
Sailcut Rig definition
Saving and Loading a rig file The Save entry of the File menu is used to save a rig. Any Rig which has been saved can be later opened as an entity with the Open entry of the File menu and can be used as an element to constitute a boat. View controls The controls of the viewer are identical to those of the sail viewer. You can rotate the rig with the sliders located around the graphic display, zoom with the mouse's wheel, pan with the mouse left click, view in wireframe or shaded surface modes. Rig dimensions The Dimensions entry of the View menu display the rig dimension screen which is divided in boxes corresponding to the entities listed below. Note that angles are expressed in degrees and linear dimensions in millimetres. Rig ID A free text identifying or describing the rig can be entered in this box. The number of characteres is limited to 40. Fore triangle The height = I and base = J of the fore triangle are entered in the corresponding fields. Note that the dimensions are measured in the vertical and horizontal directions. In particular be carefull when measuring the J dimension when the mast is inclined. Mast The mast is assumed to have a constant section from foot to tip. The heights are refered to the stem fitting horizontal plane. Mast height = MH is the straight line height of the mast top above the stem. It shall be greater than J. Mast round = MRnd is the maximum deviation from the straight line. Mast round position = MRndPos spin box is used to enter the relative height of the point at which the mast round is measured. It is expressed in percentage of the mast height. Mast rake = MRkM is the horizontal distance between the tip of the mast and its foot. Sailcut CAD will compute and display the corresponding mast rake angle = MRkD. Mast cord = MC is the fore-aft width of the mast section. Mast width = MW is the transverse width of the mast section. Mainsail See below the chapter about mainsail luff curve. Shrouds Cap shrouds height = CSH is the height of the point of attachment of the outer shroud to the mast. Cap shrouds base width = CSB is the base width of the outer shroud measured from the central line. Lower shrouds base width = LSB is the base width of the lower (inner) shroud which shall be smaller or equal to the cap shroud base width. Spreaders Number of spreaders = SPNB can be from 0 (none) to maximum 3. If only no spreader is present, the outer shroud will be identical to the lower shroud. Spreaders height SPH are entered in ascending order with 1 being the lowest. Spreaders length SPW are measured from the ecentral line. Checking and validating data Use the Check button any time after entering new data to perform a verification that the data entered are consistant with a reasonable rig design and the ancillary data are computed. In case of inconsistancy between data, the color of the fonts will tell you which data is suspicious. Red indicate a too high value, purple a too low value and blue signals which related parameter is to be checked. Once you have entered all necessary data, click on the OK button to close the rig dimensions window and display it. If there is an incompatibility in the data, the dimensions window will not close until it is corrected. Mainsail luff curve In most case users have designed sails independently from the design of a rig. However the user may wish to design a sail compatible with a rig. In the rig dimensions screen, the box labeled Mainsail is used to compute the mainsail tack position and luff curve which will fit the rig. These data can be used for creating the corresponding mainsail or to verify that a mainsail luff curve will fit the rig. The only data to be entered are the mainsail tack height = BAD and head height = HAD. Sailcut CAD will compute the other data.
Creating a hull Please note that this module is not yet fully operational, for the time being a single chine hull ouline will appear whatever the number of chine is entered. This module allow the design of a hard chines hull. It is accessed via the Hull entry of the main screen's File New menu. View controls The controls of the viewer are identical to those of the sail viewer. You can rotate the hull with the sliders located around the graphic display, zoom with the mouse's wheel, pan with the mouse left click, view in wireframe or shaded surface modes. Saving and Loading a hull file The Save entry of the File menu is used to save a hull. Any hull which has been saved can be later opened as an entity with the Open entry of the File menu and can be used as an element to constitute a boat. Hull dimensions You can modify the dimensions of the hull by using tab Deck and bottom of the screen Dimensions entry of the View menu. The deck and bottom screen is divided in boxes in which the various dimensions of the hull are entered. The hull is constructed upward from the bottom planks. The most important line is the chine which defines the outer edge of the bottom planks. The height are refered to any arbitrary horizontal datum plane located conveniently near the bottom of the hull. Angles are measured in degrees from the same horizontal datum plane. Hull ID A free text identifying or describing the hull being designed can be entered in this box. Deck Forward height Aft height Bottom Length Stem angle Transom angle Forward height Chine angle Aft height Max width Max width position Aft width Forward shape Aft shape Dead rise angle Bottom sweep angle Planking Number of planks Automatic planking Top plank angle lower plank angle Checking and validating data Use the Check button any time after entering new data to perform a verification that the data entered are consistant with a reasonable hull design and the ancillary data are computed. In case of inconsistancy between data, the color of the fonts will tell you which data is suspicious. Red indicate a too high value, purple a too low value and blue signals which related parameter is to be checked. Once you have entered all necessary data, click on the OK button to close the hull dimensions window and display it. If there is an incompatibility in the data, the dimensions window will not close until it is corrected. Planks adjustment Individual side planks can be ajusted by using the tab Planks of the screen Dimensions entry of the View menu. The planks screen is divided in boxes in which the various dimensions of the hull are entered. Forward height Aft height Plank angle Sweep angle Chine angle Checking and validating data Use the Check button any time after entering new data to perform a verification that the data entered are consistant with a reasonable hull design and the ancillary data are computed. In case of inconsistancy between data, the color of the fonts will tell you which data is suspicious. Red indicate a too high value, purple a too low value and blue signals which related parameter is to be checked. Once you have entered all necessary data, click on the OK button to close the hull dimensions window and display it. If there is an incompatibility in the data, the dimensions window will not close until it is corrected. Creating a boat This boat design module allows you to assemble hull, rig and sails files created earlier and make a virtual boat. It is accessed via the Boat entry of the main screen's File New menu. View controls The controls of the viewer are identical to those of the sail viewer. You can rotate the hull with the sliders located around the graphic display, zoom with the mouse's wheel, pan with the mouse left click, view in wireframe or shaded surface modes. Adding and removing boat elements The boat viewer is initially showing a black screen and files are added via the Add entry of the main screen's File menu. A new tab will appear with the details of the file selected and the element identification which was given at the time of creating the element (sail ID, Rig ID, Hull ID). A boat element can be removed by selecting the corresponding tab and then clicking on the Remove button. Saving and loading a boat file The Save entry of the File menu is used to save the file of a boat with any combination of hull rig and sails. The file of a boat can be opened as an entity with the Open entry of the File menu. Shifting boat elements All boat elements will be displayed in the position entered at the time the element was created. Please remember that the point of coordinate X=0, Y=0, Z=0 is located at the forward end of the deck of the hull (stem). The boat elements can be individually shifted in X, Y or Z direction by adjusting the corresponding offset in the element spinbox, then clicking on the Update button. At any time, clicking on the Reload button will restore the corresponding element to its initial position. Sails surface formulation in Sailcut This section is a translation of the paper presented by Robert Lainé to the second Workshop Science Voile IRENAV in Brest, France, on 21 May 2004. History Sailcut software was initially written in 1978 in Basic language on a computer with 1.6 KB of memory, one line text screen and a small 32 columns text printer. Hence the necessity to keep the surface formulation simple for designing the sails which I built and used on my IOR ¼ton. This short cycle: "design => manufacturing => utilisation => modification", without commercial constraints linked to sailmakers work habits has allowed me to converge quickly on a compact and robust way of describing the sail surface. The method is valid for classical triangular sails and also for quadrangular sails used on old timers and modern rigs with very large headboard. Later on, the use of Sailcut by professional sailmakers has necessitated the addition of graphic interface to the kernel of Sailcut, but that is an other story... Since 1993 the Microsoft Visual Basic version of Sailcut is available at and since 2003, the source code of Sailcut re-written in C++ is available at . For protection of the intellectual rights, the name Sailcut is a registered trademark, but the author maintains free and unrestricted access to Sailcut. Of the complexity of the definition of the surface of a sail A sail is a complex surface which sailmakers have historically defined by notions like depth at various height and position of the point of maximum depth along the local cord of the profile. This method of defining the surface of the sail by control points allows for an easy comparison of the shape between the intended design and reality. Unfortunately a large number of different surfaces can pass through these few control points. Then notions like the slope at the leading edge and trailing edge of the profiles were introduced to help sailmaker get a better control of the shape of the sail profile. Using interpolation between basic control points, with or without constraints on the tangents at the extremities of the profiles, to determine the depth of the sail in all points were too demanding for old days personal computer processing capability. From the beginning of my racing activities, I was interested in the aerodynamic of sails. The books Theory of wings sections by Ira H. Abbott and Albert E. von Doenhoff, and Sailing Theory and Practice by C.A. Marchaj convinced me that the distribution of camber along the profile was the determining factor in the quality of a sail profile. I was very sceptical about the definition of a profile by its depth, the position of its maximum depth along the cord and segments of cubic or quadratic curves on either side. Rather than trying to reproduce existing sail shape based on depth measurements, I looked for a law of distribution of its camber giving a reasonably aerodynamic profile on the complete sail surface. The first attempt was to model directly the distribution of camber, however that required to process simultaneously the first and second derivative of the surface many points of the sail surface, far too much work for my small computer. At the time I was racing on the North Sea often in relatively heavy weather for my ¼ ton and I wanted sail profiles with a high peak of pressure very far forward to fight against the tendency of the depth to move backward as the cloth stretched in increasing winds. I finally selected a simple equation defining only the second derivative of the profile and giving a monotonic decrease of its value along the cord of the profile. Experience showed that with the then available cloth, the leech was sometime falling to leeward in the upper part of the sail. I then introduced a second term in the equation to be able to control the minimum value of the second derivative at the leech. This equation is therefore controlled by only two parameters. Some Maths The coordinate system used is such that the plane X-Y contains the tack, the clew and the head of the luff. The X axis is horizontal and orientated positively from tack toward clew. The Y axis is vertical orientated upward and the Z axis (depth) is perpendicular to the X-Y plane. Profiles are defined by the intersection of the surface of the sail with an horizontal plane parallel to Z-X plane. The depth Z of any point of a given profile is a function of the local X ordinate normalised to the profile local cord as shown in .
Sailcut coordinate system
The following equation is used to describe the second derivative of the profile function of X: Z''= K*[-A*(1-X)^AV - AR*X] After a first integration it gives the slope of the profile: Z'= K*[A*(1 - X)^(AV + 1) / (AV+1) - AR/2*X^2 + C] Finally after a second integration the equation giving the depth at any point is: Z = K*[-A*(1-X)^(AV+2) / (( AV+2)*(AV+1)) - AR/6*X^3 + C*X + B] To meet the profile end conditions (X=0, Z=0) and (X=1, Z=0) the constants B and C are: B = A / ((AV + 2) * (AV + 1)) C = AR / 6 - B The maximum depth is obtained when the slope Z' is equal to zero, this allow to calculate K such that the depth at that point is the one desired. The factors AV and AR give a measure of the camber at the leading edge (AV) and trailing edge (AR). Together with the maximum depth value these factors are sufficient to describe the profile of the sail at any height. The factor A defines different families of profiles with a different distribution of fullness fore/aft. In practice A = 1 give good profiles for sails used in light conditions. I prefer to use sail profiles with more fullness forward and a flatter leech as obtained with the factor A = 1 + AV / 4. This is the factor used in Sailcut and it give a good range of utilisation of the sails. The following table give an example of profile data obtained with the above equations. AV = 5.00 AR = 0.02 K = 2.94 A = 2.250 B = 0.054 C =-0.050 curvature = z" / (1+ z'*z')^3/2 xz" z' z curvature 0.0 -6.615 0.955 0.00 -2.503 0.1 -3.912 0.438 0.0674 -3.007 0.2 -2.179 0.140 0.0949 -2.117 0.3 -1.129 -0.021 0.1000 -1.129 0.4 -0.538 -0.101 0.0934 -0.530 0.5 -0.236 -0.138 0.0812 -0.230 0.6 -0.103 -0.154 0.0665 -0.099 0.7 -0.057 -0.161 0.0507 -0.055 0.8 -0.049 -0.166 0.0343 -0.047 0.9 -0.053 -0.172 0.0174 -0.051 1.0 -0.059 -0.177 0.00 -0.056 Having defined a single equation for all profiles it is a matter of varying the maximum depth and the factors AV and AR as function of the height of the profile to generate the complete surface of the sail. The profile at foot level being always an arc of circle, the factors AV and AR are equal to zero and only the depth of the foot is entered by the user. A profile called "mid profile" is located around the middle of the height and the factors AV and AR are set such that the profile has the required shape. A third control profile defined as for the "mid profile" is located at the top of the sail. For all other profiles the depth value is interpolated by a quadratic equation and the factors AV and AR are interpolated linearly between between the foot, the middle and top values. In total 3 values of depth, 2 pairs of factor (AV, AR) and the vertical position of the "mid profile" are used to define the basic mould of the sail. Note that in Sailcut software the value displayed for the luff factor is equal to the AV ceofficient while the leech factor displayed is 50 time the AR coefficient used in the above equations such that the users can use more friendly range of data than second and third decimal figures.
Other aspects of the surface formulation The above basic mould is not sufficient to define a real sail. Indeed the luff, gaff, leech and foot of the sail are never straight and further more the sail profiles are always twisted from the foot to the top of the sail. I use the distance from the point of maximum round to the straight line and two arcs of parabola rejoining the adjacent corners to define the real edges of the sail. The profiles defined by the sail mould described above are resting on the real edges of the sail. The twist of the sail is finally obtained by applying to each profile a rotation around the leading edge end point. It is to be noted that this method of modelling the surface of sails gives shapes without bumps or hollows and guarantees that there is no inversion of camber in the profiles. The method is applicable to triangular and quadrangular sails and Sailcut is commonly used for designing old timers gaff sails.
Where can I find more information about Sailcut CAD? The Sailcut CAD project lives at . This is where you will find links to all matters related to Sailcut CAD! I think I found a bug, what should I do? Sailcut CAD is constantly under development and feedback from users is very welcome! If you think you found bug, visit Sailcut's homepage , you will find instructions in the "Reporting a Bug" section. I would like to help develop Sailcut CAD, what should I do? You can help us improve Sailcut even if you are not a programmer! Simply using Sailcut and reporting any bugs you might find is of considerable help to us. We are also looking for people to help keep translations up to date and to produce new translations. If you are interested in translating Sailcut into your native language, visit the Sailcut CAD homepage and send an email to the development mailing list! If you have some knowledge of C++ and are interested in making Sailcut CAD a better program, visit the Sailcut CAD homepage where you will find both snapshots of the Sailcut CAD code and how to access to the CVS repository. Once you have had a chance to familiarise yourself with the code, contact us via the forums or our mailing lists! File formats used by Sailcut CAD Text representation of developed sail This section describes the structure of the file generated by Sailcut CAD using the to TXT sail entry of the Export development submenu of the File menu. The extension of a text sail file is ".txt". A sail is made of a number of panels, each panel has 4 basic sides : left, top, right, bottom which are joined by a drawing line. The origin is at the bottom left corner of a rectangle surrounding the panel. These four basic sides define the net area of the panel after assembly in the sail. Around the basic panel there is provision for stiching the panels and sail edge hems, the outer side of the panel is defined by four sides named cutLeft, cutTop, cutRight, cutBottom and the material is cut along these sides. Depending on whether or not you have added material for hems around the sail some of these sides may be identical to the basic sides of the panel. Test main sail cross cut (flat) // name of the sail ===== CPanel : 0 ==== // begining of panel 0 == CPanelLabel : name == // marker for panel label name 0 == CPanelLabel : height == // marker for label height 5 == CPanelLabel : color == // marker for label color 1 == CPanelLabel : origin == // marker for label origin coordinates 427.717 764.064 0 // X Y Z coordinates (Z is always =0) == CPanelLabel : direction == // marker for label orientation 168.204 -57.8975 0 == CSide : left == // begin left side of panel #0 92.5718 886.006 0 // X Y Z coordinates of point 0 #1 92.5718 886.006 0 // X Y Z coordinates of point 1 ... == CSide : top == // begin top side #0 92.5718 886.006 0 // X Y Z coordinates of point 0 #1 262.77 886.006 0 ... == CSide : right == // begin right side #0 3533.09 25.5986 0 #1 3526.2 169.113 0 ... == CSide : bottom == // begin bottom side #0 92.5718 886.006 0 #1 259.921 823.943 0 ... == CSide : cutLeft == // begin left cut line #0 0 899.006 0 // X Y Z coordinates of point 0 of left cut line #1 0 899.006 0 ... == CSide : cutTop == // begin top cut line #0 1150.25 899.006 0 #1 262.77 899.006 0 ... == CSide : cutRight == // begin right cut line #0 3574.36 0 0 #1 3566.15 171.031 0 ... == CSide : cutBottom == // begin bottom cut line #0 0 899.006 0 #1 252.966 805.191 0 ... ===== CPanel : 1 ==== // beginning of panel 1 == CPanelLabel : name == // marker for panel label name 1 == CPanelLabel : height == 5 == CPanelLabel : color == 1 == CPanelLabel : origin == 889.341 2.64113 0 == CPanelLabel : direction == 170.396 0.562482 0 == CSide : left == #0 548.746 0.388633 0 #1 367.439 68.706 0 ... == CSide : top == #0 203.679 871.331 0 #1 393.052 872.078 0 ... Text representation of 3D sail This section describes the structure of the file generated by Sailcut CAD using the menu to TXT sail entry of the Export 3D sail submenu of the File menu. The extension of a text sail file is ".txt". A 3D sail is made of a number of panels, each panel has 4 basic sides : left, top, right, bottom which are joined by a drawing line. Test main sail cross cut (3D) // name of the sail ===== CPanel : 0 ==== // begining of panel 0 == CPanelLabel : name == // marker for panel label name 0 == CPanelLabel : height == // marker for label height 5 == CPanelLabel : color == // marker for label color 1 == CPanelLabel : origin == // marker for label origin coordinates 427.717 764.064 0 // X Y Z coordinates (Z is always =0) == CPanelLabel : direction == // marker for label orientation 168.204 -57.8975 0 == CSide : left == // begin left side of panel #0 92.5718 886.006 0 // X Y Z coordinates of point 0 #1 92.5718 886.006 0 // X Y Z coordinates of point 1 ... == CSide : top == // begin top side #0 92.5718 886.006 0 // X Y Z coordinates of point 0 #1 262.77 886.006 0 ... == CSide : right == // begin right side #0 3533.09 25.5986 0 #1 3526.2 169.113 0 ... == CSide : bottom == // begin bottom side #0 92.5718 886.006 0 #1 259.921 823.943 0 ... ===== CPanel : 1 ==== // beginning of panel 1 == CPanelLabel : name == // marker for panel label name 1 == CPanelLabel : height == 5 == CPanelLabel : color == 1 == CPanelLabel : origin == 889.341 2.64113 0 == CPanelLabel : direction == 170.396 0.562482 0 == CSide : left == #0 548.746 0.388633 0 #1 367.439 68.706 0 ... == CSide : top == #0 203.679 871.331 0 #1 393.052 872.078 0 ... XML representation of a sail This describe the structure of the file generated by Sailcut using the menu to XML sail entry of the Export development or Export 3D sail submenus of the File menu. The extension of an XML sail file is ".sail3d". A sail is made of a number of panels Each panel has 4 basic sides : left, top, right, bottom which are joined by a drawing line. The origin is at the bottom left corner of a rectangle surrounding the panel. These four basic sides define the net area of the panel after assembly in the sail. Around the basic panel there is provision for stiching the panels and sail edge hems, the outer side of the panel is defined by four sides named cutLeft, cutTop, cutRight, cutBottom and the material is cut along these sides. Depending on whether or not you have added material for hems around the sail some of these sides may be identical to the basic sides of the panel. <!DOCTYPE Sailcut > <CSailDoc> // header begin file <CSail name="sail" > // begin sail + name of sail <vector size="10" name="panel" > // indicate that the sail is made of 10 panels <CPanel name="0" > // begin panel 0 <CSide name="left" > // begin of left side of the panel <vector size="7" name="point" > // number of points on left side is 7 <CPoint3d name="0" > // first point = 0 <real value="92.5718" name="x" /> // first point coordinate X <real value="886.006" name="y" /> // first point coordinate Y <real value="0" name="z" /> // coordinate Z is always 0 // for a developped panel </CPoint3d> // end of first point <CPoint3d name="1" > // second point = 1 <real value="92.5718" name="x" /> <real value="886.006" name="y" /> <real value="0" name="z" /> </CPoint3d> // end of second point ... </vector> // end of list of left side points </CSide> // end of left side <CSide name="top" > // begin top side <vector size="21" name="point" > // number of points on top side is 21 <CPoint3d name="0" > // first point = 0 <real value="92.5718" name="x" /> <real value="886.006" name="y" /> <real value="0" name="z" /> </CPoint3d> <CPoint3d name="1" > // second point = 1 <real value="262.77" name="x" /> <real value="886.006" name="y" /> <real value="0" name="z" /> </CPoint3d> ... </vector> // end list of points of top side </CSide> // end top side <CSide name="right" > // begin right side ... </CSide> // end right side <CSide name="bottom" > // begin bottom side ... </CSide> // end bottom side <int value="1" name="hasHems" /> // header indicating that the panel has hems cloth around the edges <CSide name="cutLeft" > // begin left side cut line <vector size="7" name="point" > // left side has 7 points <CPoint3d name="0" > // first point = 0 <real value="0" name="x" /> <real value="899.006" name="y" /> <real value="0" name="z" /> </CPoint3d> // end first point ... </vector> // end list of left side points </CSide> // end left side cut line <CSide name="cutTop" > // begin top cut line ... </CSide> // end top cut line <CSide name="cutRight" > // begin right cut line ... </CSide> // end right cut line <CSide name="cutBottom" > // begin bottom cut line ... </CSide> // end bottom cut line </CPanel> // end of first panel <CPanel name="1" > // begin second panel = 1 <CSide name="left" > // begin left side <vector size="7" name="point" > <CPoint3d name="0" > <real value="548.746" name="x" /> <real value="0.388633" name="y" /> <real value="0" name="z" /> </CPoint3d> ... </vector> </CSide> // end left side ... ... </CSail> // end sail </CSailDoc> // end file Copyright Copyright (C) Robert Lainé & Jeremy Lainé. Sailcut is a Registered Trademark of Robert Lainé. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See for the licence terms and details. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The authors would appreciate that publications on sails designed with Sailcut include some acknowledgement of their work.
sailcut-1.5.0/doc/en/model-sailcut-en.sxw000066400000000000000000001322551477005247400202570ustar00rootroot00000000000000PK[219mimetypeapplication/vnd.sun.xml.writerPK[2un``-Pictures/100000000000018300000214DEE083DF.jpgJFIFPPC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( ( ( ( ( ( ( ( ()ڔ:6}\,,`*Xp=EaoR>ŴI. 2C;ۂs դFK9b^PbG:+ºݾ&bs\G3[=,C$ns"0T0qyՂO3!훈柩jR[vmo0j'B:]ƕ ^غڦpsgIqd?(Q9 ۈQe]RI[n7G P 7w< {/ ^kl%$W *.F9•q:.[^^o g_3|/]uo{_1:q$~nCXpO<6\K0DF dOk>?3isjkzkn HpϜ/}vM;N,`n,eQ r+n nHծMl7ZkqO{vrA18  j7v PH%SG#C eO =[MTKP}B-̦T^9d@;Z/5m7O--}2L ּ~ uK44ۻ2f&KYXR|~VZ^o'w+H$3)NC:?O=ګ>+}X%^u&u2D`w;9,d\*|U14Pnb.@easIA׽5 ˤjz}E䰲 %,˹ܫ #%a%}]_8'n}*KwG%+VHOp@–!s'k's6֑iZ,zM-e&ȮUxa;K++\>ˠN:~=1F)@WqQ|@:K=[M.. Kep̮жHÀr*FSLխ^S.,Ib`&-nFbx8y@(((((((&Mg\6]qo8;aA8qc cW7۶FONro6ڠصe,6 s^wRi|][[ U䶹  giwg$`ʞPg1]JW$@EVZ8fWh[$a9S#U muV25޴ݳQIU;QT**T^$[մ߶ˣNiyH XDʫ m̡+[ӵg\yae2crqT.TӼ>!M>7,f'd' XɈx؎.M>MORXmɉ Hcm,Wp ( j xr;ý+쬒"e`PSPEPEPEPEPEPEPEPEPEPEPEP>] l dtP?3vQQ2kb(((((((((WDӵhae2gkpFq (ny:gJ~3۝{>_XYvrYAwk&7!Zo\C*oHCǏn`Ҹ1"?^# q[LV]Bу缠(((((((((((WA\sa]KKf ( ( ( ( ( ( ( ( 8?垵yv$ʉŸXݎ:|E4Ν g:lO&( ( ( ( &5ha/- F|*aEjQ@߀5GmbV,^T%$l/V#J+|I+7k<<8 & I#abQEQEQEQEQEQEQEQEQEQEs u/-  ; _[5tQEQEQEQEQEQYVkmθw%˲d #ZQX K-Z-:->cͪ+ dC;`J$1CkdiZtQRnѐ\`.@lWWm_T/ jd[[f5x4fNr:m:M"XXBFn Ns<sš7#t$/0 Q9m$d'آ(((((͡x 4[Q8 qdqrEwG׼XY<|bm DoDay: pZn%( lG̛R<APW/ %-?E>m>gxqCxzԧ4Leܪ+#p@Ғ[J5tE4i"D"ppx8ܢ|Qj+c[ַ2YeBT$69#*qP$.xtkuˈ_i mmEVT8 |3?: I:Ke ;5AcR6  k<> GGg+k>WbA<its^^_xWNWĺgmdel Uܱ!p2 nkq~iieDˤ:hޤg'9vW?佒znAiXw 2<%Fԉx^bJ > 37HvWHo-1S6޽qzox/+ O@Z,|szcLvWOk]Xyץ]ſ7D3?2\%iy$?W1<3|xU=9o/5[v>'DW(EV29u4Q\; n<c&UD`pB=N0D!jKŞ,1en+vzdw;S~FI{d5X̱Ƹ`dHI&K;=cYk>éjҲ.ӟAWMG|2t?eѯE?E&h\I/' -^ZKMi&V'c>P~ 5EmKIDlNw+d9 2 0I'kmJ3ÚwAqg$~X)Wt(дhjntPW޳ۤdk噀bC -=[f-/]Í|Hh Q@Q@Q@Q@Q@Q@Q@Q@sa]KKfº]QEQEQEQEQEQE}|-WZf=4^b+J~Xԅʎz\__ÐFHCd:e@6</hUfeiO#cۯAҷ( ( ( ( ( ( *i^ͣP5[9E$yl`;73;J([_ZDBH܌S#X}KR4w P]KgZ `aJ0U'p;((((((((( ; _[5t7@w?Կj(((((((/hڿ|Q9Mp4!5$VJ83=01uh۳E+2H^p\רG𷃴V0ḽ)`[,{u:PQ@Q@Q@Q@Q@Q@Q@??8|OIuk2~&>wO3YxN=z;n4;5U[dBLu O ռW4x䍃+s(((((((((WA\sa]KKf ( ( ( ( ( (8;j1!y6%L7*[#|t6f|yymz-KdIrI(((((((co6Q<3&7#dr2 \;pi2@$i^B@6vl0OcQ;ecHv裐A m wQEQEQEQEQEQEQEQEQEs u/-  ; _[5tQEQEQEQEQEVu𷃵]i0y̭)cR*;u:p~?msF{ ^6NXElx@o FYx-N%r^E@f`1((((((((7`ͼ쵟3mU;=eD~ԴiwH#b>Wzl0r"5(oگk["/1H[$FԻm*[E$wfFJQEQEQEQEQEQEQEQE7@w?Կj+o+lPEPEPEPEPEPm_TׅHjkͲ[[bFI34NpznҸ Z_yGaB7/Ss9n (9=VW*th`"4H1`s\^$񆭨QqX:Rj}fi-0`Cm K(^I䍿5O۞9]OH_IL 39HTe;15K-F(${sklO"EGALpWWn>$O^_a M Ie#[>a(8# aPV#m9bEHc,m.cwC1w8‚N3]7:4o#mFR-Ǯ8qRA+z/$8}g%iʖ4 jsug ċ$je݅@9a|xV_o^%âepRMpW{rTѵ?A}g"Wed;p,6c;W4.Ihm@#` ,I8 @q3izַaio>1$%㉎c9}Ĝ`kb]M5s..;`8\E \ ٿl ۗ>-aAqz5v[,F@UaS߅gJkqq*'c,H%_G!l,M}Zgk_HVM<}2g^ז8'|9q+ K:lK>؟:2i(D9͍X$OMb9cĞ0u|yzfh$nVsc%|ߜml] &2տ'ZyoƟʍŰs|En7/u`YŭM< L1t_o6k=qgKP%e! Wv.N08qnQED֒h{G"߳t7GF>p^3Rx;__;J֕/un/EpÿNnWTm#T/HikŲ\EH,eN0:mPҳj@ӞQi2]ᶒmK0XX=kBUgjlSb/"1Fo| 1n\ dj\=Ė#mp`FᑐFx5r{XXɤZ16c l: 밠(((((U x_Q.|v <'s++ZϠx^X%8\w,Jy\pGXeue[y/oZ{gd/ڥzFOS}M7%QWR٫~0i* (~0i* (~0i* (~0i* (~0i*4'+MQ$vbM!@@<3}3N˵Jnj˄pn`'Ɖj#ob#K0+~Ք'}+o[&_ik%a3[!dٻz ۀc'aAUct?MUC=ZwlE$7)n.ɜs~!iZx:Sqs "ZXI=c&]+A J\$\|IJ]?/88;r=3IԡtkRdX/m㸍d0WP3jx<;tm[^JH57t`TnqpA8=>&9 >&9 >&9 mo>(=gw%s*۠|\T6F]\ILIڊ cqn5??:~^D }d7'H,Gʤ((oN5^_>[s; 11>f!O`pF|=oO o Gnb8W/P̜2w+) #OwYGo&/2|wL&ܜ3vqR|6&y6rI)+)fy.I:(([7G維M>2 3m?zqӎØt4xO z% 98=1ҫ_r^_ik7<4\X2Hqt;Vt|-'E2unqhZY,ҵɦB.,ɑ{3t'[14o5 +.綆yG/,p`ctmMoM:ut1\3h. !/ʷA4p`,Jn-6p@ECA[)٦C6Y!KK$KOQ $A;z\][j3>˘]lNTC@;vB>ʈKb0>a嫌s9OXn%<Y\ P+83WZo?+msc͙wtqO,}}ukԭ-6\cx(?.=Ʊ2w2|[-k[۰鶐X`Y^(>ᧇVŦ.mfK1`pQ,l,8- ;!1.I' 8$ƬQ@Q@Q@[F JcSjrnEiM)$XH܀A{SBçmO !Y]t ( ( (? x~]I仜kgK#AԒy8(V4?># xjo x|{q֩yq%s*Hrv$WI@Q@p~=oMH5[NTcOʷwvk5?hw쵴| cH<sѯ R&^ RhH B,H'h$qA6[0D#5 `*J(WA\sa]KKf ( ( (7ֈ-=/%VLq*$H{n@;OkpsZ?RČʛBͅH׀|6~&ohd'Nsm&<6G$!VfCiXʫ1//Ho4 !us%7AFenJҬt=.L-MD2I$I$#yZA>X?}6_"(QWkuT|!ZhZOE$"Or`Rp^T0>!xj-$r -$cm r%s^YczXtTvylPb߰x,OSֹc]τhB(ASL G<Fe=4,{8b&,(((((((/}?"} ] YV1 ,㜁ס x-h%@WR2#4O7VEJ$E `+Q}q/odo@F0.c*((L2/y.W/Ԑ˜sZ5}:h:kIE@YK6BH[v+s]Y{C,eKd[Y,NI8hB((?Z2xgF̚>hn2ƫo7Hy$j!_k=Q\!_k=ֹ=@sa]KKf? ONGwA| -8Y@'9'$[PAEsQn?ZotW?n?ZoPAEsQn?ZotOVԡѴkRdh,丑cTR 3+//~q.kj;duկeGy` QFGq7(QKbou;i&FޣpOtEsQn?ZotW?n?ZoPAEsQn?ZotW?n?ZoPAEsQn?ZotW?n?ZoPAEsQn?ZotW?n?ZoPAEsQn?ZotW?n?ZoPAEsQn?ZotW?n?ZoPA\]fG!K +\98bbz.!_k=NՆ(U2]Huk&+Tk6 4W?n?ZoPAQ<6\K0DF dOk/~}wUY2 xڔRGq#[i:x}{.[,+q]PEPEPEPEP?WR٫WA@Q@Q@Q@qz+7]Clt-\\u>JNrFյ(tmTY +y.$X,U$ z[?ӮԮ;6p8; ( ( ( ( ( ( ( ( ( ( ( ( i:5p,[ѐ+RFA5rEƧcL<$m7Z5QHKe &;f#dU;rF9((((((WA\sa]KKf ( ( (<M_I B8U"%яv\'\k_u}B)@HѦ d !T`2Ha(((((((((((((}sxWĥ|Rv}uHw|SWEeջ,^c2>hؕž:x;__;J֕/un/EpÿNnQEQEQEQEQEQE7@w?Կj+o+lPEPEPU:O.'gNPKN=*q;<}~;IDqЮ}Tp?x ?T((((((o+lW?WR٫((R :^(KX7L< (VB9/:O.'gNPKN=+gbx. J8[M^f(^s`7L!E= Z|EТVǙ$s&9=3?cdt yylL_:1U3Q@7?H֬odhL3PL^pyx[~{j .<6c8=8YmmN/[CLj-gp/;ګ* |vWD]xsWHIygPsg$85LxĚ}ϯ|:`B .xubA'rR`s9@;+ⷃ-:RKIkIlВ:Sx94wGVǙKfs'hB(((((((kygh#B#؀3©%՞IJC(xFXڷK ݼS+<1sUS>گfyە B*s`WacagYgaiy rI8Q$4Ƿ|sB 6%o;IW-έNX/u jw7+実ZyQ$.큲e,ߘaNP3-Oof?nݻf 8q ЮϕoxA|C쵟f;=QEQEQEQEQEs u/-  ; _[5tQEQEHv $.V)Ryp럼hT8i+ύ7Ā$乹!̑)H# '(((x6Xº0IFpS#tP(vp^wc;!FSq(~O\49s!B.b\dH\gҊ|5Ksa JH^\Ԡxb}2]i(\C,I8sP&CL<^o./엗z;|`s7" C]~,ĭo1t쫞`'3(|YkOGp$xWrFG^A}|RPk?+6!d69`R1vP|<~?[z9ǔS{9zo_W = tp<,:=}MvP~h'Xy>noqg=}MhQEQEQEQEpvtEqoiʰňRI[8,c*d8+b.}J8D=^f/\u]Sӭ-nI}nFdր,QEQEQEQEQE7@w?Կj+o+lPEPU:O.'gNPKN=*p>y{]IB5%y˲6 2rp  ,n"_~Uw6q(cٌJ8$ATpA VG  HB(q ( ( ( ( ( ( ( ( ( ( ( ( ( ( (#n巸9 I]H#WMe94.gӞk(eUmIbxӌW$]Ka+RYkbrX0swQEQEQEQEQEs u/-  ; _[5tQEW i]㬾Lko-ıH^I$`I$?\Kwx۹uGiľRH@U%@QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW!KӼQHg/cȶYe{f.~1bz|ôz_iw "{o%$dC@(?}:@f6\71+`j<#+((((WA\sa]KKf (82Kt,x۸RHII%$tQA6[0D#5 `+ֿXI4H_&? ( ( ( ( ( ( ( ( +Ş/$iu7=q2dԾ-xJX.LO,!#v*zu]+kqſhg$v+#A A5EQEQEQEQEQEQEQEQU%xlq (@*ג:z\_,.t; JJn&M|qGg]U.`!c Q@6b]BxNwK99 (((꺭jzvvY_I8I @~ u/- 17"K;ERiD#q| C@gz_U/v.83V)9׶V5kvؗ_حi]!s*+|u)7ė}#0uB֛•C3 #'ڀ2{+χfV.\h#h_fݜv [6[.IgΛ$3E lfh#c!67ĩn?%-. 1 +"2CIm}Z.GW BnZAXPtO<2EPEP^/ikH~}+G+t7F#u9+] t4'"bϾlAclsOplh '$/;Cc#Z4vw+^SȚLF rHAEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPU,/ZAqJFˑ~z0EQEQEQ\5"|7?W`H6ЅӮ"@ $`gZ|E4-'f_spO27J^YgHM,Iluf9$I ((((((((((((((((((((((("o M/."ʎI -=~,ι&'NBDQ33edr ebAkm>-x{Tt/ i<65r#ܠ/{ xcKA[3r{Y.wamknїmvz8K2Jf1iMe^,hP/*$X!f7IJ\M+l6_°c+D'ctXV.IY^roG{DL"XlqȱĿazN%l!CPfcu%X Ҏ*Z)2{@x|\IGYF+F?9Od8-㕊)>8)oVT6ov\]h&G$VޒQ9ȭg؛?,UR.9:xχ!Ne$Hk:zZ3,{QK',b4stv!w`K]; #9&QhH!kw8&tb*j5*]88Iq1*p -~0$9寽r蒆exdT46Jôn,m =]Z,МLF}Gi)3lϞ޾xC#QuP8)Tvu]qnIq_]) :'nDpߌ M J=$g#+@%+e:CCIC),>pW)$G_:WߨNsU|j"+;3,qrv4) LL:+z 0$`R#G21 ;tm" q멐WDTpi >O^>)2ANLn{]踎HQ`ɮ%]:ST(?~pD"0kAjHHL߽/>;#e*fAJP` TO>hRzW|ԚVT32K)'߅E\!%r<bH,Jqq& W5JҤd'Υ dOTLD`%Nb1hb*&rH&;V '=Ũ䠀o$" y@ *;7Eg=pJq%$fVPv* E4t%)vd :EK&e9 gɅIgLH;!H@1F>`B'Cˤ !`Fg ՠhnMѺ5<}Kn-\Sו\)iۦ&v F ]$ +K/pY#?7uϜI"ҭHѤ@G׏/$\-K&V#si5d~je Yl9˕lhB̥u\.}^MZ]c*JP{Ru&'Yɩv&<)R0*S˨XvYKVpY%˙ &)e! USJ>tcmT{լ+AsH"Q@d4RTzKaBqNZAl sfSTTIPغ%4 HRtZ! :a4\ɡv)eX[ f<ѫuan5iotdtejC"$V xJS {43 q62!p*>y crD4 mi["EDr!EɅ0o$j%0T"dEeXFAyI P]csZu-&+H!$WZLY(5VHqw`mIV#2('Ymc\Z^gyΝ#Lk%CkF؞(yKYͻ%l)!|4[|S(yg2{k?ȡclr Ṣl!a%]YE<9b UĆ#7Y mQ&.Y.JEPqgp2Ν*[23 scmKrw<}<` WVla,P 9}Ԭ$%GجReyT|@&M>= 4RHi{"Vl9O\ E Fv~%Q\  vZS_?챕FNopIcnK$Wy}v+"HժrtN=ʡ*΄ߢ^"D#*n2 T, VO+! mrV[EtIE+-m#WJAywWM9}u_2PjѪ;"s4)kAg)įBz xԟ 2;C;NkŒtTI8HOƞ~`ѷbk S5g[%r6FAH1&Ȋz/#d&`CdT -RvC~DCW8ssC{϶̈́wH GnA߂nc'?x̅z/kYп²B,rHŮuzoȸŌz{ho||O&FK\0 :,t)x9(\*]#khȍ4+ah©֕{q-)(1(wqiT70xZ3]Ü!W#KB*i"|$7R3kӷRU+n;*  #MLIS ۝[ꢭBϝ)}0$-HF_ R6enCrZ -FÑ7.9 :*G6U/ wZc8{Zl.Q1W`4n)goqg\WT|l*;hgswuB^h)5;# N8P#`7kNO[WaT+Ƃ'/ۆ2!@ ,0NgsH[D:$Ud؆M|m{ n vDYȃ cm+ަ1B5 6\r`]""cI?I[5]"}Ն 94y gKa·v|E -_csjJP"AIfO+'l;dHQ<\7^ ؟|#mk}L}3jߍir-. '2ܾYQC{[7ku!˻ٺ1H Ep/ 0Pdf&/TPnzwuu-UNq>HXz<[ƛpٰr>vLҰ6)_C%&s򜶃`Co\ϣS>No4G}i'仳7moZÚK+J%/ʁA"]J{_&YޱW 5{I$ F0}C*GvDvLE._IƵIpI`-ϺA~et${cKƃPKP{epYPK[2 styles.xmlZ[o6~߯4l؀%i,n&MW M&(D e;$E]:5 l/ s?MZaFgh0-L=W~/o/bA@<|3/0N"6!No_X㺷1ku//-2뾽-[·_ir3{)D| x8 (N~a~ܒ!gFa9ZwrKȸXν^]WG(1$V~E54w{%Y-r%SEF&L| .[|.ǣN!$\jQ0@0yuXX7E`-Yl+`!@ 7fuzG 'W=b08A@ +>Qv EօhE5LUܬ"=o6[l v5sl}g*uɚ$.nH!s>Pf(|Yp/؆9V.J6P@c' Y2N>Q`4-V5rc?AwY$MgkGec!6%x+|h,kBD)ZLKwojjD~çh1dh8,]ݮǢ8ď=,眍sjzN*A`rz CSTkYx`u@k @{Rpp\nV"!{ۍ25@oLB,n{[sov*|k4;SPt0KMѹ)FLɴ "?;r Ijg1R_kh*#;%ʞ1 G}^; n58=Iq⵷a2 1CmnLjGKj֟Ӎ 6IނEU9 O{gB}V7a' CNbYk}iUz] ɂʥAYi"H9+3O\ 9j^Ȉ"^ec7)ba*::}r pHȓJI3lNJY/jj}4H@Kل=KcfZX!h:Cu]vpDwWǢGV{f)8U.Ib}'ט7|},frR/nSuUw&{$l홥ٹ~NB_r5xNCtR=9ʟR/^ғ>K^'{IO>Kz4lw[(O4]I#klJE;Z4Tɧu#5SQɣh ~{[y0I6n ۂPsgAMN`Nz85EKS9ht)tcϽ;ore2̓&=870Oa&aU7ϳ( NN;J\ޡ N, ǚF3/[ \}B PevEH}|쉛Ņ׺,,*DX޾f48Rwyw:B yusFLKd5x4h%T8pQ6 _>Fm5 Ƶwj sf;X OpenOffice.org 1.1.4 (Linux)Sails surface formulation in Sailcut2004-02-21T17:18:042005-07-10T23:18:542004-02-29T19:53:36en-GB0PT0SPK[2ObjBFFFD752/content.xml]8B[,I&YMgtf,&2b-?uo($Wl(YDbMd>V4-Wx~գ (OW}׽?͋߾ xEuu-wIA߼{l8Wx=|Q98_=Okzwp002L?_X?OOZ욯O냭mqHI]2?69ߵ{HZRc 0t2kevt}% ס3/:O'c&.\ÌȌxPPϷGc2 f*N俤,\NitcӖF)fN=:P9Dm˷JTmhGڭEs_xNjud$xrׯە<;3[~JQJq9J~Le-T>׮D[=zxzWFyir k!Mxkq|DP7y.|fWv?mo2:.&Hs2GۊZw{Ζ⭽B(eU9i\lOҵ#Yb.*}}]@`_z?m" <"obž`>AFꬤVU_vKQe5🚽% q!{xKd 'fb-v%})AW?^fXN7QyailxY\b@o;v'n3-08$W3˟Nj60alviVmk79 < ^ ~^Q|D4]g3`" & - Y.A^\ '/\3Jy=M~S}B%kӃ4hEzF*o+*uDzǦ^ǬRe.ԃS[ ]c ׂrhlxk ^4['hsJ"S$Fyy; qyOVI*@\Av^bMGpNN4yw]ݚ`O`oh r-~>GvGB8J1 a/G?m~7tYY#Sf8 ;={{KaD^9Cnyuyy#prvμNVj4 ,]*C#t()e _(k:==^j*U@0EͰC/}Ic쫖y?d[CS~ }. -ϫE`h$;Vm+#{"bp=J"Ͻ;2{A{A]0P.LRYp8=ycWDzQu:]w#ċg@A0O q:wk|Q:Ws Fiycz_xI)o; )}5!ߑЅL ;}}bY܃B-˫zc%&a pf8nOf)Ø0ܢ}cVp]b&<->ec^<W0i0Us|_^+/Oq…1q`ڹWm--3^Y`"2bƘ˝]"汦` n W>/y ԅ]d }yyc~<=q&Yc><č1V0kx՜)~c^t*^kC3#nbh|}^%\crKy9֋.|_f+13OhEpoC$QQ/30áe4>ss]u졊MyV5e(@_vЇ<"YK Fo;ԃ/AJ=" (ǔFΖ2PYpis)WE|"A^34yIʷGVa_^$`t0Y>˗҃KXz M F2m)5d,=aYC$(#,/yz.W OϚP!u#+#>M|izTJL`8/@/IJ$="ܱic=E: ^3cCcv/O U$=hF`5V \ '/IJm0q-3[eуG8zLgH8kOŸ~=t7  )1GO4&AtHzЌG3 N>KYzbdѦW-ޗ%x$_iGx21^p܀PZޟYS3妻_EՃfT=kɈT%Qv>Uzk&.T=(QGB6K?iq WzN8Bp%5(֜uoАŗ;~:\UNYEf># ~9d}M)Rsf)E ױQ%.#?( _ #_CF?* ) i*tvD? /yg?q4GY#t5PK?UPK[2ObjBFFFD752/styles.xmlZR6ߧpN&k{iBv&@)lW[2 }IzIdC=J̎oĺ4Gm!;gj?~<9{s[,(G b.u~7YD]R'øe+wEv0[g#eKƲ#%< =sճ;ރx0po ZJ0[" <`5θ/H^VD"CS)(sM/L ^Ϲ"L9\:̟DTL L"]}ύӊ>:r|!Ep b7VKኍ`LXXkg@ւ((U!qnbrF,gz#)HTۉ;8><%XtC=QrkRTK-1y0EZ/,N 1( nt&.@j\drB$g//R8YBq#Pļ b3c]]t:: GWkC cCcLאYo+y>ϽFdNr؏eʙ9Ko|EnM( h[)EA{PWC/ {y>ܐ0$>FZz$&Ϧ &2喋5# 'SRdL#Qdd YgI'O x"H+LG>>bZS G$|i^K,K4NC"vdۍKunjmE:~ZQ?^>(|wE?NEq߂oE~ʞxn;ΗRoeEkE38+6G |Qikvf8w}0-_L6b Aayŵ84A[s>U1iZ7{u(^rpyF[ lwNqjk C\ A$llI8!]ŕ}NiqrRPqϸ@9K\=o%փ\ kԆQGPՀ#!}uu[s,N rkclY꯿^Q^p$Є:ǒaF/0SsSll&Kx4X¾Vbd=Y53p;3yRƏoRHSFtVNYO =YPC(IQ|;lh*nZ$[zԔ3Q23_B^3ݨ[ķւ8ݡax^$o$\ E?&MZ['` nM~Ď;b[|&3c%uz~$L+:?G~)A<)uxc&*سL̂T^IogwE,לZ!k ‘,׻RAʀW>J(]DI]}/GwLMQ9kK+ȏW4MVu]z*g&6k\)g{pqn)_LYJyc~!\ FK'_G.U!ːAZ-)MAn?C `vcbGlx-D2 H;:?ֽ'@5p!h:1@vK)H'4l]/n??yK5)ӭTi7G XfIa;bՕNC7Ģi_/VXX/bw:t)f6<,Kgqb9C dۗ؋y {[R&[vs^o' LON7Vk1%h/P㌄S`/Tȣ+GR1J>79`2hO5=Ѧ۞ P8Fjj~Vh7T쒁1f=j酖ߢ}1fTQRWV]J, V7Ex=d0/g31LF1duxzbj6 x<ٝ.Pm#&[Hvyi0z|‰8Nm#uM@M:+)$-2Ɋ灜~w??{iRdq4)*- .~N^/?N|jfZ>Ϻ^3t25͒&^]XOrl3` P7my~h 돌ݶ'Utwn>ߔwww;ڶJ޼?/Uˇ<+ljfuVg5vopeT_bM>a l?^WlWMi8rڭZAriJ}O N|ZD+ԯM˩pttVYd+ 1Y|L#I$idm{5rx&{Vc`Nʻ"*(ac],2h#YVi 4(wId@MHM;!JW% ^rh;:MFT)Ҹٻ YPJ/^TQUmouUUV*Y12dyy|gm냺8.:C-Q*]Ti4ԌӖuЯ_\23}AG.|J`2;,um[A;ŝ-gn9-;G;sk}0C$!⸣ͬ%Xu?G=9[JQ*Q":[c[f3oy-y/ҏbt-w3o}μ%Mk8n"y[_/o᝗N>͊#:BkPuiX6F|DZ){@?[nٌ'~jƹ®yH_LJ@$pJoLX0۽iII WnlJ !/=S^ De6x'?=y `& @>vIRYm2Y gFA3ʷgL6)_^!mY|VcU~Z( &ohۼwHݨuͶXrJh`3 - ~wQf4M^V㑷yuab8V+(xHuF =^a?]`pY^p qD?\ mtbq]i yAۏsIbI?}7>1J;١}PڻL߻xDH51wLq&KK##^|FfPT\#zY8a9B akDNb!AXrT~3 I ellQykd *,٪SK<t0V!c BOMC1ROJ _D=H ˶TR"QE`ː5l"BƸdH|ؗL(劇}G3L)KmՉ`G|8TTPpd~"8jI,2_^"DaEp\Ku*8#<`!(تFLI%*+q:OPSTI g|B1.T*:L#٘^lPV} Ϋ6;z 6K ,TEDsp9BFX˙D{vG)+_˛eYg|9Pד"\NNg`mE 8q;I>OHmk"gXsQƣC^mNbR7=q`3ZNODl$WC=o =K |7PKYLPK[2 settings.xmlXYs8~_usJ<8O|$~c"#qTZjue@J#E?єPa.nɸUT~Tѯ{~]̍R6* &NUgr'/T1nύk%HU=OJ \%7'DxLa14MS%˻|$'i&f[Qg E ڷK^7e_@(;y!yߥ?R,T3b jZuxuB;yc6S8[u9n{,^uD;  T [@ 8K" ij1&ԡ8to/(,G8;Dkn;KOSMc_\G=@VsFCȀ xt(ӳQ5& C73%ԮyKVNA[յr G@=:Mo~L_K뇘#!ɵI?C~•9r 9F %`d3 1xeN߀Yrb۽:-MO9E$uZ\$!(ɶ1@!T ""=6 QYlK?/X> 1@CGCq+X:HQ{P畚O_)U{qjL0[P'o!qo{ϗeoxPtfY]e󠪗5lyb?j'ZimfgckoQ9']8OP·wz?ffӷy=iOJ`$nġC[Ouc,_`$0bqGߜԘyIm8jnaQD|N &Ni@paiW>6a"ۏi-;=pjE>"ΎtBdl XV9J+ef1w?8S̓궥0bώZVEfKA= ޽rc@-d-( 8BىUش9 =-0,BXUlQH$Q$c rٛ /ЊŻgi44Op/u_iՐ,{>㈣QŘF=Z͓vO_PKHkPK[2META-INF/manifest.xmlo0+X@Dd6=aZXӍ~2t PH}5M=̔f*R.[-s&ѵ7-r%#,iXjp?3 0QͣH "Xle2 ԛRק6D ٶ$ 2H&h:1T2aB)KKB(%sڸ rȔӼ+>zAsn<߷}/y`lIѪi|«lGb- :"SgܒˋcS$z6_oAxw=fvXD>?ק'Y|k^/dž*cGTƆl~+ PKR6wPK[219mimetypePK[2un``-DPictures/100000000000018300000214DEE083DF.jpgPK[27yG `layout-cachePK[2P{epY ?acontent.xmlPK[2 l( vstyles.xmlPK[2 ~meta.xmlPK[2?U=ObjBFFFD752/content.xmlPK[21%lObjBFFFD752/styles.xmlPK[2ObjBFFFD752/settings.xmlPK[2pg 9auObjBFFFD753/content.xmlPK[2YL[ObjBFFFD753/styles.xmlPK[2Hk settings.xmlPK[2R6wMETA-INF/manifest.xmlPK GPsailcut-1.5.0/doc/en/rigplan.fig000066400000000000000000000134371477005247400164750ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 1 3 0 1 1 7 50 -1 -1 0.000 1 0.0000 8145 8145 45 45 8145 8145 8190 8145 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2655 5490 1890 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1710 7650 1710 8865 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1800 5445 1395 5445 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1890 4095 1080 4095 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2070 2745 765 2745 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 540 1350 540 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 855 2745 855 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 1170 4095 1170 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 1485 5445 1485 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 180 7650 3600 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 3690 765 2835 765 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2655 7650 2655 8100 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2835 7650 2835 8100 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 2652 765 2835 765 2835 7650 2652 7650 2652 765 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 6 2655 1350 2070 2745 1890 4050 1800 5400 1710 7650 1710 7605 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 3555 765 3555 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 1710 8775 2745 8775 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 1890 8370 2745 8370 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2430 8055 2655 8055 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 2835 8055 3285 8055 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1890 7650 1890 8460 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1440 4905 1800 5445 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2395 4898 2755 5438 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 1485 4995 2430 4995 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1720 2198 2080 2738 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 1620 3645 2430 3645 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 1800 2295 2430 2295 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2371 2184 2731 2724 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2395 3548 2755 4088 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1540 3548 1900 4088 2 1 3 1 1 7 50 -1 -1 10.000 0 0 -1 0 0 2 2745 9000 2745 405 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2655 1350 495 1350 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 2070 2745 2655 2745 2655 2790 2070 2790 2070 2745 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 1890 4095 2655 4095 2655 4140 1890 4140 1890 4095 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 1800 5445 2655 5445 2655 5490 1800 5490 1800 5445 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 4545 7650 8010 1125 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 8010 1170 8010 8775 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 4545 7650 4545 8910 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 7650 7650 7650 8370 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 8145 7650 8145 8370 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 8505 765 8505 8235 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 8010 8685 4545 8685 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 7650 8145 8145 8145 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 8145 8145 8505 8145 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 7650 8145 7020 8145 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 8505 8145 9045 8145 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 7650 8325 4545 8325 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 7155 5670 7740 6030 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 4140 7650 10710 7650 2 3 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 6 8013 765 8508 765 8148 7650 7653 7650 8013 900 8013 765 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 8010 1170 4275 1170 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 4455 1170 4455 7650 2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 0 0 2 8415 2070 9180 2070 2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 9045 2070 9045 7650 2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 9585 6525 9585 7650 2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 0 0 2 8235 6525 9720 6525 2 1 0 2 18 7 50 -1 -1 0.000 0 0 -1 0 0 4 8415 2070 10035 495 11655 6165 8235 6525 4 0 1 50 -1 0 12 1.5708 4 180 1455 3510 4905 mast height = MH\001 4 0 1 50 -1 0 12 1.5708 4 180 2070 810 5535 Spreader 3 height = SPH3\001 4 0 0 50 -1 0 12 0.0000 4 135 405 6705 5670 Mast\001 4 0 4 50 -1 0 12 1.5708 4 180 1695 4365 5040 fore triangle hoist = I\001 4 0 1 50 -1 0 12 0.0000 4 135 1290 5220 8235 mast base = MB\001 4 0 4 50 -1 0 12 0.0000 4 180 1665 5220 8640 fore triangle base = J\001 4 0 1 50 -1 0 12 0.0000 4 135 315 7110 8055 MC\001 4 0 1 50 -1 0 12 0.0000 4 135 360 3015 7965 MW\001 4 0 1 50 -1 0 12 0.0000 4 135 360 2160 8325 LSB\001 4 0 1 50 -1 0 12 0.0000 4 135 375 2025 8730 CSB\001 4 0 1 50 -1 0 12 0.0000 4 135 495 1755 3555 SPW2\001 4 0 1 50 -1 0 12 0.0000 4 135 495 1755 2205 SPW3\001 4 0 1 50 -1 0 12 0.0000 4 135 495 1710 4950 SPW1\001 4 0 1 50 -1 0 12 1.5708 4 180 2070 495 4500 Cap shroud height = CSH\001 4 0 1 50 -1 0 12 1.5708 4 180 1650 1440 7380 Spreader 1 h = SPH1\001 4 0 1 50 -1 0 12 1.5708 4 180 2070 1125 6615 Spreader 2 height = SPH2\001 4 0 1 50 -1 0 12 0.0000 4 135 1305 8640 8055 Mast rake = MR\001 4 0 18 50 -1 0 12 0.0000 4 180 1635 9090 4455 Head height = HAD \001 4 0 18 50 -1 0 14 0.0000 4 165 810 9450 3285 Mainsail\001 4 0 18 50 -1 0 12 0.0000 4 180 1575 9630 7065 Tack height = BAD\001 sailcut-1.5.0/doc/en/sail_edges.fig000066400000000000000000000105401477005247400171300ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha4 Landscape Center Metric A4 100.00 Single -2 1200 2 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 4815 1935 4185 1710 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 7065 405 7965 630 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 8730 7155 9225 7695 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 3 1 1.00 60.00 120.00 4005 7875 4140 7290 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 3060 7290 2970 7920 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 3 1 1.00 60.00 120.00 315 7965 270 7335 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 2835 1890 2160 1665 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 270 7245 2970 1935 3060 7155 270 7245 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 945 4455 1530 4725 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 1755 4860 1980 4950 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 1620 6705 1620 7200 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 1620 7380 1620 7785 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 3960 3960 4410 4050 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 4590 4095 5355 4230 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 6300 6750 6300 7155 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 6300 7425 6300 7830 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 5445 630 5760 990 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 5895 1170 6165 1485 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 4950 4185 4484 7243 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 8685 7065 9315 6885 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 8015 3301 8600 3121 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 7251 3531 7701 3396 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 8271 3242 9216 6887 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 2520 4590 2835 4590 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 4905 2025 5130 2295 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 5106 2230 6096 1375 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 4135 7199 4912 1989 6874 366 8674 7071 4135 7199 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 3015 4590 3735 4590 3 2 0 2 1 7 50 -1 -1 0.000 0 0 0 3 4909 1981 4365 4050 4140 7200 0.000 -1.000 0.000 3 2 0 2 1 7 50 -1 -1 0.000 0 0 0 3 4905 1980 5760 990 6885 360 0.000 -1.000 0.000 3 2 0 2 1 7 50 -1 -1 0.000 0 0 0 3 4140 7200 6300 7425 8685 7065 0.000 -1.000 0.000 3 2 0 2 4 7 50 -1 -1 0.000 0 0 0 3 270 7245 1665 7380 3060 7155 0.000 -1.000 0.000 3 2 0 2 4 7 50 -1 -1 0.000 0 0 0 3 2970 1935 2835 4590 3060 7155 0.000 -1.000 0.000 3 2 0 2 1 7 50 -1 -1 0.000 0 0 0 3 6885 360 8010 3285 8685 7065 0.000 -1.000 0.000 3 2 0 2 4 7 50 -1 -1 0.000 0 0 0 3 2970 1935 1800 4725 270 7245 0.000 -1.000 0.000 4 0 4 50 -1 0 18 0.0000 4 210 360 2025 5445 Jib\001 4 0 0 50 -1 0 14 0.0000 4 225 1845 4770 5850 Luff round position\001 4 0 4 50 -1 0 12 0.0000 4 195 1320 405 4365 (negative value)\001 4 0 4 50 -1 0 14 0.0000 4 180 1035 585 4185 Luff round\001 4 0 4 50 -1 0 12 0.0000 4 195 1320 3060 4770 (negative value)\001 4 0 0 50 -1 0 14 0.0000 4 225 2010 8730 4680 Leech round position\001 4 0 0 50 -1 0 14 0.0000 4 165 465 8100 720 Peak\001 4 0 1 50 -1 0 18 0.0000 4 240 1155 5625 3195 Main sail\001 4 0 0 50 -1 0 14 0.0000 4 225 1860 5445 2070 Gaff round position\001 4 0 1 50 -1 0 14 0.0000 4 240 2715 8325 3060 Leech round (positive value)\001 4 0 1 50 -1 0 14 0.0000 4 180 1050 6435 7785 Foot round\001 4 0 1 50 -1 0 12 0.0000 4 195 1275 6300 8010 (positive value)\001 4 0 0 50 -1 0 14 0.0000 4 195 510 9135 7920 Clew\001 4 0 0 50 -1 0 14 0.0000 4 165 510 3690 1710 Head\001 4 0 0 50 -1 0 14 0.0000 4 165 480 4005 8100 Tack\001 4 0 1 50 -1 0 14 0.0000 4 240 2550 4815 4050 Luff round (positive value)\001 4 0 1 50 -1 0 14 0.0000 4 180 1050 4365 540 Gaff round\001 4 0 1 50 -1 0 12 0.0000 4 195 1275 4095 765 (positive value)\001 4 0 4 50 -1 0 14 0.0000 4 180 1200 3060 4500 Leech round\001 4 0 4 50 -1 0 14 0.0000 4 180 1050 1260 8010 Foot round\001 4 0 0 50 -1 0 14 0.0000 4 165 480 180 8190 Tack\001 4 0 0 50 -1 0 14 0.0000 4 195 510 2745 8235 Clew\001 4 0 0 50 -1 0 14 0.0000 4 165 510 1575 1665 Head\001 sailcut-1.5.0/doc/en/sail_seams.fig000066400000000000000000000120541477005247400171530ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 5120.579 -4210.354 2655 3015 5985 3375 8460 2655 0 0 2.00 60.00 120.00 5 1 0 1 0 7 50 -1 -1 0.000 0 0 1 0 3867.387 6515.855 1755 2700 3645 2160 5715 2565 0 0 2.00 60.00 120.00 5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 4720.387 5318.285 1260 5490 1755 7110 2655 8100 0 0 2.00 60.00 120.00 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 5 485 5869 1101 1770 2112 530 3880 5869 464 5871 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1016 5869 3597 4985 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1051 2086 2289 5869 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1581 1202 3077 5866 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 591 5197 3348 4239 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 6 5752 1148 5292 1700 5246 2068 6488 5886 7270 5886 5752 1148 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 6 5715 1035 5175 1665 5130 2025 6435 5985 7290 5985 5715 1035 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5 8370 315 7650 1215 9180 5940 10215 5940 8370 315 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 5 8300 534 7760 1209 9245 5844 10055 5844 8300 534 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 6 4770 7110 1845 8100 1755 8820 2205 8820 5040 7875 4770 7110 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 6 4635 7200 1890 8145 1800 8775 2340 8775 4905 7920 4635 7200 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 9495 3690 9720 3600 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 9138 3833 9363 3743 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 8547 3637 8772 3547 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8232 3772 8457 3682 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 5898 4058 6123 3968 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 5583 4193 5808 4103 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 4542 7642 4767 7552 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 4893 7484 5118 7394 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 2070 8775 2070 8550 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2070 9045 2070 8820 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 6840 5895 6840 5670 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 9675 5850 9675 5625 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 8055 855 8235 1035 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 7785 585 7965 765 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 5310 1125 5490 1305 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 5580 1395 5760 1575 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 5266 1883 5536 1928 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 4906 1838 5176 1883 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 3150 7335 3240 7605 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 3285 7695 3375 7965 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 1887 8347 2247 8392 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 1438 8297 1798 8342 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 6840 6210 6840 5985 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 9675 6165 9675 5940 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 9675 2205 8955 2520 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 9627 1523 8907 1838 4 0 0 50 -1 0 14 0.0000 4 150 435 1800 6165 Foot\001 4 0 0 50 -1 0 14 0.0000 4 150 435 1170 1035 Gaff\001 4 0 0 50 -1 0 14 0.0000 4 150 585 2745 2070 Leech\001 4 0 0 50 -1 0 14 0.0000 4 165 975 5220 7380 leech hem\001 4 0 0 50 -1 0 14 0.0000 4 150 960 4545 1035 other hem\001 4 0 0 50 -1 0 14 0.0000 4 150 960 720 8145 other hem\001 4 0 0 50 -1 0 17 0.0000 4 195 150 2745 8235 1\001 4 0 0 50 -1 0 16 0.0000 4 195 135 1665 2970 2\001 4 0 0 50 -1 0 16 0.0000 4 195 135 2430 2925 3\001 4 0 0 50 -1 0 17 0.0000 4 195 150 8505 2565 3\001 4 0 0 50 -1 0 14 0.0000 4 165 975 9765 3510 leech hem\001 4 0 1 50 -1 0 14 0.0000 4 210 1500 9765 2205 draw line (blue)\001 4 0 4 50 -1 0 14 0.0000 4 210 1200 9720 1485 cut line (red)\001 4 0 0 50 -1 0 16 0.0000 4 195 1950 8415 8595 Draw line in blue \001 4 0 0 50 -1 0 16 0.0000 4 195 1590 8415 8910 Cut line in red\001 4 0 0 69 -1 0 16 0.0000 4 195 135 1305 5355 1\001 4 0 0 50 -1 0 17 0.0000 4 195 150 5805 2700 2\001 4 0 0 50 -1 0 17 0.0000 4 270 1860 3825 8685 Cross cut layout\001 4 0 0 50 -1 0 14 0.0000 4 150 420 405 3240 Luff\001 4 0 0 50 -1 0 14 0.0000 4 150 1095 4590 4050 seam width\001 4 0 0 50 -1 0 14 0.0000 4 150 1095 7245 3645 seam width\001 4 0 0 50 -1 0 14 0.0000 4 150 960 4095 1755 other hem\001 4 0 0 50 -1 0 14 0.0000 4 150 960 6750 585 other hem\001 4 0 0 50 -1 0 17 0.0000 4 270 2100 7695 6840 Vertical cut layout\001 4 0 0 50 -1 0 14 0.0000 4 150 1095 2565 7290 seam width\001 4 0 0 50 -1 0 14 0.0000 4 150 855 2205 9135 foot hem\001 4 0 0 50 -1 0 14 0.0000 4 150 855 6930 6300 foot hem\001 4 0 0 50 -1 0 14 0.0000 4 150 855 9765 6255 foot hem\001 sailcut-1.5.0/doc/en/sailcut-profile-en.sxc000066400000000000000000000311741477005247400205710ustar00rootroot00000000000000PK$3Emimetypeapplication/vnd.sun.xml.calcPK$3 content.xml]r9r?OR,C|e˻I꼷WkjD$fIkHZwț%O 9p8ݪHэ7?}N:x1f]GN8Fo{W~M'óQ4\Mٲ7fKoE f( ~xI߿] GQ˪A,=, aaBh?X~n4__;[Y򞾓849ߴַ[ZF4d2~lnV0-I yY|y:37A{w3BGm7 wPݻ鋧;;7 2x[IwIXw8 F0R+p(N^&s}WIς)xLps xu]>:/0E1~7r駝 c0.O G E4:@fq:O/yՇԮǭvVlRk绌&#ݫ@twв ۏ@@n6I nb2^ZB_]5;͙c覿9n< K`VoqtCC) m9%)Z{g sakwZ)ifuf%!@`<$|9X"*nbŝD:a>U[~D8)D$Nc׶*ktt7mZ9En:fsV"}&nVݔmk&+gם3谇NdN 5`rYM9~oȧ2 < ?ek0g`sI_ih04x,1 d sا83kqX8 ?7۞~Zg̍UHwxJ*W?wGRWK.dɫ\0)>ghk>> p N2A<a N>ml= n B^|t[kr2نÉkcGcL> cN>6'<9E}U9XÞIb]tmyornҩ#ҡ;W@ ׼7;nq>յqpT,-9ɳ^J+l^2)N6h8=q 6E5Xa{Q uӟɋLW5g*o-#F' F'IN;E5h)IKYh] l lrxsf61LG>dtRT:r #N~>hd"9i1!0s?ńM>6I?l) 3$K!vg0%K0%=`&\p'@`Kf%`K32D1 O+lἅqqB-eܣ}j6`QAUDQX|JJ`T)Pݞ !`Jy#$%S,+]S Cj#XInRu+]XX+܎H3bi_%>"Q5Z{/Tt[+aJ!1DXjp=fҮe|Ae*̏ڇP.^%+hWb*Z,F6PAPi8fܚ xBkJlP ÚlOO&2vD(+rj5Q D>DL"ֱ> *T ”%} uv,\,Xjb1 m>\Bnp {-l BBb;n;v-0m?"UE` E6bAaˈE#A,C$HPG8TvF+VV4gܞ |{AsT 0Qať"H89,ZTiJ0&*ZXP2\pE}J( )C-Z-ZR9Bj(H*fE=x.K!A0A>J1tn[G.V\i)s;a.*1,Y!-udt"bXJXżRȏ;YR 8eR"(8kqqs)"WwZ بGAMXc*B1&HSiCy敭 ddqA)Ts!^ugŽrL`DL qw- xUQ۫B~-#V};bĢ裔⇠^_6;)ى`3H 2b;!͙!HfDXvnCUV0 1L 7aq«vl72(Djsfg+ wvR/ndq9X(}%`yT!Wm'>vcI Av QOh?ƪ"spX@9R%d/n{T U888*_n;)qۉ]@yቤN|.B+ ?i.Lӹ!t *n;qᶃΒhA AvZ`/vmO 2 )f?DRn'%v;bs%dH 8XPu8ćn\I`Yݧ`9ۥC`*~;uyصZ@9RhwEp7%0$‚iNHI Ahԇn<M?eMćGUԙnYe*;u!'_Jj ݩ=,|O( 3LwZbS/;#\aDidq0KteLwt7,(HPN WgEeUqݩ 8\Yԗꎅ`XNt'XiNQ Pv8hԇnTbE8BsL+xy:ݕ}~UEtnDw"B>ѝݱP aNϝz 7O#f[&xUЕܩDWp*0҅cF^8˙n?.~UEtnDwĉV7jgSoİ;+]<ƒ¯xu%;c )Tb~ ԏn7DAqF3][FGYUtwFwG+A%(-Gi};J)!Qzc,_;-ݩ) A2AMgxS%'2~9ëSŦ"]rM&=`Ѧ(.W y7Q$;WYib;pMɐdfy_WMS` [q#2eڢXo9* 82}{7i8ىfKPKA PK$3 styles.xmlYn6ԡhʒڴ؀ rDD%R 8=ϞjOCR%,NvmB<;GM:ט 4d̽|~<򏳷cÈEMpή^q=cQF'ryrf|qQ$#w~ԣ<gRXak+ |AFX7r- 8Z Uj5Zix:_PMJ^Z(-Þ K!r9\">̟Fً0Y0 B> *W*|sqm7NKU1p&pg29Aubf1Hz[NmkNdq_#b&RHQQLc޶Lj s\ *:B4_aww-Y&3Izkff t"+J bΕݞq#L1'+"eC㈔K ""-UZz4u-NYUk(ӒdQ.ة'ٹgcswg}7*NHNgzqlޫnub.Mj߿v@V5v["QJQs59i&)!r=P&^>d-^7ZmHyp$C[W$`Wc^LnZCrHn|Ae;p*bΤU*; 壚3zV5zk#<5ߔ{r.%y,F/O@X 7WLBXJdD̘ZUI|IQl0sKI< Qdd|`𓺨id0P+j<-ŷ{{H)0R.*MCwz͒n=&e#|XJg;"`T4>I2Y~B)fZ ~m̞Ab'-bˋ'ZQK''LCRcI 0ޑ IΉܟVwNӹ4k_wsPKBC"PK$3Object 6/content.xml]m۶_~Ȅ_ܻ$qc'ڞi?H5%jHΗ_A;LjVn `ų.@brUu^.xliZ\N߽}WW󋟾}77y=OdVM~O~~ͫLum6+|틉5;w?N'S;,mša^Nof|>/L9!>:Cq}ۢodMm#c-imm7잶-z7/joWo}fyUg7nop픓۸:~#4bo,P_xjp_<:i]_R3M="iN)ay>.t;a*^~oe^<\N͎؆SWQ|70;<_]X{0OD%2.u'LN?qz[nAe]UMO0DUrhnE7yQ%_nڟv"#&@6crZEjo:)w_Wy\l- h*O`I FbO?hSW3U -Aqǀ׫4WV~f}+xCo(z6>CzonC&߸W$O㮧m7xBzwQ ޾㜜u}Z{_NjўI>fm{5rx&{VchNUtW7qQbc82 ƅOl Bj`e V.a;3d@1Y: *K uLE^UtYUUE⢼,e6A] CωcJڊ٨[-6uksB_gEԶri'`^'RVMaȇ\x_U9lvF1ƨ+cs4E% a X⪊W̔ː>Dy Y!+@j[M5uSeD)Pt}k&9L9mH[TvO D0c)bCUfEt!i⦸3-ǹew<~~f!Dt4cD R*ݯw~nn·&<3G}~zdQsTE>[c[v3oy[[Gd!x<1ܙμ-}#o4iJ!μ-'Yq]LcMjq}m/n|b>k"ٝ;>L.Ξͤd=aK3Zz7E||x^aވ K:WD 3e fV.&,X$8MM¸ͲϞ} g/QP}>ƵХ*1̸]V\VT-YjЌrݍgj5aC^3d?u=ƶ.6,6 )@ y̹f1,~!#L`>XCXB3͙,A,qD 3Ω&#'볁EY8a9BakӄDNf!AXTa3 ) ellS6kd %5b\թ`$#:kq0fSa|4X*Ũr@EH(CR8^vUQj#XIXfqŐ|WL(A{@aJ!_",uN;~RSA¡jȊqh@S3XeDaMp\Gu*8#<`q$v2OfBQ)kI\.4 hB1!ĹPE l0Kn: E.za)Tacq(yf`Vať"3cթu<76K0&Bz;hBL( ) @Bu $ ^uUv9)T sF3LsYi 0J!7#N+FgJ{zSA*Q 𢽞rcфrVE t֔pTsā43O az|5]('fiK`0ب)Iv 1CI= P&PZ9T 4v38G eIF1i. $CPkDr鲲P!f`vT schA An5i)L03Wn\I ܣy`" y&`^ѱN rSH] 4$1K6K ,TEDsp9BFX˙D{vG)+_˛eYg|9Pד"\NNg`mE 8q;I>OHmk"gXsQƣC^mNbR7=q`3ZNODl$WC=o =K |7PKYLPK$3/ċmeta.xml OpenOffice.org 1.1.4 (Linux)2004-02-29T17:21:282005-09-04T22:31:592004-02-29T19:50:47en-US15PT6H26M29SPK$3 settings.xml[w:ϯzE:Bjm[T2 + D{Z*E|8ڧ$I%4#J~*գRġ."ӟ(ݺ1ADO]>$̡r,/ F˾QRʪz@rwDTU[V[i%)HUJIIGpY&]jIiSNUJ9?9ZRQ0Lj<=(:^uuջPﰫj2D՞uߨ8Ke$L/W2C0z^mcđ hl:"Q9SB>0; ozR;߃hmU]Tw}qiY0ھK9IJ.è#44)=- -򑢯 =EuhS6 yYo'_-GZR"+´=8 ~c"KfpE7f'n-omfSٓ[PTKgս:ne8}1F1 1P[S蕎c45rLa@ޥr‡bMi ƩKoS! J`@FW,{8P:@ŔИWՎ5$g}JpzF=\5DʑHOsz߄B pmB!B50Eܬ`L~gfܞ8HCE33/]G'sć x9Ql`]-m ݊2og⯘ŌKDF .W8 Gt8H jXYu\FF N^pyyC 8}k"Bi#G:-gݡw~ۤ?:zg2>Я#۩< A pwR־]D~{7ٮ;ŃVx9vQ#ïzoznmr[2貥+=mkR~E^ݱ6/]X[-JL ۦvnLG5;Bo+#9m턓ng1 y/FݡF }/knX c0)`t]SՏ7dvB7wЮ70QX_@Ft.m=#B)w&0b`$9lQ߂~^ChrNmb Uᦾ]S/PKmp}vNPK$3META-INF/manifest.xmlj0 { ODc (X-σ%e7H/GCaĞjK8 LM )x&]$}:'Ǔ6\@Td<׊² .҅xm<qڧ0 >IeG'p/'n+kGtU b97:c"!? PKLʒ!qPK$3EmimetypePK$3A  Bcontent.xmlPK$3BC" Vstyles.xmlPK$3/wv
Manual de Usuario del Sailcut CAD RobertLainé JeremyLainé JoanGelpiTranslation Sailcut CAD 1.5.0 - 23 de marzo de 2025 Introducción Sobre el Sailcut CAD Sailcut es un software para el diseño de velas desarrollado para paños planos. El Sailcut se puede usar tanto para velas de cuatro lados tipo cangreja como para mayores y foques Marconi de tres lados. La primera versión del Sailcut fue desarrollada en 1978 y usada por Robert Lainé para fabricar las velas de su barco "Flying Sheep III", un ¼ Ton IOR. Sailcut ha estado disponible en la web desde 1994 y es utilizado por muchos fabricantes de velas, tanto amateurs como profesionales, para cruceros, regatas y recientemente para barcos de radiocontrol. Sailcut se basa en una única definición matemática para la superfície vélica que asegura un perfil aerodinámico y uniforme. ¿Cómo obtener el Sailcut CAD? Se puede descargar la última versión del Sailcut CAD desde la página principal en . También está disponible en binario (compilado) y en código fuente. Información técnica sobre el programa Sailcut CAD se ha escrito con la intención que sea transportable. El programa fuente es el C++ utilizando la librería Qt de Trolltech para los gráficos y el OpenGL para la visualización en 3D de las velas. Sailcut CAD se puede compilar y funcionar bajo GNU/Linux, Microsoft Windows y MacOSX. Usando el Sailcut CAD Últimas notas Al igual que la versión 0.6.5, el Sailcut CAD usa diferentes extensiones para cada tipo de archivo instalado en lugar de los finales con extensión ".xml". Si deseamos abrir nuestras velas creadas con la versión anterior del Sailcut CAD debemos renombrar el archivo de definición de vela así como las extensiones con ".saildef". Al abrir el archivo resultante, todos los archivos se conservarán excepto los datos para el molde. Preferencias de usuario Preferencias de archivo Las preferencias se almacenan en un archivo llamado .sailcutrc. Bajo UNIX este archivo se localiza en el directorio raíz y en Windows está en Documents and Settings\USUARIO. Internacionalización Como en la versión 0.5.5, el Sailcut CAD tiene soporte para la internacionalización. Al arrancar el programa, podemos seleccionar el idioma que nos interese en el menu Ver->Idioma. Crear una vela Cuando iniciamos Sailcut CAD, se presenta una vela por defecto y en la parte superior de la ventana encontraremos menús desplegables. El menú ARCHIVO se usa para cargar una vela existente, GUARDAR los parámetros de la vela y EXPORTAR los paneles desarrollados. Se puede modificar las dimensiones de la vela utilizando el menú Ver->Dimensiones. Con el menú Ver->Molde podremos modificar el perfil de la vela. Y en el menú Ver->Aparejo visualizaremos varias velas con diferentes aparejos. Pantalla Dimensiones (menú Ver->Dimensiones) El programa permite diseñar tanto una vela triangular como cuadrangular. La clásica vela Marconi se diseña esencialmente igual que una Cangreja pero con un pequeño puño de driza. La superficie de la vela se genera desde unas sencillas ecuaciones que definen el perfil en todas las alturas. Dichos perfiles se basan en los extremos de las velas que han sido definidos por la longitud y alunamiento en cada lado y por el twist de la vela. En la ventana "Dimensión" hallaremos los parámetros que definen la vela. Al pulsar el botón "Calcular" el programa evalúa y visualiza los datos auxiliares. Estos datos aparecen en pestañas de color y que pueden modificarse. Si el color es rojo, significa que el valor excede del límite superior; si es amarillo indica que está por debajo del límite aceptable y debe cambiarse. Una vez finalizada la entrada de datos de dimensiones, pulsamos OK para visualizar la vela en formato 3D. Pestaña "Geometría del Aparejo" El primer paso es seleccionar el tipo de vela con la que vamos a trabajar y entrar los datos que definen la geometría del aparejo y el plano vélico (ver la Figura 1.) Seleccionar el tipo de vela marcando bulón deseado: FOQUE para cualquier vela de proa, MAYOR para cualquier vela envergada en el mástil, ALA para cualquier tipo de cometa simétrica. The rig data are used for displaying the sails in their proper relative position with the "rig viewer".
Sailcut plan definition
Pestaña "Dimensiones de la vela" Aquí es donde se introducen las dimensiones de la vela. En una vela mayor, el valor mínimo para la longitud de la percha (galleta del puño de driza) es de 5mm. Cualquier valor inferior dará siempre por defecto 5mm. El ángulo de percha viene definido como el ángulo entre el mástil y la baluma que puede ser hasta 90 grados. El alunamiento del pujamen, la baluma y la percha extiende la vela más allá de su línea recta. El alunamiento negativo equivaldrá a un hueco en la parte exterior de la vela. La posición del alunamiento se expresa en porcentaje en el correspondiente lado de la vela calculado desde la parte más baja o más externa del lado.
Sailcut edges definition
Dimensions and angles defining the sail plan are expressed in millimetre and degrees. Length of the sail sides and diagonal are the 3D straight line distance between the corners of the sail. The actual length on the finished sail lais on the floor can be slightly longer depending on the shape of the sail. For example, the foot length entered in the screen below is 3600 mm. If the foot camber is null then that will be the actual distance between clew and tack (straight foot) of the finished sail. If a 10% camber is entered for the foot depth, then the actual foot will be the length of the arc which has 10% camber, that is 2.7% longer than the straight line foot length. Having entered the sail main dimensions you can press on the "Compute" button to obtain additional informations on the sail, like the X-Y coordinates of the corners of the sail, the perpendicular length LP measured from the clew to the luff as well as IRC racing rules width. The X-Y coordinates of the sail corners are usefull to quickly adjust the data entered. For example if you find that the clew height (Y) is way below or above the height of the tack when you would like it to be leveled, then you can substract or add the difference to the leech length.
"Layout" box Click on the radio button corresponding to the desired layout of the sail. The layout of the panels does not affect the shape of the sail which is defined by its dimensions and its mould. Except for the Radial cut layout, the number of panels is determined by the cloth width and seam width entered in the "Cloth" box. The most commonly used layout is the "Crosscut". The panels are laid perpendicular to the straight line joining the peak to the clew of the sail. The "Twist foot" layout is similar to the cross cut except that the lower panels are rotated such that they do not intersect the foot of the sail. The "Horizontal cut" layout lay the seams in the horizontal plane. This option can be used to visualise the profile of the sail at various levels and to output files with the 3D coordinates of the sails for use by CFD tools. The "Vertical cut" layout places the panels parrallel to the straight line joining the peak to the clew of the sail. This is the favorite layout for the old timer's main sail. The "Mitre cut" layout is the favorite for the old timer's genoa. The sail is divided in two parts by a line joining the clew to the mid point on the luff and the panels organised to be perpendicular to the foot in the lower part of the sail and perpendicular to the leech in its upper part. The "Radial cut" is used mostly for competition as the cloth is mostly aligned with the directions of maximum strain. When using the Radial cut option it is important to understand the definition of the number of sections, number of radial gores and number of luff gores (see figure below).
Radial cut gores definition
"Sail shape" box You enter there the depth of the sail at 3 levels, near the foot, in the middle of the sail(the exact position being defined in the mould screen) and near the top of the sail. The twist angle is the angle expressed in degrees by which the top of the sail is rotated with respect to the foot. The twist is globally determined by the amount by which the apparent wind at the top of the mast is rotated with respect to the apparent wind at deck level. For a jib the twist is sometime driven by the need to have the upper part of the leech sufficiently open to clear the spreaders. For a mainsail the twist is also driven by the ability of the rig to carry the tension in the leech, in particular a gaff rig will have more twist in its main sail than a Bermuda rig. It is important that the twist angle entered in Sailcut reflects the reality of the shape of the leech when sailing in an average wind. The sheeting angle value is the actual sheeting angle measured from the boat centerline when the sail is set on the boat. For a jib the minimum value is 5 degrees. The value is of importance to ensure that the sail is properly positioned when displayed in the "rig viewer". You can then visualise for example the slot between a jib and the main sail as set when sailing. "Cloth" box Enter there the width of cloth used, the width of the seams between adjacent panels, the width of material to be added to the leech to make the leech hem and the width of material for the foot hem and the other edges hems. The figure below describes de location of the various hems and seam width. Sailcut will compute the panels such that they fit within the declared cloth width including the seam and hems width as appropriate. Note that when using the radial layout, the seam width between horizontal sections will be twice the width of the seams between adjacent panels of the same section.
Sailcut seams and hems definition
Mould dialog screen (View->Mould menu) The depth of the sail can be entered at three levels located at the bottom (foot) the middle (maximum depth level) and near the top. The vertical position of the maximum depth profile is controlled by the vertical slide bar to the right of the left vertical frame. The luff shape and the leech shape can be adjusted for the Top profile and Middle profile only. The foot profile is always an arc of circle. In order to avoid that the leech makes a hook in the upper part of the sail when the wind increases it is recommended that the Top profile luff shape value be higher than that of the middle profile and that the leech shape value at the top be lower than the middle value. Rig viewer (View->Rig menu) This viewer is used to display several sails on the same rig. The File->Add sail menu entry is used to purge the viewer. The File->Add sail menu entry is used to add sails already created and saved with Sailcut. Once a sail is added to the rig viewer the sail information frame appears below and it is possible to translate the sail in the 3 directions by adding X-Y-Z displacement values. If you have misplaced a sail use the Reload button to recover the initial sail. You can also use the Remove button to eliminate a sail. 2 slides allows you to ratate the rig in azimuth and elevation and view the ig from any vantage point. The File->Save menu entry is used to save a rig with a combination of sails. Rigs which have been saved can be later opened as an entity with File->Open menu entry. Note that the rig viewer window must be closed to allow you to return to the main screen of Sailcut. View controls It is possible to zoom, pan and rotate the sail in the view window: rotation : you can control the rotation that is applied to the sail by using the elevation and azimuth sliders. pan : click on a point with the left mouse to center the view on that point. zoom : to zoom in press CTRL and + and to zoom out press CTRL and -. You can also use the zoom buttons in the view controls or your mouse wheel to zoom in and out. Sail panels development The developed sail is display by clicking on the "Development" tab from Sailcut CAD's main window. This presents you with a view of the developed (flat) panels of the sail. The view controls are the same as those of the main window. The blue line represents the edge of the finished panel (draw line) and the red line represents the outer edge taking into account the seam and hems width allowance (cut line). You can export the points which define the edges of the developed panels with the draw and cut lines to the following file formats: Carlson Design plotter (.sp4) using File->Export development->to Carlson plotter AutoCAD DXF using File->Export development->to DXF XML dump of the points using File->Export development->to XML sail (see for file format details) plain text dump of the points using File->Export development->to TXT sail (see for file format details) Loading / saving sails Once you have customised you sail, you can save it to a file (File->Save or File->Save As) and load it (File->Open) next time you want to work on it. Both the sail's dimensions and the parameters of the mould are saved. Sailcut CAD uses XML files to store the sail data. These files are plain text so they can easily be viewed using your favourite text editor. Exporting 3D sails In addition to Sailcut CAD's native file format, it is possible to export all the 3D points located on the edges and seams of the panels that make up a sail. You can export the three dimensional sail to the following file formats from the Export 3D sail submenu of the File menu: AutoCAD DXF file using the to DXF menu entry. XML dump of the points using the to XML sail menu entry (see for file format details). Plain ASCII text dump of the points using the to TXT sail menu entry (see for file format details). SVG (Scalable Vector Graphics) file using the to SVG menu entry. Printing data and drawings The File menu offers various printout possibilities: File->Print->data, will print the data of the sail, File->Print->drawing, will print a drawing of the complete sail, File->Print->develop, will print all the developed panels with key points coordinates (1 panel per page). The definition of the developed panel key points coordinates is given in the figure below. The X,Y coordinates are absolute coordinates referenced to the lower left corner of the box enveloping the contour of the CUT line of the panel (edge of cloth). The dX,dY coordinates are relative to the straight line joining the end of the corresponding edge and it should be remembered that the origin of dX is at the left end of the edge and positive value of dY indicate that the point is left of the straight line joining the origin to the end points of the edge. The printout scaling is such that the sail drawing and the largest developed panel automatically fit in one page. For printing panels to a precise scale it is preferable to export the developed sail in a DXF file and use a CAD package to print the panels.
Developed panels drawing
Sails surface formulation in Sailcut TODO Where can I find more information about Sailcut CAD? TODO File formats used by Sailcut CAD Text representation of developed sail TODO Text representation of 3D sail TODO XML representation of a sail TODO Copyright Copyright (C) Robert Lainé & Jeremy Lainé. Sailcut is a Registered Trademark of Robert Lainé. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See for the licence terms and details. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The authors would appreciate that publications on sails designed with Sailcut include some acknowledgement of their work.
sailcut-1.5.0/doc/es/rigplan.fig000066400000000000000000000134221477005247400164740ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 1 3 0 1 1 7 50 -1 -1 0.000 1 0.0000 8145 8145 45 45 8145 8145 8190 8145 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2655 5490 1890 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1710 7650 1710 8865 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1800 5445 1395 5445 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1890 4095 1080 4095 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2070 2745 765 2745 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 540 1350 540 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 855 2745 855 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 1170 4095 1170 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 1485 5445 1485 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 180 7650 3600 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 3690 765 2835 765 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2655 7650 2655 8100 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2835 7650 2835 8100 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 2652 765 2835 765 2835 7650 2652 7650 2652 765 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 6 2655 1350 2070 2745 1890 4050 1800 5400 1710 7650 1710 7605 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 3555 765 3555 7650 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 1710 8775 2745 8775 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 1890 8370 2745 8370 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2430 8055 2655 8055 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 2835 8055 3285 8055 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1890 7650 1890 8460 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1440 4905 1800 5445 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2395 4898 2755 5438 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 1485 4995 2430 4995 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1720 2198 2080 2738 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 1620 3645 2430 3645 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 1800 2295 2430 2295 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2371 2184 2731 2724 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2395 3548 2755 4088 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 1540 3548 1900 4088 2 1 3 1 1 7 50 -1 -1 10.000 0 0 -1 0 0 2 2745 9000 2745 405 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 2655 1350 495 1350 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 2070 2745 2655 2745 2655 2790 2070 2790 2070 2745 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 1890 4095 2655 4095 2655 4140 1890 4140 1890 4095 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 1800 5445 2655 5445 2655 5490 1800 5490 1800 5445 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 4545 7650 8010 1125 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 8010 1170 8010 8775 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 4545 7650 4545 8910 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 7650 7650 7650 8370 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 8145 7650 8145 8370 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 8505 765 8505 8235 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 8010 8685 4545 8685 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 7650 8145 8145 8145 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 8145 8145 8505 8145 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 7650 8145 7020 8145 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 8505 8145 9045 8145 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 7650 8325 4545 8325 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 7155 5670 7740 6030 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 4140 7650 10710 7650 2 3 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 6 8013 765 8508 765 8148 7650 7653 7650 8013 900 8013 765 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 8010 1170 4275 1170 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 4455 1170 4455 7650 2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 0 0 2 8415 2070 9180 2070 2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 9045 2070 9045 7650 2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 9585 6525 9585 7650 2 1 0 1 18 7 50 -1 -1 0.000 0 0 -1 0 0 2 8235 6525 9720 6525 2 1 0 2 18 7 50 -1 -1 0.000 0 0 -1 0 0 4 8415 2070 10035 495 11655 6165 8235 6525 4 0 1 50 -1 0 12 1.5708 4 180 1455 3510 4905 mast height = MH\001 4 0 1 50 -1 0 12 1.5708 4 180 2070 810 5535 Spreader 3 height = SPH3\001 4 0 0 50 -1 0 12 0.0000 4 135 405 6705 5670 Mast\001 4 0 4 50 -1 0 12 1.5708 4 180 1695 4365 5040 fore triangle hoist = I\001 4 0 1 50 -1 0 12 0.0000 4 135 1290 5220 8235 mast base = MB\001 4 0 4 50 -1 0 12 0.0000 4 180 1665 5220 8640 fore triangle base = J\001 4 0 1 50 -1 0 12 0.0000 4 135 315 7110 8055 MC\001 4 0 1 50 -1 0 12 0.0000 4 135 360 3015 7965 MW\001 4 0 1 50 -1 0 12 0.0000 4 135 360 2160 8325 LSB\001 4 0 1 50 -1 0 12 0.0000 4 135 375 2025 8730 CSB\001 4 0 1 50 -1 0 12 0.0000 4 135 495 1755 3555 SPW2\001 4 0 1 50 -1 0 12 0.0000 4 135 495 1755 2205 SPW3\001 4 0 1 50 -1 0 12 0.0000 4 135 495 1710 4950 SPW1\001 4 0 1 50 -1 0 12 1.5708 4 180 2070 495 4500 Cap shroud height = CSH\001 4 0 1 50 -1 0 12 1.5708 4 180 1650 1440 7380 Spreader 1 h = SPH1\001 4 0 1 50 -1 0 12 1.5708 4 180 2070 1125 6615 Spreader 2 height = SPH2\001 4 0 1 50 -1 0 12 0.0000 4 135 315 8640 8055 MR\001 4 0 18 50 -1 0 12 0.0000 4 180 1635 9090 4455 Head height = HAD \001 4 0 18 50 -1 0 14 0.0000 4 165 810 9450 3285 Mainsail\001 4 0 18 50 -1 0 12 0.0000 4 180 1575 9630 7065 Tack height = BAD\001 sailcut-1.5.0/doc/es/sail_edges.fig000066400000000000000000000116311477005247400171370ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 4815 1935 4185 1710 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 7020 405 7965 630 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 8730 7155 9225 7695 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 3 1 1.00 60.00 120.00 4005 8100 4140 7290 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 3060 7290 3015 8460 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 3 1 1.00 60.00 120.00 450 8460 270 7335 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 2835 1890 2160 1665 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 270 7245 2970 1935 3060 7155 270 7245 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 945 4455 1530 4725 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 1755 4860 1980 4950 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 1620 6705 1620 7200 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 1620 7380 1620 7785 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 3960 3960 4410 4050 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 4590 4095 5355 4230 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 6300 6750 6300 7155 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 6300 7425 6300 7830 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 5445 630 5760 990 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 5895 1170 6165 1485 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 4950 4185 4484 7243 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 8685 7065 9315 6885 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 8015 3301 8600 3121 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 7251 3531 7701 3396 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 8271 3242 9216 6887 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 2520 4590 2835 4590 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 4905 2025 5130 2295 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 5106 2230 6096 1375 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 4135 7199 4912 1989 6874 366 8674 7071 4135 7199 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 3015 4590 3735 4590 3 2 0 2 1 7 50 -1 -1 0.000 0 0 0 3 4909 1981 4365 4050 4140 7200 0.000 -1.000 0.000 3 2 0 2 1 7 50 -1 -1 0.000 0 0 0 3 4905 1980 5760 990 6885 360 0.000 -1.000 0.000 3 2 0 2 1 7 50 -1 -1 0.000 0 0 0 3 4140 7200 6300 7425 8685 7065 0.000 -1.000 0.000 3 2 0 2 4 7 50 -1 -1 0.000 0 0 0 3 270 7245 1665 7380 3060 7155 0.000 -1.000 0.000 3 2 0 2 4 7 50 -1 -1 0.000 0 0 0 3 2970 1935 2835 4590 3060 7155 0.000 -1.000 0.000 3 2 0 2 1 7 50 -1 -1 0.000 0 0 0 3 6885 360 8010 3285 8685 7065 0.000 -1.000 0.000 3 2 0 2 4 7 50 -1 -1 0.000 0 0 0 3 2970 1935 1800 4725 270 7245 0.000 -1.000 0.000 4 0 0 50 -1 0 14 0.0000 4 150 1305 765 1620 Pu\361o de driza\001 4 0 4 50 -1 0 12 0.0000 4 180 1305 270 4365 (valor negativo)\001 4 0 4 50 -1 0 14 0.0000 4 210 1785 90 4095 Alunamiento gr\341til\001 4 0 0 50 -1 0 14 0.0000 4 150 1305 3465 1575 Pu\361o de driza\001 4 0 0 50 -1 0 14 0.0000 4 150 1155 405 8685 Pu\361o amura\001 4 0 0 50 -1 0 14 0.0000 4 150 1140 2385 8685 Pu\361o escota\001 4 0 0 50 -1 0 14 0.0000 4 150 1140 8955 8010 Pu\361o escota\001 4 0 4 50 -1 0 14 0.0000 4 225 2130 630 7965 Alunamiento pujamen\001 4 0 4 50 -1 0 12 0.0000 4 180 1260 1035 8190 (valor positivo)\001 4 0 0 50 -1 0 14 0.0000 4 150 1155 4050 8280 Pu\361o amura\001 4 0 4 50 -1 0 12 0.0000 4 180 1305 270 4365 (valor negativo)\001 4 0 1 50 -1 0 12 0.0000 4 180 1260 4095 810 (valor positivo)\001 4 0 4 50 -1 0 14 0.0000 4 165 1245 2970 4230 Alunamiento\001 4 0 4 50 -1 0 14 0.0000 4 165 705 2970 4455 baluma\001 4 0 4 50 -1 0 12 0.0000 4 180 1305 2925 4815 (valor negativo)\001 4 0 1 50 -1 0 12 0.0000 4 180 1260 8640 3330 (valor positivo)\001 4 0 1 50 -1 0 14 0.0000 4 165 2010 8280 2970 Alunamiento baluma\001 4 0 0 50 -1 0 14 0.0000 4 210 1290 8055 720 Pu\361o de pena\001 4 0 1 50 -1 0 18 0.0000 4 195 1080 5625 3195 MAYOR\001 4 0 1 50 -1 0 12 0.0000 4 180 1260 5445 4500 (valor positivo)\001 4 0 1 50 -1 0 14 0.0000 4 210 1785 5445 4230 Alunamiento gr\341til\001 4 0 1 50 -1 0 14 0.0000 4 225 2130 5850 8010 Alunamiento pujamen\001 4 0 1 50 -1 0 12 0.0000 4 180 1260 6120 8235 (valor positivo)\001 4 0 0 50 -1 0 14 0.0000 4 150 810 8730 4770 Posici\363n\001 4 0 0 50 -1 0 14 0.0000 4 165 1170 8910 5040 alunamiento\001 4 0 0 50 -1 0 14 0.0000 4 150 810 5805 1890 Posici\363n\001 4 0 0 50 -1 0 14 0.0000 4 165 1170 5670 2115 alunamiento\001 4 0 0 50 -1 0 14 0.0000 4 150 810 4905 5355 Posici\363n\001 4 0 0 50 -1 0 14 0.0000 4 165 1170 4860 5625 alunamiento\001 4 0 1 50 -1 0 14 0.0000 4 225 1935 3870 540 Alunamiento percha\001 4 0 4 50 -1 0 18 0.0000 4 255 975 1575 5985 FOQUE\001 sailcut-1.5.0/doc/es/sail_seams.fig000066400000000000000000000120541477005247400171600ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 5120.579 -4210.354 2655 3015 5985 3375 8460 2655 0 0 2.00 60.00 120.00 5 1 0 1 0 7 50 -1 -1 0.000 0 0 1 0 3867.387 6515.855 1755 2700 3645 2160 5715 2565 0 0 2.00 60.00 120.00 5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 4720.387 5318.285 1260 5490 1755 7110 2655 8100 0 0 2.00 60.00 120.00 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 5 485 5869 1101 1770 2112 530 3880 5869 464 5871 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1016 5869 3597 4985 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1051 2086 2289 5869 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1581 1202 3077 5866 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 591 5197 3348 4239 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 6 5752 1148 5292 1700 5246 2068 6488 5886 7270 5886 5752 1148 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 6 5715 1035 5175 1665 5130 2025 6435 5985 7290 5985 5715 1035 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5 8370 315 7650 1215 9180 5940 10215 5940 8370 315 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 5 8300 534 7760 1209 9245 5844 10055 5844 8300 534 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 6 4770 7110 1845 8100 1755 8820 2205 8820 5040 7875 4770 7110 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 6 4635 7200 1890 8145 1800 8775 2340 8775 4905 7920 4635 7200 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 9495 3690 9720 3600 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 9138 3833 9363 3743 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 8547 3637 8772 3547 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8232 3772 8457 3682 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 5898 4058 6123 3968 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 5583 4193 5808 4103 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 4542 7642 4767 7552 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 4893 7484 5118 7394 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 2070 8775 2070 8550 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2070 9045 2070 8820 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 6840 5895 6840 5670 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 9675 5850 9675 5625 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 8055 855 8235 1035 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 7785 585 7965 765 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 5310 1125 5490 1305 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 5580 1395 5760 1575 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 5266 1883 5536 1928 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 4906 1838 5176 1883 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 3150 7335 3240 7605 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 3285 7695 3375 7965 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 1887 8347 2247 8392 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 1438 8297 1798 8342 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 6840 6210 6840 5985 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 2.00 60.00 120.00 9675 6165 9675 5940 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 9675 2205 8955 2520 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 9627 1523 8907 1838 4 0 0 50 -1 0 14 0.0000 4 150 435 1800 6165 Foot\001 4 0 0 50 -1 0 14 0.0000 4 150 435 1170 1035 Gaff\001 4 0 0 50 -1 0 14 0.0000 4 150 585 2745 2070 Leech\001 4 0 0 50 -1 0 14 0.0000 4 165 975 5220 7380 leech hem\001 4 0 0 50 -1 0 14 0.0000 4 150 960 4545 1035 other hem\001 4 0 0 50 -1 0 14 0.0000 4 150 855 2205 9135 foot hem\001 4 0 0 50 -1 0 14 0.0000 4 150 960 720 8145 other hem\001 4 0 0 50 -1 0 17 0.0000 4 195 150 2745 8235 1\001 4 0 0 50 -1 0 16 0.0000 4 195 135 1665 2970 2\001 4 0 0 50 -1 0 16 0.0000 4 195 135 2430 2925 3\001 4 0 0 50 -1 0 17 0.0000 4 195 150 8505 2565 3\001 4 0 0 50 -1 0 14 0.0000 4 165 975 9765 3510 leech hem\001 4 0 1 50 -1 0 14 0.0000 4 210 1500 9765 2205 draw line (blue)\001 4 0 4 50 -1 0 14 0.0000 4 210 1200 9720 1485 cut line (red)\001 4 0 0 50 -1 0 16 0.0000 4 195 1950 8415 8595 Draw line in blue \001 4 0 0 50 -1 0 16 0.0000 4 195 1590 8415 8910 Cut line in red\001 4 0 0 69 -1 0 16 0.0000 4 195 135 1305 5355 1\001 4 0 0 50 -1 0 17 0.0000 4 195 150 5805 2700 2\001 4 0 0 50 -1 0 17 0.0000 4 270 1860 3825 8685 Cross cut layout\001 4 0 0 50 -1 0 14 0.0000 4 150 420 405 3240 Luff\001 4 0 0 50 -1 0 14 0.0000 4 150 1095 4590 4050 seam width\001 4 0 0 50 -1 0 14 0.0000 4 150 1095 7245 3645 seam width\001 4 0 0 50 -1 0 14 0.0000 4 150 855 6930 6300 foot hem\001 4 0 0 50 -1 0 14 0.0000 4 150 855 9765 6255 foot hem\001 4 0 0 50 -1 0 14 0.0000 4 150 960 4095 1755 other hem\001 4 0 0 50 -1 0 14 0.0000 4 150 960 6750 585 other hem\001 4 0 0 50 -1 0 17 0.0000 4 270 2100 7695 6840 Vertical cut layout\001 4 0 0 50 -1 0 14 0.0000 4 150 1095 2565 7290 seam width\001 sailcut-1.5.0/doc/es/sailplan.fig000066400000000000000000000074471477005247400166550ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 5 1 0 2 1 7 50 -1 -1 0.000 0 0 1 1 4980.000 1860.000 5175 720 5625 900 5940 1215 0 0 2.00 60.00 120.00 0 0 2.00 60.00 120.00 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 1350 7920 9000 7920 8910 8280 1575 8280 1350 7920 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1350 7920 4590 3150 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 4140 7290 4140 8955 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 1350 7920 315 7920 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 1530 7695 675 7695 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 4140 7245 3285 7245 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 5 4140 7245 4923 2028 6840 630 8685 7110 4113 7248 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 3 1 1.00 60.00 120.00 3150 4005 4275 3555 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 3960 7920 4905 1575 4815 1575 3870 7920 3960 7920 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 3 1 1.00 60.00 120.00 5265 5985 4230 7155 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 4995 2070 5486 2479 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 8550 7020 7335 6300 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 4590 3195 360 3195 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 1530 7695 4185 3780 3645 7605 1530 7695 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 3420 7245 3420 6705 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 3420 7920 3420 8190 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 3 1 1.00 60.00 120.00 4230 1710 4669 2140 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 3 1 2.00 60.00 120.00 3 1 2.00 60.00 120.00 1350 8775 4140 8775 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 3 1 2.00 60.00 120.00 3 1 2.00 60.00 120.00 4140 8775 4950 8775 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 1 2 3 1 2.00 60.00 120.00 3 1 2.00 60.00 120.00 1350 9135 4545 9135 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 4545 3195 4545 9135 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 1350 7740 1350 9135 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 4905 2070 5130 720 5130 675 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 4950 2025 4950 8910 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 1 2 3 1 1.00 60.00 120.00 3 1 1.00 60.00 120.00 405 7920 405 3195 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 6975 720 7560 1125 3 2 0 2 4 7 50 -1 -1 0.000 0 0 1 2 3 1 2.00 60.00 120.00 720 7695 720 6840 0.000 0.000 3 2 0 2 4 7 50 -1 -1 0.000 0 0 1 2 3 1 2.00 60.00 120.00 720 7920 720 8280 0.000 0.000 4 0 1 50 -1 0 16 0.0000 4 255 975 6390 7110 Pujamen\001 4 0 1 50 -1 0 16 0.0000 4 195 855 7785 3375 Baluma\001 4 0 4 50 -1 0 14 0.0000 4 150 1230 1935 9045 Distancia = J\001 4 0 1 50 -1 0 14 0.0000 4 210 1770 1935 8685 Pu\361o amura - proa\001 4 0 4 50 -1 0 14 0.0000 4 225 1140 720 6660 Altura pu\361o\001 4 0 4 50 -1 0 14 0.0000 4 210 1200 810 6930 amura foque\001 4 0 4 50 -1 0 14 0.0000 4 210 1365 540 5535 Altura stay = I\001 4 0 0 50 -1 0 16 0.0000 4 195 1695 6705 6210 Pu\361o\240 de escota\001 4 0 0 50 -1 0 16 0.0000 4 195 1710 5040 5850 Pu\361o\240 de amura\001 4 0 1 50 -1 0 14 0.0000 4 150 1275 2340 7425 amura mayor\001 4 0 1 50 -1 0 14 0.0000 4 225 1140 2205 7200 Altura pu\361o\001 4 0 4 50 -1 0 18 0.0000 4 255 705 2970 6030 Foque\001 4 0 0 50 -1 0 16 0.0000 4 255 480 2160 4005 Stay\001 4 0 1 50 -1 0 16 0.0000 4 195 690 4680 4365 Gr\341til\001 4 0 1 50 -1 0 18 0.0000 4 255 765 6120 4095 Mayor\001 4 0 0 50 -1 0 18 0.0000 4 195 1080 3600 1665 MASTIL\001 4 0 0 50 -1 0 16 0.0000 4 195 1485 7740 1215 Pu\361o de Pena\001 4 0 1 50 -1 0 16 0.0000 4 195 765 5805 810 Percha\001 4 0 0 50 -1 0 16 0.0000 4 195 1560 5445 2790 Pu\361o de Driza\001 4 0 1 50 -1 0 14 0.0000 4 210 1095 4995 8730 Ca\355da gr\341til\001 4 0 0 50 -1 0 14 0.0000 4 165 2265 6030 7830 Eslora de cubierta LOA\001 4 0 1 50 -1 0 14 0.0000 4 255 1965 3015 720 \301ngulo percha-gr\341til\001 sailcut-1.5.0/doc/fr/000077500000000000000000000000001477005247400143475ustar00rootroot00000000000000sailcut-1.5.0/doc/fr/coordinates_system.fig000066400000000000000000000030611477005247400207540ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 3 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 630 9000 1755 8055 8235 8055 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 1755 8055 1755 1080 2 3 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 6 2250 7560 4095 1845 5355 1350 6660 7200 2205 7560 2250 7560 2 3 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 6390 4275 5805 5040 2070 5040 2925 4275 6390 4275 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 3330 4275 2880 4815 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 6390 4275 6660 4275 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 4284 4282 3956 4676 3 2 0 1 4 7 50 -1 -1 0.000 0 0 0 3 3330 4275 4005 4680 6030 4275 0.000 -1.000 0.000 3 2 0 1 0 7 50 -1 -1 0.000 0 0 0 3 3915 2520 4635 2700 5580 2475 0.000 -1.000 0.000 3 2 0 1 0 7 50 -1 -1 0.000 0 0 0 3 2745 6030 3510 6345 6390 5940 0.000 -1.000 0.000 4 0 0 50 -1 0 12 0.0000 4 150 510 1035 1035 Y axis\001 4 0 0 50 -1 0 12 0.0000 4 150 495 900 9135 Z axis\001 4 0 0 50 -1 0 12 0.0000 4 150 510 7875 8370 X axis\001 4 0 0 50 -1 0 12 0.0000 4 90 105 6570 4185 x\001 4 0 0 50 -1 0 12 0.0000 4 135 630 4095 7590 bordure\001 4 0 0 50 -1 0 12 0.0000 4 135 450 5985 3510 chute\001 4 0 0 50 -1 0 12 0.0000 4 180 735 2790 3465 guindant\001 4 0 0 50 -1 0 12 0.0000 4 195 1200 3780 4860 creux du profil\001 4 0 0 50 -1 0 12 0.0000 4 195 1740 3870 4185 corde locale du profil\001 4 0 0 50 -1 0 12 0.0000 4 90 90 2745 4860 z\001 sailcut-1.5.0/doc/fr/develop_panel_drawing.fig000066400000000000000000000072421477005247400213730ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 3 6705 3510 7155 5040 7245 6615 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 3 1215 6750 1620 5085 2565 3375 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 3 900 6930 1350 5085 2430 3105 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 3 6885 3285 7425 5040 7515 6975 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 1 3 0 0 1.00 120.00 240.00 0 0 1.00 120.00 240.00 900 1350 900 7290 9900 7290 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1710 2385 2565 3375 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 4230 2655 3960 3285 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 6390 2745 6120 3600 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 7965 2385 6705 3510 2 1 0 1 9 7 50 -1 -1 0.000 0 0 -1 1 1 3 0 0 1.00 90.00 180.00 0 0 1.00 90.00 180.00 1170 4500 1215 6750 8595 6570 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2880 7785 3240 7020 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 900 8100 1215 6750 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 6525 6525 6165 7875 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 7245 6615 7605 8055 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1575 6345 1215 6750 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 1 1 3 0 0 1.00 90.00 180.00 0 0 1.00 90.00 180.00 2610 1530 2565 3375 8955 3600 2 2 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 5 900 7290 7515 7290 7515 2970 900 2970 900 7290 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 2790 2745 2565 3375 2610 3375 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 900 7290 810 7380 3 2 0 2 1 7 50 -1 -1 0.000 0 0 0 4 1215 6750 3735 7020 6075 6570 7245 6615 0.000 -1.000 -1.000 0.000 3 2 0 2 1 7 50 -1 -1 0.000 0 0 0 4 2565 3375 4185 3285 6030 3555 6705 3510 0.000 -1.000 -1.000 0.000 3 2 0 2 4 7 50 -1 -1 0.000 0 0 0 4 900 6930 3690 7290 6030 6840 7515 6975 0.000 -1.000 -1.000 0.000 3 2 0 2 4 7 50 -1 -1 0.000 0 0 0 4 2430 3105 4185 3015 6030 3285 6885 3285 0.000 -1.000 -1.000 0.000 4 0 0 50 -1 0 12 0.0000 4 135 705 2115 8055 dY = -10\001 4 0 0 50 -1 0 12 0.0000 4 135 750 2115 7830 dX = 321\001 4 0 1 50 -1 0 12 0.0000 4 135 540 1665 6210 dX = 0\001 4 0 1 50 -1 0 12 0.0000 4 135 540 1665 6435 dY = 0\001 4 0 0 50 -1 0 12 0.0000 4 135 750 7785 2025 X = 1789\001 4 0 0 50 -1 0 12 0.0000 4 135 645 7785 2295 Y = 678\001 4 0 0 50 -1 0 12 0.0000 4 135 645 1395 2070 X = 234 \001 4 0 0 50 -1 0 12 0.0000 4 135 645 1395 2340 Y = 789\001 4 0 0 50 -1 0 12 0.0000 4 135 540 5265 8145 dY = 2\001 4 0 0 50 -1 0 12 0.0000 4 135 855 5265 7875 dX = 1345\001 4 0 9 50 -1 0 12 0.0000 4 135 240 1215 4500 dY\001 4 0 0 50 -1 0 12 0.0000 4 135 750 7740 7965 X = 1890\001 4 0 0 50 -1 0 12 0.0000 4 135 540 7740 8235 Y = 35\001 4 0 0 50 -1 0 12 0.0000 4 135 750 4050 2340 dX = 345\001 4 0 0 50 -1 0 12 0.0000 4 135 540 4050 2565 dY = 5\001 4 0 0 50 -1 0 12 0.0000 4 135 600 6075 2700 dY = -2\001 4 0 0 50 -1 0 12 0.0000 4 135 855 6075 2475 dX = 1234\001 4 0 1 50 -1 0 12 0.0000 4 135 540 2835 2520 dX = 0\001 4 0 1 50 -1 0 12 0.0000 4 135 540 2835 2700 dY = 0\001 4 0 1 50 -1 0 12 0.0000 4 180 1455 8145 3420 dX bord sup\351rieur\001 4 0 9 50 -1 0 12 0.0000 4 135 1395 8145 6435 dX bord inf\351rieur\001 4 0 1 50 -1 0 12 0.0000 4 180 1455 2745 1710 dY bord sup\351rieur\001 4 0 4 50 -1 0 12 0.0000 4 135 435 315 7335 X = 0\001 4 0 4 50 -1 0 12 0.0000 4 135 435 315 7560 Y = 0\001 4 0 4 50 -1 0 18 0.0000 4 195 210 9540 7155 Y\001 4 0 4 50 -1 0 18 0.0000 4 195 210 585 1845 X\001 4 0 0 50 -1 0 12 0.0000 4 135 540 270 8145 X = 15\001 4 0 0 50 -1 0 12 0.0000 4 135 540 270 8370 Y = 25\001 4 0 0 50 -1 0 18 0.0000 4 195 1005 3105 4320 Panneau\001 4 0 1 90 -1 0 12 0.0000 4 180 2550 4365 4995 Ligne de trac\351 (DRAW) en bleu\001 4 0 4 50 -1 0 12 0.0000 4 180 2565 4365 5400 Ligne de coupe (CUT) en rouge\001 sailcut-1.5.0/doc/fr/head_gores_definition.fig000066400000000000000000000035121477005247400213470ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 1350 8685 3555 7245 6075 8595 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 3690 3735 4230 5985 6075 8595 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 4 3510 675 3105 3735 2430 6030 1350 8685 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 3690 675 4230 3735 4905 5985 6075 8595 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2610 3735 4905 3735 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 4 3600 675 3566 3738 2981 6033 1350 8685 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2025 6005 5535 5985 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3602 5985 3510 8730 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 1350 8685 3600 5985 6075 8595 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3420 675 3825 675 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 3420 675 1350 8685 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 2 1 1.00 60.00 120.00 5175 2700 4590 2700 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 2 1 1.00 60.00 120.00 2295 2700 2880 2700 3 0 0 1 0 7 50 -1 -1 0.000 0 0 0 3 1350 8685 3510 8820 6075 8595 0.000 1.000 0.000 3 0 0 1 0 7 50 -1 -1 0.000 0 0 0 4 3825 675 4950 3735 5535 5940 6075 8595 0.000 1.000 1.000 0.000 4 0 0 50 -1 0 14 0.0000 4 210 2655 4860 2520 4 panneaux Radiaux en tout\001 4 0 0 50 -1 0 14 0.0000 4 165 2175 5400 4590 Cette voile a 3 sections\001 4 0 0 50 -1 0 16 0.0000 4 195 510 2700 765 T\352te\001 4 0 0 50 -1 0 14 0.0000 4 150 780 3330 9045 Bordure\001 4 0 0 50 -1 0 14 0.0000 4 150 570 5760 6435 Chute\001 4 0 1 50 -1 0 14 0.0000 4 150 945 990 6390 Guindant \001 4 0 0 50 -1 0 16 0.0000 4 195 765 5985 8955 Ecoute\001 4 0 0 50 -1 0 16 0.0000 4 195 810 720 9000 Amure\001 4 0 1 50 -1 0 14 0.0000 4 165 2250 495 2925 vont de la tete \340 l'amure\001 4 0 1 50 -1 0 14 0.0000 4 210 3030 225 2565 2 panneaux radiaux de guindant\001 sailcut-1.5.0/doc/fr/index.docbook000066400000000000000000001470301477005247400170250ustar00rootroot00000000000000
Manuel de Sailcut CAD Robert Lainé Jeremy Lainé Sailcut CAD 1.5.0 - 23 mars 2025 Introduction Ce manuel est en cours de rédaction. A propos de Sailcut CAD Sailcut is est un logiciel de tracé de voiles et de développement à plat des laizes. Les voiles peuvent être à 3 cotés ou à 4 cotés pour les gréements anciens par exemple. La première version de Sailcut a été développée en 1978 et utilisée par Robert Lainé sur son 1/4 ton IOR "Flying Sheep III". Sailcut est disponible sur la toile Internet depuis 1994 et est utilisé par beaucoup de professionels et amateurs maîtres voiliers, pour des bateaux de course, de croisière ou maquettes navigantes. Sailcut utilise une définition mathématique de la surface des voiles qui garantie que le profil de la voile sera lisse et aérodynamique. Où obtenir Sailcut CAD? Vous pouvez télécharger la dernière version de Sailcut CAD depuis la page du projet à . Informations techniques sur le code Sailcut CAD est écrit dans le but d'être portable. Le code est donc du C++ qui utilise la librairie Qt de Trolltech pour l'interface graphique. Sailcut CAD utilise OpenGL pour tous les affichages 3D. Sailcut se compile et tourne sur GNU/Linux, Microsoft Windows et MacOS/X. Utilisation de Sailcut CAD Notes sur l'utilisation de fichier de versions précédentes A partir de la version 0.6.5 Sailcut CAD utilise des extensions de nom de fichier distincts au lieu de l'extension générique ".xml". Si vous souhaitez réutiliser des fichiers de données de voile de ce type vous devez les renommer avec l'extension ".saildef". Vous pourrez alors récupérer les données dimensionelles de la voile mais pas le moule que vous devrez redéfinir avant de sauvegarder les données. Préférences utilisateur Fichier des préférences Vos préférences sount enregistrées dans le fichier .sailcutrc. Sur les plateformes Unix ce fichier est placé dans votre répertoire HOME. Sous Windows ce fichier se trouve généralement dans le répertoire Documents and Settings\UTILISATEUR. Internationalisation A partir de la version 0.6.5, Sailcut CAD est internationalisé. La traduction des interfaces utilisateur est disponibles dans plusieurs languages. Au démarrage Sailcut utilise la langue correspondante à vos paramètres locaux. Vous pouvez changer la langue en utilisant le sous-menu Langue du menu Vue. Créer une voile Au lancement Sailcut CAD vous présente une voile par défaut. En haut de la fenêtre vous trouverez une série de menus déroulant. Le menu Fichier est utilisé pour le chargement d'une voile existante, la sauvegarde des données et paramètres de la voile et l'export des panneaux développés. Vous pouvez changer les dimensions de la voile à partir de l'entrée Dimensions du menu déroulant Vue. Vous pouvez modifier le profil de la voile à partir de l'entrée Moule du menu déroulant Vue. Vous pouvez visualiser plusieurs voiles sur le même gréement à partir de l'entrée Gréement du menu déroulant Vue. Définition de la voile Dans cette fenêtre vous définissez toutes les dimensions de la voile. Le programme est concu pour traiter les voiles triangulaires et quadrangulaires. Une voile triangulaire peut être vue comme une voile quadrangulaire dont le coté haut est très petit. La surface de la voile est générée à partir d'un jeu d'équations qui défini le profil de la voile à toutes les hauteurs. Ces profils reposent sur les bords de la voile qui sont eux même définis par leur longueur et le rond de ces bords, ainsi que par le vrillage de la voile. La fenêtre Définition de la voile est constituée de boites regroupant les divers paramètres de la voile. Utilisez le bouton Calculer pour calculer et afficher des données auxiliaire et en particulier la largeur de la voile aux points spécifiés par la règle IRC. Cette opération peut aussi changer la couleur de certaines zones de saisie. La couleur est rouge c' si la valeur est trop forte et jaune si elle est trop faible. La valeur elle même sera changée pour être à la limite acceptable. Lorsque vous avez fini d'entrer les données pressez le bouton OK pour afficher la voile en 3D. Géométrie du gréement La première étape est de choisir le type de voile sur laquelle vous voulez travailler et d'entrer les dimensions du gréement et du pont du bateau. Choisissez le type de voile en appuyant sur le bouton radio correspondant: Grand-voile pour toute voile montée sur un mât. Foc pour toute voile montée sur un étais fixe ou mobile. Aile pour toute voile cerf-volant ou planneur symétrique par rapport à la bordure. Les dimensions du gréement sont utilisée pour que les voiles s'affichent à la bonne position dans la fenêtre Gréement.
Définition du plan des voiles dans Sailcut
Identifiant de la voile Vous pouvez attacher un nom explicite aux données de la voile (maximum 40 caractères espaces compris). Dimensions de la voile C'est ici que vous entrez les dimensions de la voile. Pour une Grand-voile la longueur minimum de la vergue est de 5mm. Cette vergue peut aussi être la têtière. Une longueur inférieur à 5mm sera corrigée automatiquement par Sailcut. L'angle de la vergue par rapport au guindant est limité à 90 degrés. Une valeur positive du rond de guindant, bordure, chute ou vergue fait que le bord de la voile est à l'extérieur de la ligne droite joignant les coins correspondants. Un rond négatif revient à creuser le bord de la voile. Laposition du rond est exprimé en pourcentage de la longueur du bord correspondant, mesuré en partant du coin gauche ou bas de ce bord.
Définition des bords des laizes dans Sailcut
Les dimensions et les angles sont exprimés en millimètres et degrés. La longueur des bords ou de la diagonale d'une voile est la distance en ligne droite dans l'espace 3D entre les coins correspondants. Selon la forme de la voile, la longueur réelle d'un bord de la voile finie telle que mesurée sur le plancher, peut être légèrement plus grande que celle entrée. Par exemple, pour une longueur de bordure entrée de 3600 mm, si le creux de la bordure est nul, ce sera aussi la distance à plat entre point d'amure et d'écoute. Si le creux de la voile au niveau de la bordure est de 10%, alors la distance à plat entre point d'amure et d'écoute sera 2.7% plus grande que la longueur entrée. Après avoir entré les dimensions de la voile, vous pouvez cliquer sur le bouton Calculer pour obtenir des informations supplémentaires, tel que les coordonnées des coins de la voile, la distance perpendiculaire LP mesurée du point d'écoute au guindant anisi que les largeurs de la voile selon la règle de jauge IRC. Les coordonnées X-Y des coins de la voile sont utiles pour ajuster rapidement le plan de la voile. Si par exemple vous voyez que le point d'écoute est trop haut ou trop bas par rapport au point d'amure (valeur de Y), vous pouvez corriger cela en ajoutant ou retranchant la différence à la longueur de la chute.
Coupe Cliquez sur le bouton radio correspondant à la coupe de voile désirée. L'arrangement des laizes n'affecte pas la forme de la voile qui est définie par ses dimensions et son moule. Sauf pour la coupe radiale, le nombre de panneaux est déterminé automatiquement par la largeur du tissus et la largeur de couture entrés dans la boite Tissus. La coupe la plus courante est la Coupe transversale. Les laizes sont positionnées perpendiculairement à la ligne droite joignat le point d'écoute au pic de la voile. La Coupe twist est similaire à la coupe transversale sauf que les laizes du bas sont réorientées pour ne pas couper la bordure de la voile. La Coupe horizontale positionne les laizes horizontalement. Cette option peut être utilisée pour visualiser la forme de la voile et pour sortir des fichiers de points 3D positionés dans des plans horizontaux pour être utilisés par des outils de calcul d'écoulement de l'air. La Coupe verticale positionne les laizes parallélement à la chute. C'est la coupe classique des grand-voiles de vieux gréements. La Coupe mître est classiquement utilisée pour les génoas de vieux gréements. La voile est divisée en deux par une ligne joignant le point d'écoute au milieu du guindant. Les laizes sont placées perpendiculairement à la bordure dans la moitié inférieure et perpendiculairement à la chute dans la moitiée supérieure. La Coupe radiale est surtout utilisée en compétition avec les laizes orientées selon les directions de contrainte maximum. Avant d'utiliser cette coupe radiale il est important de bien comprendre la définition du nombre de sections, du nombre de fuseaux radiaux et du guindant (voir ).
Définition des fuseaux radiaux dans Sailcut
Forme Vous entrez ici le creux de la voile à trois hauteurs dans la voile: à la bordure, au milieu (la position exacte est définie dans le moule de la voile) et en haut de la voile. Ces valeurs se retrouvent dans la fenêtre Moule de la voile. L'angle de vrillage exprimé en degrés est l'ouverture du haut de la voile par rapport à la bordure. Le vrillage est essentiel pour tenir compte de la différence de direction du vent apparent entre le bas de la voile et le haut. Quelque fois le vrillage des focs ou génoas est déterminé par le besoin de passer la chute en dehors des barres de flèche. Pour une grand-voile à vergue, le vrillage est aussi déterminé par la capacité du gréement à tenir la tension de la chute. Ceci fait que le vrillage de ces gréements est plus important que pour un gréement Bermudien. Dans tous les cas il est important d'entre un angle de vrillage qui reflète la réalité de la forme de la voile sur le bateau dans les conditions de vent attendues. L'angle d'Ouverture est l'angle que fait la ligne joignant le point d'amure au point d'écoute par rapport à l'axe du bateau. Pour un foc la valeur minimum est de 5 degrés. Il est important de donner la bonne valeur de facon à ce que l'ensemble grand-voile + foc soit bien positionné dans la vue Gréement. ceci vous permettra de bien visualiser la fente entre le foc et la grand voile, comme sur le bateau. Notez que cet angle d'ouverture s'ajoute au vrillage pour donner l'angle du profile de la voile à toutes les hauteurs dans la voile. Tissus Entrez ici la largeur du tissus utilisé, la largeur de couture nécessaire pour assembler les laizes et les réservations de tissus pour faire les ourlets de la chute, de la bordure et des autres bords de la voile. La figure donne la position des réservations pour couture et ourlets. Sailcut CAD va calculer la position des coutures pour que les laizes utilisent au maximum la largeur du tissus, sauf dans la coupe radiale ou la largeur des laizes dépend du nombre de fuseaux. Notez que dans la coupe radiale, la largeur des coutures entre sections horizontales est le double de la largeur des coutures entre panneaux adjacent d'une section.
Définition des coutures et ourlets dans Sailcut
Moule de la voile La profondeur et la forme de la voile sont définies par trois profiles situés au niveau de la bordure, au milieu et en haut de la voile. Ces profiles peuvent être ajusté avec les 3 curseurs placé en dessous de chaque profile. La position du creux maximum de chaque profile est indiqué en dessous de la valeur du creux. Cette position dépend des coefficients de forme du guindant et de la chute, elle est exprimé par rapport à la corde de ce profile. Par exemple: 0.34 veut dire que le creux maximum du profile est situé à 34% de la corde en partant du guindant. La forme du profile coté guidant et coté chute peuvent être modifiés avec les curseurs correspondants. Dans le cas d'une voile à bordure libre, il est recommandé de mettre le coefficient de forme guidant à 1 et celui de la chute à 0 pour avoir un arc de cercle. Sous les coefficients de forme du guidant et de la chute, les valeurs correspondantes de l'angle d'entrée et de sortie du profile sont affichées en degrés. Ces angles sont rapportés à la corde du profile. Pour obtenir l'angle d'entrée ou de sortie du profile par rapport à l'axe du bateau il faut y ajouter l'angle de vrillage du profile et l'angle d'ouverture de la voile. En particulier pour un foc il est utile de vérifier que l'angle de sortie des profiles ajouté à l'angle d'ouverture de la voile ne donne pas une valeur trop négative (risque de renvois dans la grand-voile). La position verticale du creux maximum de la voile peut être ajusté par le curseur vertical situé à la droite du panneau vertical de gauche. Afin d'éviter que le haut de la voile ne se referme trop quand le vent augmente, il est recommandé de donner un coefficient de forme du guindant qui augmente avec la hauteur du profile et que par contre, le coefficient de forme de la chute diminue avec la hauteur du profile. Controle des vues Il est possible de faire un zoom, déplacer (pan) ou tourner les voiles dans une zone d'affichage graphique: Rotation : Vous pouvez tourner la voile en azimuth et élévation avec les curseurs situés au bord du panneau d'affichage. Déplacement : Cliquez sur un point de la voile pour le placer au centre de la zone d'affichage graphique. Zoom: Utilisez les touches CTRL + pour agrandir la vue et CTRL - pour la réduire. Vous pouvez aussi utiliser la molette de la souris pour ces fonctions de zoom avant et arrière. Développement des laizes Le développement de la voile s'affiche en cliquant sur l'onglet Développement de la fenêtre principale de Sailcut CAD. Les fonctions de controle de la vue sont les mêmes que pour la vue 3D. Les lignes bleues représentent les ligne de tracé des laizes et les ligne rouges les lignes de découpe prenant en compte les marges de couture. Vous pouvez exporter les points qui définissent les lignes de tracé et de découpe des laizes aux formats suivants à l'aide du sous-menu Export développement du menu déroulant Fichier: Fichier pour table traçante Carlson Design avec l'entrée table traçante Carlson. Fichier AutoCAD DXF avec l'entrée DXF. Tous les panneaux sont dans un seul fichier avec un panneau par calque. Plusieurs fichiers AutoCAD DXF avec l'entrée DXF (divisé). Chaque panneau est enregistré dans un fichier distinct sur le calque 1. Le nom des fichiers est le nom saisi complété avec le numéro du panneau (0,1,2,...). Fichier pouvant être lu avec un éditeur de texte pour le traçage à la main avec l'entrée traçage manuel. Fichier XML de toutes les laizes avec l'entrée voile XML (voir pour les détails du format du fichier). Fichier texte ASCII ordinaire de toutes les laizes avec l'entrée voile TXT (voir pour les détails du format du fichier). Fichier SVG (Scalable Vector Graphics) avec l'entrée SVG. Enregistrer et ouvrir les voiles Dès que vous avez créé une voile, vous pouvez enregistrer ses données dans un fichier avec les entrées Enregistrer ou Enregistrer sous du menu déroulant Fichier. Vous pouvez ensuite la recharger avec l'entrée Ouvrir la prochaine fois que vous voulez y retravailler. Les dimensions de la voile et la forme du moule sont sauvegardées simultanément. Ceci permet de recharger une voile et réutiliser son moule même si les dimensions de la voile sont changées par la suite. Sailcut CAD cré des fichiers XML pour sauvegarder les données des voiles. Ces fichiers peuvent être lus avec n'importe quel éditeur de texte. Exporter les voiles 3D En plus d'enregistrer les caractéristiques des voiles comme ci-dessus, il est possible d'exporter les points 3D situés sur les bords et les coutures de la voile. Ceci peut être fait dans les formats suivants à l'aide du sous-menu Export voile 3D du menu déroulant Fichier: Fichier AutoCAD DXF avec l'entrée DXF. Tous les panneaux sont dans un seul fichier avec un panneau par calque. Plusieurs fichiers AutoCAD DXF avec l'entrée DXF (divisé). Chaque panneau est enregistré dans un fichier distinct sur le calque 1. Le nom des fichiers est le nom saisi complété avec le numéro du panneau. Fichier XML avec l'entrée voile XML (voir pour les détails du format du fichier). Fichier texte ASCII ordinaire avec l'entrée voile TXT (voir pour les détails du format du fichier). Imprimer les données et dessins Le sous-menu Imprimer du menu Fichier offre plusieurs possibilités d'impression: L'entrée donnés permet d'imprimer les caractéristiques de la voile. L'entrée dessin permet d'imprimer un dessin de la voile complète. Une fenètre de prévisualiser l'impression et un spinbox permet de changer le facteur d'échelle. Le facteur d'échelle est le nombre par lequel on multiplie la dimension de la voile pour avoir sa taille sur le dessin imprimé. Le facteur d'échelle peut être aussi petit que 0.001 (une voile de 1000mm sera imprimée dans 1mm), la valeur par défaut est telle que la voile tiens dans 80% de la taille du papier. L'entrée développement permet d'imprimer le dessin d'une laize développée par page avec les coordonnées des points clés sur les bords. Une fenètre de prévisualiser l'impression et un spinbox permet de changer le facteur d'échelle comme pour la voile entière. L'impression est en mode paysage. La définition des coordonnées des points clés est donnée dans . Les coordonnées X,Y sont référencées au coin en bas à gauche du rectangle qui enveloppe la ligne de coupe de la laize. Les coordonnées dX,dY sont référencées à la ligne droite qui joint les extrémités du bord concerné. Le point dX = 0 (origine) est à l'extrémité gauche du bord et les points avec des valeurs dY positives sont situés à gauche de la ligne droite joignant l'origine (dX = 0) à l'autre extrémité du bord concerné en partant de l'origine du bord. Le facteur d'échelle d'impression est tel que le dessin de la voile et de la laize la plus grande logent sur une page. Pour imprimer les laizes à échelle 1 ou autre, il est préferrable d'exporter la voile au format DXF et d'utiliser un logicile de CAO pour piloter l'impression.
Dessin des laizes développées
Créer un gréement Ce module permet de dessiner un mât avec jusqu'à 3 niveaux de barres de flèche. On y accède avec l'entrée Gréement du menu principal Fichier Nouveau. L'entrée Dimensions du menu Vue affiche l'écran à partir duquel vous pouvez saisir et modifier les dimensions du gréement. La définition des diverses dimensions est donnée dans la figure . Veuillez noter que pour assurer que l'on puisse définir des voiles indépendament du gréement, la définition de la quête et de la courbure du mât se réfère à la hauteur complète du mât alors que dans la grandvoile, la courbe du guindant et son inclinaison sont rapportées à la longeur du guindant. Le module du gréement permet de calculer ces dernières données en partant de la hauteur du point d'amure et de la hauteur de la têtière.
Définitions du gréement Sailcut
Sauvegarder et Charger un fichier de gréement L'entrée Sauvegarder du menu Fichier est utilisée pour sauvegarder les données d'un gréement. Tout gréement qui est sauvegardé peut ensuite être chargé en utilisant l'entrée Ouvrir du menu Fichier et peut être utilisé comme élément constitutif d'un bateau. Contrôle des vues Le contrôle des vues est identiques à celui de l'écran graphique des voiles. Vous pouvez fare tourner le gréement avec les curseurs situés au bord de la fenêtre graphique, faire un zoom avec la roulette de la souris, recentrer la vue avec un clic gauche sur un point, afficher le gréement en surfaces colorées ou vue fil de fer. Dimensions d'un gréement L'entrée Dimensions du menu Vue affiche l'écran avec les dimensions du gréement. Cet écran est divisé en cadres correspondants aux entités listées ci-dessous. Veillez noter que les angles sont exprimés en degrés et les dimensions linéaires en millimètres. Gréement ID Un texte libre identifiant ou décrivant le gréement. Le nombre de caractères est limité à 40. Triangle avant La hauteur = I et la base = J du triangle avant sont entrées dans les cjhamps correspondants. Notez que ces dimensions sont prises selon la verticale et l'horizontale. Soyez attentifs à la mesure de J quand le mât est incliné. Mât Le mât a une section constante du haut en bas. Les hauteurs sont référencées au plan horizontal passant par la ferrure d"étrave. Hauteur du mât = MH hauteur du sommet du mât, elle doit être supérieure à J. Rond du mât = MRnd déviation maximum par rapport à la ligne droite joingant le sommet du ma à son pied. Position du rond du mât = MRndPos spin box permettant d'entrer la hauteur relative du point de rond maximum, exprimé en pourcentage de la hauteur du mât. Quête du mât = MRkM distance horizontale entre le sommet du mât et son pied. Sailcut CAD calcul en degré l'inclinaison correspondante du mât = MRkD. Corde du mât = MC dimension avant-arrière du profile de mât. Largeur du mât = MW dimension transversse du profile du mât. Grandvoile Voir plus loin le paragraphe à propos de la courbe du guindant de la grandvoile. Haubans Hauteur hauban de tête = CSH hauteur du point de fixation de ce hauban sur le mât. Base hauban de tête = CSB distance de la cadène du hauban de tête à la ligne centrale du pont. Base bas hauban = LSB distance de la cadène du bas hauban à la ligne centrale du pont. Doit être inférieure ou égale à la base du hauban de tête. Barres de flèche Nombre de barres de flèche = SPNB peut être de 0 (pas de barre de flèche) à 3. Si il n'y a pas de barre de flèche alors la base du hauban de tête est égale à celle du bas hauban. Hauteur barre de flèche SPH mesurées depuis le plan horizontal de référence, elles doivent être entrées dans l'ordre ascendant, 1 etant la barre la plus basse. Longeur barre de flèche SPW mesurée depuis la ligne centrale du mât. Vérifier et Valider les données Utilisez le bouton Vérifier pour afficher les données auxilliaires et vérifier que les données entrées sont cohérentes avec une géometrie raisonable du gréement. En cas d'anomalie dans les données, la couleur ds caractères douteux vous indique le type d'anomalie. Rouge indique une valeur trop forte, mauve une valeur trop faible et bleu indique les données en relation avec l'anomalie et qui doivent être vérifiées. Une fois que vous avez entré le données, cliquer sur le bouton OK pour fermer l'écran dimensions et afficher le dessin. L'écran dimensions ne se fermera qu'une fois toutes les anomalies de dimensions corrigées. Courbe de guindant de la Grandvoile Dans certains cas, vous aurez dessiné des voiles indépendemment du gréement et défini la courbe du guindant à partir d'observations de celle ci sur un bateau. Il se peut aussi que vous vouliez définir une grand voile qui se monte sur un gréement dont les dimensions sont entrées dans le module gréement de Sailcut. Le cadre Grandvoile permet de calculer la position exacte du point d'amure de la grandvoile, de la têtière, la quête du guidant et sa courbe correspondant au mât. Ces données sont à entrer dans le module voile ou peuvent être utilisées pour vérifier si une voile correspond à un mât. Les seules données à entrer sont hauteur amure = BAD et hauteur têtière = HAD. Sailcut CAD calcule les autres valeurs.
Créer une coque Veuillez noter que ce module n'est pas complètement opérationel, seul un bouchain apparaitra pour toutes les coques. Ce module permet de dessiner un coque à bouchains vifs. On y accède avec l'entrée Coque du menu principal Fichier Nouveau. Contrôle des vues Le contrôle des vues est identiques à celui de l'écran graphique des voiles. Vous pouvez faire tourner la coque avec les curseurs situés au bord de la fenêtre graphique, faire un zoom avec la roulette de la souris, recentrer la vue avec un clic gauche sur un point, afficher la coque en surfaces colorées ou vue fil de fer. Sauvegarder et Charger un fichier de coque L'entrée Sauvegarder du menu Fichier est utilisée pour sauvegarder les données d'une coque. Toute coque qui est sauvegardée peut ensuite être chargée en utilisant l'entrée Ouvrir du menu Fichier et peut être utilisé comme élément constitutif d'un bateau. Dimensions d'une coque Vous pouvez accéder aux dimensions de la coque avec l'onglet Pont et Fond (entrée Dimensions du menu Vue). L'écran est divisé en cadres correspondant au diverses dimensions de la coque. La coque est construite en partant du fond et en montant vers le pont. La ligne la plus importante est le bouchain qui défini le bord extérieur du fond. Les hauteurs sont prises par rapport à un plan horizontal arbitraire souvent placé au point le plus bas du fond. Les angles sont mesurés en degrés par rapport à ce plan horizontal. Coque ID Un texte identifiant ou décrivant la coque est entré dans ce cadre. Pont Hauteur avant Hauteur arrière Fond Longeur Inclinaison de l'étrave Inclinaison du tableau Hauteur avant Angle du bouchain Hauteur arrière Bau maximum Position du bau max Largeur arrière Forme avant Forme arrière Inclinaison du fond Angulation longitudinale du fond Bordé Nombre de bordés Bordage automatique Inclinaison du bordé haut Inclinaison du bordé bas Vérifier et Valider les données Utilisez le bouton Vérifier pour afficher les données auxilliaires et vérifier que les données entrées sont cohérentes avec une géometrie raisonable de la coque. En cas d'anomalie dans les données, la couleur ds caractères douteux vous indique le type d'anomalie. Rouge indique une valeur trop forte, mauve une valeur trop faible et bleu indique les données en relation avec l'anomalie et qui doivent être vérifiées. Une fois que vous avez entré le données, cliquer sur le bouton OK pour fermer l'écran dimensions et afficher le dessin. L'écran dimensions ne se fermera qu'une fois toutes les anomalies de dimensions corrigées. Ajustement des bordés Les bordés peuvent être ajustés individuellement en cliquant l'onglet Bordés de l'écran Dimensions entry of the View menu. L'écran bordés est divisé en zones dans lesquelles les diverses dimensions sont entrées. Hauteur avant Hauteur arrière Inclinaison du bordé Angulation longitudinale Angle du bouchain Créer un bateau Ce module permet d'assembler un bateau virtuel à partir de fichiers de coque, mât et voiles. On y accède avec l'entrée Bateau du menu principal Fichier Nouveau. Contrôle des vues Le contrôle des vues est identiques à celui de l'écran graphique des voiles. Vous pouvez faire tourner le bateau avec les curseurs situés au bord de la fenêtre graphique, faire un zoom avec la roulette de la souris, recentrer la vue avec un clic gauche sur un point, afficher le bateau en surfaces colorées ou vue fil de fer. Ajouter et enlever les éléments d'un bateau L'affichage graphique est initialement noir et on ajoute les fichiers des éléments avec l'entrée Ajouter du menu principal Fichier. Un nouvel onglet apparaitra pour chaque élément ajouté avec les détails du fichier chargé et le texte d'identification donné au moment de la création du fichier (Voile ID, Grément ID, Coque ID). Un élément de bateau peut être enlevé en choisissant l'onglet correspondant et en suite en cliquant sur le bouton Enlever. Sauvegarder et charger un bateau L'entrée Sauvegarder du menu principal Fichier est utilisé pour sauvegarder les données d'un bateau constitué de n'importe quelle combinaison de coque, mât et voiles. Un bateau sauvegarder peut ensuite être chargé avec l'entrée Ouvrir du menu principal Fichier. Déplacer un élément du bateau Chaque élément constitutif sera affiché initialement à la position donnée au moment de la création du fichier correspondant. Veuillez vous souvenir que le point origine des coordonnées X=0, Y=0, Z=0 est placé à l'éxtrémité avant du pont de la coque (étrave). Les éléments peuvent être individuellement déplacés en X, Y or Z en ajustant les spinbox des onglets correspondant, puis en cliquant sur le bouton Mise à jour. A tout instant, un clique sur le bouton Recharger replacera l'élément correspondant à sa position initiale. Modélisation de la surface des voiles dans Sailcut Papier présenté par Robert Lainé au 2ème Workshop Science Voile IRENAV à Brest, France, le 21 mai 2004. Historique Le logiciel de coupe de voile Sailcut a été développé initialement en 1978 en Basic sur un calculateur disposant d'un écran avec une ligne de texte, une petite imprimante à 32 colonnes et seulement 1.6 ko de mémoire vive. D'où la nécessité de faire simple pour modéliser la surface des voiles que je fabriquais et utilisais sur mon ¼ ton IOR. Ce cycle court "conception=>fabrication=>utilisation=>correction" sans contrainte commerciale d'adaptation aux habitudes de travail des voileries m'a permis de converger rapidement sur une modélisation compacte et robuste de la surface des voiles. Plus tard l'utilisation de Sailcut par des voileries a contribué à l'ajout d'interfaces graphiques au noyau Sailcut mais ceci est une autre histoire... Depuis 1993 la version Visual Basic de Sailcut est disponible sur Internet à et depuis 2003, le code source de Sailcut récrit en C++ est disponible à . Pour des raisons de protection de la propriété intellectuelle, le nom Sailcut est déposé mais l'auteur maintient l'accès libre et gratuit au logiciel Sailcut. Problématique de la définition de la surface d'une voile Une voile est une surface complexe que les voileries définissaient historiquement par des notions telles que le creux à différentes hauteurs et la position du creux maximum sur la corde locale. Cette manière de définir la voile par des points de contrôle permet de faire facilement une corrélation visuelle entre le modèle et la voile réelle sur le bateau. Malheureusement par quelques points peuvent passer un grand nombre de surfaces plus ou moins bosselées. Ensuite des notions telles que la pente au bord d'attaque et au bord de fuite furent introduites pour améliorer le contrôle du maître voilier sur la forme du profil de la voile. Ces méthodes menaient à des calculs d'interpolation assez lourds pour trouver le creux en tous points d'une voile, calculs dépassant la capacité des calculateurs personnels d'antan. Dès le début de mes activités sportives en voile, je me suis intéressé à l'aérodynamique de la voile. La lecture du livre Theory of wings sections m'a convaincu que ce qui comptait le plus dans la qualité d'un profil était la répartition de la courbure le long du profil. La définition d'un profil par son creux maximum, la position du creux et des segments de fonctions quadratiques ou cubiques me semblait suspecte. Plutôt que de chercher à reproduire des voiles existantes, j'ai cherché à produire une loi de courbure raisonnablement aérodynamique sur toute la surface de la voile. La première approche a été de modéliser directement la courbure mais cela nécessitait de traiter simultanément les dérivées premières et secondes en tous points et donc trop de calculs pour mon petit ordinateur. Navigant à l'époque en mer du Nord dans des conditions assez musclées pour mon ¼ ton, un de mes objectifs était d'obtenir une forme de profil ayant un pic de pression avancé pour combattre la tendance du creux à reculer quand le vent augmente. J'ai finalement choisi une équation définissant la dérivée seconde du profil et me donnant une évolution continue de celle-ci et contrôlée par seulement deux paramètres. Le système de coordonnées choisi est tel que le plan X-Y contient le point d'amure, le point d'écoute et la tête du guindant. L'axe X est horizontal du point d'amure vers le point d'écoute, l'axe Y est vertical vers le haut et l'axe Z transverse au plan X-Y. Les profils sont définis comme l'intersection de la surface de la voile avec un plan horizontal Y-Z. Le Z d'un point d'un profil donné est donc une fonction de l'abscisse X normalisée par rapport à la longueur de la corde locale comme montré dans .
Système de coordonnées de Sailcut
L'équation retenue pour décrire la dérivée seconde du profil est: Z'' = K * ( -A * (1 - X)^AV - AR * X) Ce qui donne par intégration la pente du profil : Z' = K * ( A * (1 - X)^(AV + 1) / (AV +1) - AR/2 * X^2 + C ) Et enfin le profil après une seconde intégration : Z = K * ( -A * (1 - X)^(AV + 2) / (( AV + 2) * (AV +1)) - AR/6 * X^3 + C * X + B ) Pour satisfaire les conditions (X=0, Z=0) et (X=1, Z=0) on prend : B = A / ((AV + 2) * (AV + 1)) C = AR / 6 - B Le maximum de Z est trouvé quand Z' = 0, ce qui permet ensuite de calculer K pour que ce Z maximum soit celui souhaité (creux du profil). Les coefficients AV et AR donnent une mesure de la courbure au bord d'attaque et au bord de fuite. Avec le creux maximum, ces deux coefficients suffisent pour décrire le profil de la voile à toutes les hauteurs. Le coefficient A définit différentes familles de profils avec un bord d'attaque plus ou moins rond. En pratique A = 1 donne de bons profils pour toutes les voiles navigant dans des conditions de vent moyen ou faible. Personnellement je préfère avoir un bord d'attaque plus plein et j'utilise A = 1 + AV / 4. Ce coefficient est celui utilisé dans le code de Sailcut et il donne des voiles polyvalentes. Le tableau ci dessous donne un exemple de profil obtenu avec la formulation ci dessus. AV = 5.00 AR = 0.02 K = 2.94 A = 2.25 B = 0.054 C =-0.050 curvature = z" / (1+ z'*z')^3/2 xz" z' z curvature 0.0 -6.615 0.955 0.00 -2.503 0.1 -3.912 0.438 0.0674 -3.007 0.2 -2.179 0.140 0.0949 -2.117 0.3 -1.129 -0.021 0.100 -1.129 0.4 -0.538 -0.101 0.0934 -0.530 0.5 -0.236 -0.138 0.0812 -0.230 0.6 -0.103 -0.154 0.0665 -0.099 0.7 -0.057 -0.161 0.0507 -0.055 0.8 -0.049 -0.166 0.0343 -0.047 0.9 -0.053 -0.172 0.0174 -0.051 1.0 -0.059 -0.177 0.00 -0.056 Ayant défini une formulation simple pour les profils, il suffit de faire varier les valeurs du creux et des coefficients AV et AR en fonction de la hauteur du profil dans la voile. Pour la bordure qui est un arc de cercle, les coefficients AV et AR sont nuls et seul le creux est défini par l'utilisateur. Un profil dit de creux maximum est positionné autour de la ½ hauteur de la voile et les valeurs de AV et AR sont ajustées par l'utilisateur pour obtenir la forme désirée. Le profil haut de la voile est défini de la même manière. Pour tout autre profil intermédiaire la valeur du creux est interpolée par une fonction parabolique et la valeur des coefficients AV et AR est interpolée linéairement entre celles des profils de référence. Au total on utilise 3 valeurs de creux, la position verticale du creux maximum, et 2 paires de coefficients (AV,AR) pour définir le moule de la voile. Notez que dans le logiciel Sailcut, la valeur affichée pour le coefficiend de forme du guidant est directement le coefficient AV alors que pour la chute la valeur affichée est 50 fois le coefficient AV des équations ci-dessus, ceci afin que les utilisateurs travaillent avec des chiffres plus simples que des valeurs à la deuxième ou troisième décimales. Autres aspects de la modélisation Le moule ci dessus ne suffit pas pour faire une vraie voile. En effet les bords d'une voile sont rarement droits et de plus la voile présente un certain vrillage des profils entre le haut et le bas. Pour définir la forme des bords j'utilise maintenant une formulation avec un point représentant le rond maximum du bord, c'est à dire l'écart maximum du bord réel par rapport à la ligne droite joignant les coins adjacents, et deux arcs de parabole qui joignent le point de rond maximum aux coins de la voile. Les profils s'appuient sur ces bords de la voile. Le vrillage de la voile est obtenu par une rotation des profils autour de leur extrémité coté guindant. L'angle de rotation est proportionnel à la hauteur du profil. Il est à noter que cette méthode de modélisation de la surface des voiles permet de construire une voile ayant une forme sans bosses ou méplats, ni possibilité d'inversion de cambrure des profils, ceci avec peu de paramètres et des calculs simples. La méthode est applicable aussi bien aux voiles triangulaires qu'aux voiles à quatre cotés et Sailcut est utilisé régulièrement pour des vieux gréements.
Plus d'informations sur Sailcut CAD TODO Formats de fichiers de Sailcut CAD Text representation of developed sail TODO Text representation of 3D sail TODO XML representation of a sail Copyright Copyright (C) Robert Lainé & Jeremy Lainé. Sailcut est une marque déposée par Robert Lainé. Ce logiciel est libre; vous pouvez le redistribuer et le modifier selon les termes de la licence GNU General Public Licence telle que publiée par la Free Software Fondation version 2 ou autre version plus récente. Voyez pour les termes de cette licence. Ce logiciel est distribué avec l'éspoir qu'il vous soit utile mais SANS AUCUNE GARANTIE même implicite quand son utilisation. Voyez les termes de la licence GNU pour plus de détail. Vous devriez avoir une copie de la licence GNU General Public Licence avec ce logiciel, si ce n'est pas le cas demandez la à Free Software Fondation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Les auteurs apprécieraient que les publications sur des voiles conçues avec Sailcut comportent une reconnaissance de leur travail. Merci par avance.
sailcut-1.5.0/doc/fr/model-sailcut-fr.pdf000066400000000000000000011262451477005247400202240ustar00rootroot00000000000000%PDF-1.4 % 1 0 obj << /Length 2 0 R >> stream 0 w q 0 -0.1 612.1 792.1 re W* n q 0 0 0 rg BT 187.4 711 Td /F1 10 Tf <01> Tj 8.4 0 Td <02> Tj 6.1 0 Td <0304> Tj 11.7 0 Td <05> Tj 2.8 0 Td <06> Tj 2.7 0 Td <07> Tj 5.6 0 Td <08> Tj 5.6 0 Td <09> Tj 3.3 0 Td <06> Tj 2.8 0 Td <020A> Tj 12.2 0 Td <0B> Tj 2.8 0 Td <030C> Tj 11.6 0 Td <0B> Tj 2.8 0 Td <05> Tj 2.7 0 Td <08> Tj 5.6 0 Td <0B> Tj 2.7 0 Td <07> Tj 5.6 0 Td <0D> Tj 6 0 Td <0E0F> Tj 7.2 0 Td <08> Tj 5.5 0 Td <10> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <0B> Tj 2.8 0 Td <03> Tj 6 0 Td <0C> Tj 5.6 0 Td <07> Tj 5.5 0 Td <0B> Tj 2.8 0 Td <11> Tj 5.6 0 Td <0206> Tj 8.8 0 Td <05> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <07> Tj 5.6 0 Td <0B> Tj 2.8 0 Td <0308> Tj 11.6 0 Td <0A> Tj 6.1 0 Td <07> Tj 5.6 0 Td <0B> Tj 2.7 0 Td <12> Tj 6.7 0 Td <08> Tj 5.5 0 Td <06> Tj 2.7 0 Td <05> Tj 2.7 0 Td <10> Tj 5.6 0 Td <0D> Tj 6.1 0 Td <09> Tj ET Q q 0 0 0 rg BT 218 688.7 Td /F2 10 Tf <01> Tj 7.2 0 Td <02> Tj 5.5 0 Td <03> Tj 5.5 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <08> Tj 5.5 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0D> Tj ET Q q 0 0 1 rg BT 281 688.7 Td /F2 10 Tf <05> Tj 3.4 0 Td <02> Tj 5.4 0 Td <03> Tj 5.5 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <06> Tj 2.8 0 Td <0E> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <1011> Tj 15.1 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <12> Tj 5 0 Td <13> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0E> Tj 2.8 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <14> Tj ET Q q 1 0 0 1 281 688.7 cm 0.6 w 0 0 1 RG 0 -0.8 m 109.8 -0.8 l S Q q 0 0 0 rg BT 390.8 688.7 Td /F2 10 Tf <15> Tj ET Q q 0 0 0 rg BT 304.7 677.5 Td /F2 10 Tf <07> Tj ET Q q 0 0 0 rg BT 194.5 666.4 Td /F2 10 Tf <16> Tj 6.7 0 Td <09> Tj 5.4 0 Td <17> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <05> Tj 3.4 0 Td <0C> Tj 5.5 0 Td <11> Tj 5 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.7 0 Td <09> Tj 5.6 0 Td <13> Tj 5.5 0 Td <07> Tj 2.7 0 Td <18> Tj 5.6 0 Td <19> Tj 5.5 0 Td <14> Tj 8.4 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <1A> Tj 9.5 0 Td <02> Tj 5.7 0 Td <05> Tj 3.4 0 Td <1B> Tj 5.1 0 Td <11> Tj 5.1 0 Td <1C> Tj 5.5 0 Td <02> Tj 5.6 0 Td <17> Tj 5.7 0 Td <07> Tj 2.7 0 Td <1D> Tj 6.7 0 Td <12> Tj 4.9 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <12> Tj 4.9 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <1E> Tj 6.6 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj ET Q q 0 0 0 rg BT 224.7 655.2 Td /F2 10 Tf <1F> Tj 2.8 0 Td <01> Tj 7.1 0 Td <20> Tj 6.6 0 Td <21> Tj 7.2 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.6 0 Td <23> Tj 2.8 0 Td <07> Tj 2.8 0 Td <24> Tj 6.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <06> Tj 2.7 0 Td <23> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2505> Tj 9.4 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <12> Tj 5 0 Td <04> Tj 5.5 0 Td <23> Tj 2.8 0 Td <07> Tj 2.8 0 Td <18> Tj 5.5 0 Td <26> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.3 0 Td <07> Tj 2.7 0 Td <18> Tj 5.5 0 Td <27> Tj 5.5 0 Td <27> Tj 5.6 0 Td <28> Tj ET Q q 0 0 0 rg BT 286.7 610.6 Td /F1 10 Tf <13> Tj 7.2 0 Td <04> Tj 5.5 0 Td <07> Tj 5.5 0 Td <0D14> Tj 15 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 588.3 Td /F2 10 Tf <29> Tj 7.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <09> Tj 5.5 0 Td <17> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <12> Tj 5 0 Td <05> Tj 3.4 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.6 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <19> Tj 5.6 0 Td <05> Tj 3.2 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <1113> Tj 10.6 0 Td <05> Tj 3.3 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.5 0 Td <1204> Tj 10.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <02> Tj 5.6 0 Td <2A> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 4.9 0 Td <0C> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <0A> Tj 2.1 0 Td <04> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <07> Tj 2.8 0 Td <1D> Tj 6.7 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.8 0 Td <29> Tj 7.2 0 Td <04> Tj 5.5 0 Td <06> Tj 2.7 0 Td <06> Tj 2.8 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 577.2 Td /F2 10 Tf <14> Tj 8.4 0 Td <02> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <09> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <2E> Tj 4.9 0 Td <06> Tj 2.6 0 Td <0A> Tj 2.2 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <17> Tj 5.5 0 Td <02> Tj 5.6 0 Td <11> Tj 5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <30> Tj 1.8 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <30> Tj 1.9 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <12> Tj 5 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj ET Q q 0 0 0 rg BT 90 566 Td /F2 10 Tf <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.7 0 Td <08> Tj 5.6 0 Td <30> Tj 1.8 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <05> Tj 3.4 0 Td <31> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <3013> Tj 7.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <02> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <09> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <11> Tj 4.9 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.6 0 Td <12> Tj 5 0 Td <04> Tj 5.7 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <06> Tj 2.8 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 554.9 Td /F2 10 Tf <1205> Tj 8.4 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <06> Tj 2.8 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <1106> Tj 7.7 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <14> Tj 8.4 0 Td <17> Tj 5.5 0 Td <0F> Tj 2.3 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <33> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <34> Tj 9.4 0 Td <13> Tj 5.5 0 Td <2C> Tj 5 0 Td <05> Tj 3.2 0 Td <04> Tj 5.6 0 Td <23> Tj 2.7 0 Td <07> Tj 2.8 0 Td <06> Tj 2.7 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2D> Tj 5.5 0 Td <09> Tj 5.5 0 Td <05> Tj 3.4 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <11> Tj 5.1 0 Td <11> Tj 5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <03> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 543.7 Td /F2 10 Tf <2B> Tj 2.8 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <08> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <12> Tj 4.9 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <1D> Tj 6.6 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <12> Tj 4.9 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <12> Tj 4.9 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <29> Tj 7.2 0 Td <35> Tj 5.8 0 Td <35> Tj 5.7 0 Td <07> Tj 2.8 0 Td <11> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <1117> Tj 10.5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <03> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 532.6 Td /F2 10 Tf <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <1204> Tj 10.5 0 Td <0B> Tj 5.6 0 Td <12> Tj 4.9 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <36> Tj 7.8 0 Td <0B> Tj 5.5 0 Td <13> Tj 5.6 0 Td <36> Tj 7.7 0 Td <16> Tj 6.7 0 Td <08> Tj 5.5 0 Td <0E> Tj 2.8 0 Td <07> Tj ET Q q 0 0 0 rg BT 276.9 488 Td /F1 10 Tf <15> Tj 2.8 0 Td <0A> Tj 6.1 0 Td <09> Tj 3.3 0 Td <0E02030D> Tj 22.2 0 Td <10> Tj 5.5 0 Td <09> Tj 3.3 0 Td <06> Tj 2.8 0 Td <020A> Tj ET Q q 0 0 0 rg BT 90 465.7 Td /F2 10 Tf <08> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <1202> Tj 10.6 0 Td <13> Tj 5.5 0 Td <17> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.4 0 Td <07> Tj 2.8 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <1D> Tj 6.7 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <0C> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <2C> Tj 5 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <17> Tj 5.5 0 Td <17> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <14> Tj 8.3 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <26> Tj 5.5 0 Td <37> Tj 5.5 0 Td <38> Tj 5.6 0 Td <39> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <24> Tj 6.6 0 Td <09> Tj 5.5 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj ET Q q 0 0 0 rg BT 90 454.5 Td /F2 10 Tf <12> Tj 5 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <11> Tj 5 0 Td <17> Tj 5.5 0 Td <02> Tj 5.6 0 Td <11> Tj 5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <3013> Tj 7.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <12> Tj 5 0 Td <05> Tj 3.4 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.5 0 Td <12> Tj 5.1 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.1 0 Td <2D> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.4 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <3206> Tj 7.7 0 Td <04> Tj 5.6 0 Td <23> Tj 2.8 0 Td <07> Tj 2.7 0 Td <13> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <14> Tj 8.4 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.3 0 Td <14> Tj 8.3 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <33> Tj 5.5 0 Td <07> Tj 2.7 0 Td <3A> Tj 5.5 0 Td <18> Tj 5.6 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <04> Tj 5.6 0 Td <06> Tj ET Q q 0 0 0 rg BT 90 443.4 Td /F2 10 Tf <11> Tj 5 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <14> Tj 8.4 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <26> Tj 5.5 0 Td <0E> Tj 2.7 0 Td <3B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <1B02> Tj 10.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <0C> Tj 5.6 0 Td <14> Tj 8.3 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.4 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <0A> Tj 2.2 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <3C> Tj 7.2 0 Td <30> Tj 1.9 0 Td <02> Tj 5.5 0 Td <3D> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <0B> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <12> Tj 5 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <110A> Tj 7.3 0 Td <06> Tj 2.7 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <110A> Tj 7.2 0 Td <14> Tj 8.4 0 Td <17> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <02> Tj 5.5 0 Td <2A> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <04> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.5 0 Td <12> Tj 5 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 432.2 Td /F2 10 Tf <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.7 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <3E> Tj 2.2 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.6 0 Td <03> Tj 5.5 0 Td <05> Tj 3.4 0 Td <0A> Tj 2.1 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <13> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.8 0 Td <3F> Tj 8.3 0 Td <07> Tj 2.7 0 Td <06> Tj 2.8 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <1F> Tj 2.8 0 Td <40> Tj 7.7 0 Td <01> Tj 7.2 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.8 0 Td <29> Tj 7.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <2E> Tj 5 0 Td <12> Tj 4.9 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.4 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <1202> Tj 10.6 0 Td <0B> Tj 5.5 0 Td <12> Tj 5 0 Td <04> Tj 5.5 0 Td <17> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <41> Tj 3.4 0 Td <42> Tj ET Q q 0 0 0 rg BT 90 421.1 Td /F2 10 Tf <2B> Tj 2.8 0 Td <09> Tj 5.6 0 Td <03> Tj 5.5 0 Td <05> Tj 3.4 0 Td <0A> Tj 2.2 0 Td <12> Tj 4.9 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <41> Tj 3.4 0 Td <42> Tj 5.8 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.8 0 Td <41> Tj 3.3 0 Td <42> Tj 5.8 0 Td <07> Tj 2.7 0 Td <12> Tj 5.1 0 Td <02> Tj 5.5 0 Td <05> Tj 3.3 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <12> Tj 5.1 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <05> Tj 3.4 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <43> Tj 3.5 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <14> Tj 8.4 0 Td <14> Tj 8.4 0 Td <04> Tj 5.6 0 Td <05> Tj 3.4 0 Td <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <4307> Tj 6.3 0 Td <2A> Tj 5.6 0 Td <30> Tj 1.8 0 Td <09> Tj 5.5 0 Td <2A> Tj 5.6 0 Td <09> Tj 5.5 0 Td <17> Tj 5.5 0 Td <06> Tj 2.8 0 Td <09> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <09> Tj 5.5 0 Td <13> Tj 5.6 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <09> Tj 5.5 0 Td <03> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <13> Tj 5.5 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 409.9 Td /F2 10 Tf <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <2C> Tj 4.9 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <05> Tj 3.2 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <14> Tj 8.4 0 Td <3009> Tj 7.6 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <0A> Tj 2.2 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.6 0 Td <05> Tj 3.2 0 Td <2D> Tj 5.6 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <17> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <14> Tj 8.4 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <11> Tj 4.9 0 Td <13> Tj 5.6 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <02> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <09> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <14> Tj 8.4 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <12> Tj 5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <06> Tj ET Q q 0 0 0 rg BT 90 398.8 Td /F2 10 Tf <05> Tj 3.4 0 Td <02> Tj 5.5 0 Td <03> Tj 5.5 0 Td <13> Tj 5.6 0 Td <1106> Tj 7.7 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.6 0 Td <12> Tj 5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <1107> Tj 7.7 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <11> Tj 4.9 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.8 0 Td <16> Tj 6.6 0 Td <0F> Tj 2.2 0 Td <13> Tj 5.5 0 Td <1107> Tj 7.8 0 Td <06> Tj 2.7 0 Td <09> Tj 5.6 0 Td <05> Tj 3.2 0 Td <2A> Tj 5.6 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <30> Tj 1.8 0 Td <13> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <0A> Tj 2.3 0 Td <11> Tj 4.9 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <1D> Tj 6.7 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <09> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <05> Tj 3.2 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <09> Tj 5.6 0 Td <07> Tj 2.7 0 Td <1202> Tj 10.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <05> Tj 3.2 0 Td <0A> Tj 2.3 0 Td <03> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <07> Tj 2.8 0 Td <33> Tj ET Q q 0 0 0 rg BT 90 387.6 Td /F2 10 Tf <0F> Tj 2.2 0 Td <30> Tj 1.9 0 Td <09> Tj 5.5 0 Td <3E> Tj 2.3 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <30> Tj 1.9 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.5 0 Td <12> Tj 5.1 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.8 0 Td <2D> Tj 5.5 0 Td <05> Tj 3.3 0 Td <09> Tj 5.6 0 Td <17> Tj 5.5 0 Td <1C> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <09> Tj 5.6 0 Td <13> Tj 5.5 0 Td <07> Tj 2.7 0 Td <0B> Tj 5.5 0 Td <02> Tj 5.5 0 Td <2E> Tj 4.9 0 Td <09> Tj 5.5 0 Td <13> Tj 5.4 0 Td <07> Tj 2.8 0 Td <1D> Tj 6.6 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <12> Tj 4.9 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5.1 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <04> Tj 5.6 0 Td <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.8 0 Td <04> Tj 5.6 0 Td <11> Tj 4.9 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <1C> Tj 5.5 0 Td <0A> Tj 2.3 0 Td <11> Tj 5 0 Td <06> Tj 2.7 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.8 0 Td <0E> Tj 2.8 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.7 0 Td <07> Tj 2.8 0 Td <3C> Tj 7.2 0 Td <04> Tj 5.5 0 Td <17> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <26> Tj 5.5 0 Td <37> Tj 5.6 0 Td <37> Tj 5.5 0 Td <3A> Tj 5.5 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj ET Q q 0 0 0 rg BT 90 376.5 Td /F2 10 Tf <2C> Tj 5 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <110A> Tj 7.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <1E> Tj 6.6 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <24> Tj 6.6 0 Td <09> Tj 5.5 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.4 0 Td <07> Tj 2.8 0 Td <1D> Tj 6.7 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <1106> Tj 7.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <03> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <1F> Tj 2.7 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <0B> Tj 5.6 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <0D> Tj 3.3 0 Td <1C> Tj 5.5 0 Td <06> Tj 2.8 0 Td <06> Tj 2.7 0 Td <17> Tj 5.5 0 Td <44> Tj 2.8 0 Td <45> Tj 2.8 0 Td <45> Tj 2.7 0 Td <46> Tj 7.2 0 Td <46> Tj 7.1 0 Td <46> Tj 7.1 0 Td <0E> Tj 2.8 0 Td <11> Tj 4.9 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <12> Tj 4.9 0 Td <13> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0E> Tj 2.8 0 Td <1202> Tj 10.6 0 Td <14> Tj 8.4 0 Td <15> Tj 3.5 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <17> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <18> Tj 5.6 0 Td <27> Tj 5.5 0 Td <27> Tj 5.5 0 Td <3A> Tj 5.5 0 Td <23> Tj ET Q q 0 0 0 rg BT 90 365.3 Td /F2 10 Tf <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <1102> Tj 10.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <12> Tj 5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <1D> Tj 6.6 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <12> Tj 4.9 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <0C> Tj 5.6 0 Td <12> Tj 5 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <29> Tj 7.1 0 Td <35> Tj 5.8 0 Td <35> Tj 5.8 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <11> Tj 5 0 Td <17> Tj 5.5 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <03> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <33> Tj 5.5 0 Td <07> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <06> Tj 2.8 0 Td <06> Tj 2.7 0 Td <17> Tj 5.5 0 Td <44> Tj 2.8 0 Td <45> Tj 2.7 0 Td <45> Tj 2.8 0 Td <11> Tj 5 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <12> Tj 5 0 Td <13> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0E> Tj 2.8 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <12> Tj 5 0 Td <04> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.5 0 Td <05> Tj 3.4 0 Td <2D> Tj 5.5 0 Td <04> Tj 5.6 0 Td <0E> Tj 2.7 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.8 0 Td <16> Tj 6.6 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 354.2 Td /F2 10 Tf <05> Tj 3.4 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <1206> Tj 7.8 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.1 0 Td <0C> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <1206> Tj 7.8 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <23> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0B> Tj 5.5 0 Td <02> Tj 5.5 0 Td <14> Tj 8.5 0 Td <07> Tj 2.8 0 Td <1D> Tj 6.6 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <12> Tj 4.9 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <17> Tj 5.5 0 Td <02> Tj 5.6 0 Td <11> Tj 4.9 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <11> Tj 5.1 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <30> Tj 1.8 0 Td <09> Tj 5.6 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj ET Q q 0 0 0 rg BT 90 343 Td /F2 10 Tf <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <30> Tj 1.9 0 Td <09> Tj 5.6 0 Td <12> Tj 5 0 Td <12> Tj 5 0 Td <19> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <03> Tj 5.5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2D> Tj 5.6 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <09> Tj 5.6 0 Td <13> Tj 5.4 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <0A> Tj 2.1 0 Td <04> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <07> Tj 2.8 0 Td <1D> Tj 6.6 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <12> Tj 4.9 0 Td <13> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0E> Tj 2.8 0 Td <07> Tj ET Q q 0 0 0 rg BT 175.7 298.4 Td /F1 10 Tf <16> Tj 6.7 0 Td <0E> Tj 3.8 0 Td <02> Tj 6.1 0 Td <1705> Tj 8.8 0 Td <04> Tj 5.6 0 Td <14> Tj 8.8 0 Td <08> Tj 5.6 0 Td <09> Tj 3.3 0 Td <06> Tj 2.8 0 Td <180D> Tj 12.2 0 Td <0C> Tj 5.6 0 Td <0B> Tj 2.7 0 Td <03> Tj 6.1 0 Td <0C> Tj 5.6 0 Td <0B> Tj 2.7 0 Td <05> Tj 2.7 0 Td <08> Tj 5.6 0 Td <0B> Tj 2.8 0 Td <0304> Tj 11.6 0 Td <0F> Tj 3.3 0 Td <06> Tj 2.8 0 Td <0A> Tj 6.1 0 Td <06> Tj 2.8 0 Td <09> Tj 3.3 0 Td <06> Tj 2.8 0 Td <020A> Tj 12.3 0 Td <0B> Tj 2.7 0 Td <03> Tj 6.1 0 Td <0C> Tj 5.6 0 Td <0B> Tj 2.7 0 Td <05> Tj 2.7 0 Td <08> Tj 5.6 0 Td <0B> Tj 2.8 0 Td <07> Tj 5.5 0 Td <0D0E0F> Tj 13.3 0 Td <08> Tj 5.5 0 Td <10> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <0B> Tj 2.7 0 Td <03> Tj 6.1 0 Td <19> Tj 2.4 0 Td <0D0A> Tj 12.2 0 Td <0C> Tj 5.6 0 Td <0B> Tj 2.8 0 Td <11> Tj 5.6 0 Td <02> Tj 6.1 0 Td <06> Tj 2.7 0 Td <05> Tj 2.8 0 Td <0C> Tj ET Q q 0 0 0 rg BT 90 276.1 Td /F2 10 Tf <47> Tj 7.2 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <2B> Tj 2.7 0 Td <09> Tj 5.6 0 Td <12> Tj 5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <14> Tj 8.3 0 Td <17> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <3204> Tj 10.5 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <1109> Tj 10.5 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <06> Tj 2.7 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.2 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.6 0 Td <14> Tj 8.4 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <09> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <1107> Tj 7.8 0 Td <0B> Tj 5.5 0 Td <02> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 265 Td /F2 10 Tf <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <32> Tj 5 0 Td <07> Tj 2.7 0 Td <33> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.3 0 Td <2B> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <0C> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <09> Tj 5.5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <1205> Tj 8.4 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <09> Tj 5.6 0 Td <320A> Tj 7.3 0 Td <14> Tj 8.3 0 Td <13> Tj 5.6 0 Td <14> Tj 8.7 0 Td <07> Tj 2.7 0 Td <1113> Tj 10.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <12> Tj 4.9 0 Td <09> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <0E> Tj ET Q q 0 0 0 rg BT 90 253.8 Td /F2 10 Tf <29> Tj 7.2 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <19> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <05> Tj 3.3 0 Td <48> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <04> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2B> Tj 2.7 0 Td <09> Tj 5.6 0 Td <120A> Tj 7.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <14> Tj 8.3 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 242.7 Td /F2 10 Tf <12> Tj 5 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <05> Tj 3.3 0 Td <0C> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <0A> Tj 2.1 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <02> Tj 5.5 0 Td <2A> Tj 5.6 0 Td <19> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.4 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <0C> Tj 5.6 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <03> Tj 5.5 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <09> Tj 5.5 0 Td <13> Tj 5.6 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <49> Tj 8.3 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <1C> Tj 5.5 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <11> Tj 5 0 Td <04> Tj 5.6 0 Td <14> Tj 8.4 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <09> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 231.5 Td /F2 10 Tf <17> Tj 5.5 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <2C> Tj 5 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <11> Tj 5 0 Td <1104> Tj 10.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <13> Tj 5.6 0 Td <0B> Tj 5.4 0 Td <07> Tj 2.8 0 Td <2D> Tj 5.6 0 Td <05> Tj 3.2 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0B> Tj 5.5 0 Td <02> Tj 5.6 0 Td <14> Tj 8.4 0 Td <03> Tj 5.5 0 Td <05> Tj 3.4 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <1113> Tj 10.6 0 Td <05> Tj 3.3 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.5 0 Td <12> Tj 5.1 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <13> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <02> Tj 5.6 0 Td <13> Tj 5.4 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <03> Tj 5.5 0 Td <02> Tj 5.6 0 Td <11> Tj 5 0 Td <11> Tj 5 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.7 0 Td <20> Tj 6.7 0 Td <0B> Tj 5.5 0 Td <1113> Tj 10.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 220.4 Td /F2 10 Tf <0B> Tj 5.5 0 Td <02> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.6 0 Td <13> Tj 5.4 0 Td <07> Tj 2.8 0 Td <03> Tj 5.6 0 Td <02> Tj 5.5 0 Td <05> Tj 3.3 0 Td <2A> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <30> Tj 1.9 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <06> Tj 2.7 0 Td <09> Tj 5.5 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <09> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <03> Tj 5.5 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <2A> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <13> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <06> Tj 2.8 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2A> Tj 5.6 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <17> Tj 5.6 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <09> Tj 5.6 0 Td <14> Tj 8.4 0 Td <0C> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <05> Tj ET Q q 0 0 0 rg BT 90 209.2 Td /F2 10 Tf <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <48> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <09> Tj 5.5 0 Td <4A> Tj 2.8 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <04> Tj 5.7 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.4 0 Td <07> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.6 0 Td <05> Tj 3.4 0 Td <14> Tj 8.3 0 Td <04> Tj 5.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.3 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.3 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <29> Tj 7.1 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <0C> Tj 5.5 0 Td <06> Tj 2.8 0 Td <1C> Tj 5.6 0 Td <02> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <33> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 198.1 Td /F2 10 Tf <12> Tj 5 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.3 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <30> Tj 1.9 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <11> Tj 5 0 Td <1104> Tj 10.5 0 Td <4B> Tj 4.9 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <2A> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <2C> Tj 5 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <06> Tj 2.7 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <3013> Tj 7.4 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <23> Tj 2.8 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <09> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <12> Tj 4.9 0 Td <13> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 186.9 Td /F2 10 Tf <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <17> Tj 5.5 0 Td <09> Tj 5.5 0 Td <11> Tj 5 0 Td <11> Tj 5.1 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <09> Tj 5.5 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <12> Tj 5 0 Td <0A> Tj 2.1 0 Td <06> Tj 2.8 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <1107> Tj 7.8 0 Td <12> Tj 5 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <30> Tj 1.9 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.8 0 Td <07> Tj 2.7 0 Td <07> Tj 2.8 0 Td <07> Tj 2.7 0 Td <07> Tj 2.8 0 Td <07> Tj ET Q q 0 0 0 rg BT 90 164.6 Td /F2 10 Tf <3C> Tj 7.2 0 Td <19> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <03> Tj 5.5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <04> Tj 5.5 0 Td <11> Tj 5.2 0 Td <07> Tj 2.7 0 Td <09> Tj 5.6 0 Td <12> Tj 4.9 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <2C> Tj 4.9 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <0C> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <17> Tj 5.5 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <23> Tj 2.7 0 Td <07> Tj 2.8 0 Td <3E> Tj 2.2 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <11> Tj 5 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.7 0 Td <33> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <30> Tj 1.9 0 Td <09> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <05> Tj 3.4 0 Td <02> Tj 5.5 0 Td <2A> Tj 5.4 0 Td <2E> Tj 4.9 0 Td <0B> Tj 5.6 0 Td <09> Tj 5.5 0 Td <14> Tj 8.3 0 Td <0A> Tj 2.2 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj ET Q q 0 0 0 rg BT 90 153.5 Td /F2 10 Tf <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.7 0 Td <08> Tj 5.6 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <12> Tj 5 0 Td <06> Tj 2.8 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <0A> Tj 2.2 0 Td <2C> Tj 4.9 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <434C> Tj 9.7 0 Td <1C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <02> Tj 5.5 0 Td <05> Tj 3.2 0 Td <2E> Tj 4.9 0 Td <07> Tj 2.7 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <07> Tj 2.8 0 Td <46> Tj 7.2 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <1107> Tj 7.8 0 Td <11> Tj 5 0 Td <04> Tj 5.5 0 Td <1206> Tj 7.8 0 Td <0A> Tj 2.1 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <11> Tj 5 0 Td <4307> Tj 6.3 0 Td <14> Tj 8.4 0 Td <3009> Tj 7.6 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <2C> Tj 4.9 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.6 0 Td <12> Tj 4.9 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <14> Tj 8.4 0 Td <17> Tj 5.5 0 Td <06> Tj 2.8 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <13> Tj 5.6 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 142.3 Td /F2 10 Tf <2A> Tj 5.5 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <09> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <30> Tj 1.8 0 Td <13> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <05> Tj 3.2 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.3 0 Td <07> Tj 2.7 0 Td <0C> Tj 5.6 0 Td <06> Tj 2.7 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <0C> Tj 5.5 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <1202> Tj 10.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <03> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.3 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.8 0 Td <08> Tj 5.5 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.3 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <30> Tj 1.9 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.4 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj ET Q q 0 0 0 rg BT 90 131.2 Td /F2 10 Tf <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <1205> Tj 8.4 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <09> Tj 5.6 0 Td <320A> Tj 7.2 0 Td <14> Tj 8.4 0 Td <13> Tj 5.6 0 Td <14> Tj 8.4 0 Td <23> Tj 3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <02> Tj 5.5 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.1 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <32> Tj 5.1 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <04> Tj 5.5 0 Td <2D> Tj 5.6 0 Td <14> Tj 8.4 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <12> Tj 5.1 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.1 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <09> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <05> Tj 3.3 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <02> Tj 5.5 0 Td <13> Tj ET Q q 0 0 0 rg BT 90 120 Td /F2 10 Tf <12> Tj 5 0 Td <13> Tj 5.6 0 Td <03> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <04> Tj 5.6 0 Td <14> Tj 8.4 0 Td <03> Tj 5.5 0 Td <0F> Tj 2.3 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <11> Tj 5 0 Td <17> Tj 5.5 0 Td <04> Tj 5.6 0 Td <1206> Tj 7.7 0 Td <04> Tj 5.6 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.8 0 Td <07> Tj 2.7 0 Td <16> Tj 6.7 0 Td <0F> Tj 2.1 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <48> Tj 5.5 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <121C> Tj 10.6 0 Td <04> Tj 5.5 0 Td <05> Tj 3.4 0 Td <12> Tj 4.9 0 Td <1C> Tj 5.6 0 Td <04> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.8 0 Td <33> Tj 5.5 0 Td <07> Tj 2.7 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <17> Tj 5.5 0 Td <05> Tj 3.4 0 Td <02> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.3 0 Td <05> Tj 3.2 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <320A> Tj 7.2 0 Td <1106> Tj 7.8 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <23> Tj 2.7 0 Td <07> Tj 2.8 0 Td <3E> Tj 2.2 0 Td <3009> Tj 7.5 0 Td <0A> Tj ET Q q 0 0 0 rg BT 90 108.9 Td /F2 10 Tf <12> Tj 5 0 Td <1C> Tj 5.6 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <12> Tj 5.1 0 Td <1C> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <07> Tj 2.8 0 Td <33> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.3 0 Td <02> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <03> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <05> Tj 3.2 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <09> Tj 5.5 0 Td <03> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <14> Tj 8.4 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <09> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2A> Tj 5.4 0 Td <2E> Tj 4.9 0 Td <0B> Tj 5.5 0 Td <09> Tj 5.6 0 Td <14> Tj 8.3 0 Td <0A> Tj 2.2 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <06> Tj 2.8 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.6 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.5 0 Td <1204> Tj 10.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj ET Q q 0 0 0 rg BT 90 97.7 Td /F2 10 Tf <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.7 0 Td <08> Tj 5.6 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <14> Tj 8.3 0 Td <0A> Tj 2.2 0 Td <19> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <17> Tj 5.5 0 Td <17> Tj 5.5 0 Td <05> Tj 3.4 0 Td <02> Tj 5.5 0 Td <12> Tj 5 0 Td <1C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <09> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0C> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <02> Tj 5.6 0 Td <2A> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <04> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <1206> Tj 7.8 0 Td <04> Tj 5.6 0 Td <14> Tj 8.3 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <03> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <11> Tj 5.1 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0B> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <12> Tj 4.9 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.8 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 86.6 Td /F2 10 Tf <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <110A> Tj 7.2 0 Td <14> Tj 8.4 0 Td <13> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <06> Tj 2.8 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <14> Tj 8.3 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.2 0 Td <2C> Tj 4.9 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <14> Tj 8.4 0 Td <0A> Tj 2.2 0 Td <19> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <04> Tj 5.6 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <06> Tj 2.7 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <12> Tj 5 0 Td <07> Tj 2.8 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <17> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <1209> Tj 10.5 0 Td <0F> Tj 2.2 0 Td <12> Tj 5.1 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 75.4 Td /F2 10 Tf <17> Tj 5.5 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <02> Tj 5.5 0 Td <05> Tj 3.4 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <09> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <21> Tj 7.2 0 Td <09> Tj 5.5 0 Td <2C> Tj 4.9 0 Td <0A> Tj 2.2 0 Td <2D> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <33> Tj 5.5 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <4D> Tj 2.2 0 Td <0C> Tj 5.5 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <04> Tj 5.6 0 Td <05> Tj 3.4 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <21> Tj 7.2 0 Td <02> Tj 5.6 0 Td <05> Tj 3.2 0 Td <2A> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <11> Tj 5 0 Td <11> Tj 5.1 0 Td <04> Tj 5.5 0 Td <4B> Tj ET Q Q endstream endobj 2 0 obj 63303 endobj 3 0 obj << /Length 4 0 R >> stream 0 w q 0 -0.1 612.1 792.1 re W* n q 0 0 0 rg BT 90 711 Td /F2 10 Tf <14> Tj 8.4 0 Td <13> Tj 5.6 0 Td <1112> Tj 10 0 Td <0F> Tj 2.2 0 Td <0C> Tj 5.6 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <3F> Tj 8.3 0 Td <07> Tj 2.8 0 Td <06> Tj 2.7 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <23> Tj 2.7 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <04> Tj 5.6 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <02> Tj 5.6 0 Td <03> Tj 5.5 0 Td <3E> Tj 2.2 0 Td <04> Tj 5.6 0 Td <12> Tj 5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <2B> Tj 2.8 0 Td <11> Tj 5.2 0 Td <07> Tj 2.7 0 Td <0C> Tj 5.6 0 Td <06> Tj 2.7 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <02> Tj 5.5 0 Td <03> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.3 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.3 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.7 0 Td <09> Tj 5.5 0 Td <2E> Tj 4.9 0 Td <09> Tj 5.4 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.6 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 699.8 Td /F2 10 Tf <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <1111> Tj 10.1 0 Td <0A> Tj 2.1 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <2C> Tj 4.9 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <120C> Tj 10.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <14> Tj 8.4 0 Td <03> Tj 5.5 0 Td <09> Tj 5.6 0 Td <06> Tj 2.8 0 Td <06> Tj 2.7 0 Td <05> Tj 3.4 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <12> Tj 5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <33> Tj 5.5 0 Td <07> Tj 2.8 0 Td <05> Tj 3.2 0 Td <04> Tj 5.6 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.6 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 5 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <13> Tj 5.5 0 Td <2D> Tj 5.6 0 Td <14> Tj 8.3 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.8 0 Td <4E> Tj 5 0 Td <4D> Tj 2.2 0 Td <09> Tj 5.5 0 Td <0A> Tj ET Q q 0 0 0 rg BT 90 688.7 Td /F2 10 Tf <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <09> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <14> Tj 8.4 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <1C> Tj 5.6 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5.1 0 Td <11> Tj 5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.1 0 Td <2C> Tj 5 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <04> Tj 5.6 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 677.5 Td /F2 10 Tf <0C> Tj 5.5 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.4 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <41> Tj 3.4 0 Td <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <48> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <14> Tj 8.3 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <09> Tj 5.5 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <14> Tj 8.4 0 Td <19> Tj 5.6 0 Td <06> Tj 2.7 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <0E> Tj ET Q q 0 0 0 rg BT 90 655.2 Td /F2 10 Tf <08> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <11> Tj 4.9 0 Td <2E> Tj 5 0 Td <11> Tj 4.9 0 Td <06> Tj 2.8 0 Td <19> Tj 5.5 0 Td <14> Tj 8.4 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <02> Tj 5.5 0 Td <05> Tj 3.4 0 Td <2A> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.7 0 Td <121C> Tj 10.6 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <11> Tj 4.9 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.7 0 Td <4F> Tj 6.7 0 Td <41> Tj 3.4 0 Td <50> Tj 6.5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <09> Tj 5.6 0 Td <14> Tj 8.3 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <23> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj ET Q q 0 0 0 rg BT 90 644.1 Td /F2 10 Tf <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <0C> Tj 5.6 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <06> Tj 2.8 0 Td <31> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2D> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <08> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <09> Tj 5.6 0 Td <3204> Tj 10.5 0 Td <07> Tj 2.7 0 Td <4F> Tj 6.7 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <02> Tj 5.5 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.2 0 Td <4B> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <09> Tj 5.6 0 Td <14> Tj 8.3 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2C> Tj 5 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <0C> Tj 5.5 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <23> Tj ET Q q 0 0 0 rg BT 90 632.9 Td /F2 10 Tf <0F> Tj 2.2 0 Td <4D> Tj 2.2 0 Td <09> Tj 5.5 0 Td <3204> Tj 10.5 0 Td <07> Tj 2.8 0 Td <50> Tj 6.5 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <11> Tj 4.9 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2C> Tj 5 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <1C> Tj 5.6 0 Td <09> Tj 5.5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <4D> Tj 2.1 0 Td <09> Tj 5.6 0 Td <3204> Tj 10.5 0 Td <07> Tj 2.7 0 Td <5107> Tj 8.9 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <11> Tj 4.9 0 Td <2C> Tj 5 0 Td <04> Tj 5.5 0 Td <05> Tj 3.4 0 Td <1104> Tj 10.6 0 Td <07> Tj 2.7 0 Td <09> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <4F> Tj 6.7 0 Td <41> Tj 3.4 0 Td <50> Tj 6.6 0 Td <0E> Tj 2.6 0 Td <07> Tj 2.8 0 Td <08> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <1102> Tj 10.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.7 0 Td <14> Tj 8.4 0 Td <14> Tj 8.4 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 621.8 Td /F2 10 Tf <0F> Tj 2.2 0 Td <4D> Tj 2.2 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <05> Tj 3.4 0 Td <11> Tj 5 0 Td <04> Tj 5.5 0 Td <12> Tj 5.1 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.6 0 Td <07> Tj 2.7 0 Td <1113> Tj 10.6 0 Td <05> Tj 3.3 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.6 0 Td <12> Tj 5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <09> Tj 5.5 0 Td <2C> Tj 5 0 Td <04> Tj 5.5 0 Td <12> Tj 5 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <02> Tj 5.6 0 Td <05> Tj 3.2 0 Td <0A> Tj 2.2 0 Td <4B> Tj 4.9 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <07> Tj 2.8 0 Td <50> Tj 6.6 0 Td <41> Tj 3.2 0 Td <510E> Tj 8.9 0 Td <07> Tj 2.8 0 Td <08> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <5107> Tj 8.8 0 Td <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj ET Q q 0 0 0 rg BT 90 610.6 Td /F2 10 Tf <2A> Tj 5.5 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <12> Tj 5.1 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <12> Tj 5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <30> Tj 1.9 0 Td <09> Tj 5.5 0 Td <03> Tj 5.6 0 Td <1112> Tj 9.9 0 Td <0A> Tj 2.3 0 Td <11> Tj 5 0 Td <11> Tj 5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <4F> Tj 6.8 0 Td <07> Tj 2.7 0 Td <0B> Tj 5.5 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <17> Tj 5.6 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <05> Tj 3.4 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <33> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <05> Tj 3.4 0 Td <2A> Tj 5.5 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 599.5 Td /F2 10 Tf <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <12> Tj 5 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <14> Tj 8.4 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <05> Tj 3.4 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <2D> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <0A> Tj 2.3 0 Td <41> Tj 3.3 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <1111> Tj 10 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <11> Tj 5 0 Td <44> Tj 2.8 0 Td <07> Tj ET Q q 0 0 0 rg BT 90 226.5 Td /F2 10 Tf <08> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <0C> Tj 5.5 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.6 0 Td <09> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <12> Tj 5 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.3 0 Td <05> Tj 3.2 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.2 0 Td <2C> Tj 4.9 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <04> Tj 5.6 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.3 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.3 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <11> Tj 4.9 0 Td <06> Tj 2.8 0 Td <44> Tj ET Q q 0 0 0 rg BT 126 215.3 Td /F2 10 Tf <513030> Tj 10 0 Td <07> Tj 2.7 0 Td <52> Tj 5.8 0 Td <07> Tj 2.8 0 Td <53> Tj 6.6 0 Td <07> Tj 2.7 0 Td <54> Tj 3.9 0 Td <07> Tj 2.7 0 Td <0D> Tj 3.4 0 Td <07> Tj 2.7 0 Td <41> Tj 3.4 0 Td <22> Tj 6.6 0 Td <07> Tj 2.8 0 Td <54> Tj 3.8 0 Td <07> Tj 2.8 0 Td <0D> Tj 3.3 0 Td <26> Tj 5.5 0 Td <07> Tj 2.8 0 Td <41> Tj 3.4 0 Td <07> Tj 2.7 0 Td <4F15> Tj 9.9 0 Td <5522> Tj 11.3 0 Td <1E> Tj 6.7 0 Td <07> Tj 2.7 0 Td <56> Tj 5.5 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <01> Tj 7.2 0 Td <07> Tj 2.8 0 Td <54> Tj 3.8 0 Td <07> Tj 2.8 0 Td <4F> Tj 6.6 0 Td <15> Tj ET Q q 0 0 0 rg BT 90 193 Td /F2 10 Tf <29> Tj 7.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <2D> Tj 5.6 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.4 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.4 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <44> Tj 2.7 0 Td <07> Tj ET Q q 0 0 0 rg BT 126 181.3 Td /F2 10 Tf <5130> Tj 8.1 0 Td <07> Tj 2.7 0 Td <52> Tj 5.8 0 Td <07> Tj 2.7 0 Td <53> Tj 6.6 0 Td <07> Tj 2.8 0 Td <54> Tj 3.8 0 Td <07> Tj 2.8 0 Td <0D> Tj 3.4 0 Td <07> Tj 2.7 0 Td <22> Tj 6.6 0 Td <07> Tj 2.8 0 Td <54> Tj 3.8 0 Td <07> Tj 2.8 0 Td <0D> Tj 3.3 0 Td <26> Tj 5.6 0 Td <07> Tj 2.7 0 Td <41> Tj 3.4 0 Td <07> Tj 2.7 0 Td <4F> Tj 6.7 0 Td <15> Tj 3.3 0 Td <550D> Tj 7.9 0 Td <22> Tj 6.7 0 Td <1E> Tj 6.6 0 Td <07> Tj 2.8 0 Td <35> Tj 5.8 0 Td <07> Tj 2.7 0 Td <26> Tj 5.6 0 Td <15> Tj 3.3 0 Td <07> Tj 2.8 0 Td <45> Tj 2.7 0 Td <07> Tj 2.8 0 Td <0D> Tj 3.2 0 Td <22> Tj 6.7 0 Td <1E> Tj 6.6 0 Td <07> Tj 2.8 0 Td <35> Tj 5.8 0 Td <26> Tj 5.5 0 Td <15> Tj 3.3 0 Td <07> Tj 2.8 0 Td <56> Tj 5.5 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <01> Tj 7.2 0 Td <45> Tj 2.7 0 Td <18> Tj 5.6 0 Td <07> Tj 2.7 0 Td <54> Tj 3.9 0 Td <07> Tj 2.7 0 Td <4F> Tj ET Q q 0 0 0 rg BT 343.9 181.3 Td /F4 10 Tf <00> Tj ET Q q 0 0 0 rg BT 347.5 181.3 Td /F2 10 Tf <07> Tj 2.8 0 Td <35> Tj 5.7 0 Td <07> Tj 2.8 0 Td <29> Tj 7.2 0 Td <07> Tj 2.8 0 Td <15> Tj ET Q q 0 0 0 rg BT 90 158.7 Td /F2 10 Tf <20> Tj 6.7 0 Td <06> Tj 2.7 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <19> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.7 0 Td <13> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <04> Tj 5.6 0 Td <1202> Tj 10.5 0 Td <0B> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0C> Tj 5.5 0 Td <2D> Tj 5.6 0 Td <05> Tj 3.2 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <44> Tj 2.7 0 Td <07> Tj ET Q q 0 0 0 rg BT 126 147 Td /F2 10 Tf <5107> Tj 8.9 0 Td <52> Tj 5.8 0 Td <07> Tj 2.7 0 Td <53> Tj 6.6 0 Td <07> Tj 2.8 0 Td <54> Tj 3.8 0 Td <07> Tj 2.8 0 Td <0D> Tj 3.3 0 Td <07> Tj 2.8 0 Td <41> Tj 3.4 0 Td <22> Tj 6.6 0 Td <07> Tj 2.7 0 Td <54> Tj 3.9 0 Td <07> Tj 2.7 0 Td <0D> Tj 3.3 0 Td <26> Tj 5.6 0 Td <07> Tj 2.8 0 Td <41> Tj 3.3 0 Td <07> Tj 2.8 0 Td <4F> Tj 6.7 0 Td <15> Tj 3.2 0 Td <55> Tj 4.7 0 Td <0D> Tj 3.3 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.7 0 Td <07> Tj 2.7 0 Td <35> Tj 5.8 0 Td <07> Tj 2.8 0 Td <18> Tj 5.5 0 Td <15> Tj 3.3 0 Td <07> Tj 2.8 0 Td <45> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0D> Tj 3.4 0 Td <0D> Tj 3.3 0 Td <07> Tj 2.8 0 Td <22> Tj 6.7 0 Td <1E> Tj 6.5 0 Td <07> Tj 2.8 0 Td <35> Tj 5.7 0 Td <07> Tj 2.8 0 Td <18> Tj 5.5 0 Td <15> Tj 3.4 0 Td <07> Tj 2.7 0 Td <54> Tj 3.9 0 Td <07> Tj 2.7 0 Td <0D> Tj 3.3 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.7 0 Td <07> Tj 2.7 0 Td <35> Tj 5.8 0 Td <26> Tj 5.5 0 Td <15> Tj 3.4 0 Td <15> Tj 3.3 0 Td <07> Tj 2.8 0 Td <56> Tj 5.5 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <01> Tj 7.2 0 Td <45> Tj 2.7 0 Td <3B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <54> Tj 3.9 0 Td <07> Tj 2.7 0 Td <4F> Tj ET Q q 0 0 0 rg BT 400.9 147 Td /F4 10 Tf <01> Tj ET Q q 0 0 0 rg BT 404.5 147 Td /F2 10 Tf <07> Tj 2.8 0 Td <35> Tj 5.7 0 Td <07> Tj 2.8 0 Td <29> Tj 7.2 0 Td <07> Tj 2.8 0 Td <54> Tj 3.8 0 Td <07> Tj 2.8 0 Td <4F> Tj 6.7 0 Td <07> Tj 2.7 0 Td <35> Tj 5.8 0 Td <07> Tj 2.8 0 Td <24> Tj 6.6 0 Td <07> Tj 2.7 0 Td <15> Tj ET Q q 0 0 0 rg BT 90 124.4 Td /F2 10 Tf <16> Tj 6.7 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <11> Tj 4.9 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.3 0 Td <11> Tj 5 0 Td <2B> Tj 2.7 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0D> Tj 3.3 0 Td <4F> Tj 6.7 0 Td <52> Tj 5.8 0 Td <27> Tj 5.6 0 Td <23> Tj 2.7 0 Td <07> Tj 2.8 0 Td <51> Tj 6 0 Td <52> Tj 5.8 0 Td <27> Tj 5.6 0 Td <15> Tj 3.3 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0D> Tj 3.4 0 Td <4F52> Tj 12.4 0 Td <26> Tj 5.6 0 Td <23> Tj 2.8 0 Td <07> Tj 2.7 0 Td <51> Tj 6.1 0 Td <52> Tj 5.8 0 Td <27> Tj 5.5 0 Td <15> Tj 3.4 0 Td <07> Tj 2.7 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.6 0 Td <07> Tj 2.7 0 Td <44> Tj 2.8 0 Td <07> Tj ET Q q 0 0 0 rg BT 126 113.3 Td /F2 10 Tf <24> Tj 6.6 0 Td <07> Tj 2.8 0 Td <52> Tj 5.7 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <07> Tj 2.8 0 Td <45> Tj 2.7 0 Td <07> Tj 2.8 0 Td <0D> Tj 3.3 0 Td <0D> Tj 3.3 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.7 0 Td <07> Tj 2.8 0 Td <35> Tj 5.7 0 Td <07> Tj 2.8 0 Td <18> Tj 5.5 0 Td <15> Tj 3.4 0 Td <07> Tj 2.7 0 Td <54> Tj 3.9 0 Td <07> Tj 2.7 0 Td <0D> Tj 3.3 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.7 0 Td <07> Tj 2.7 0 Td <35> Tj 5.8 0 Td <07> Tj 2.8 0 Td <26> Tj 5.5 0 Td <15> Tj 3.3 0 Td <15> Tj ET Q q 0 0 0 rg BT 126 102.1 Td /F2 10 Tf <29> Tj 7.2 0 Td <07> Tj 2.8 0 Td <52> Tj 5.7 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <01> Tj 7.2 0 Td <07> Tj 2.8 0 Td <45> Tj 2.7 0 Td <07> Tj 2.8 0 Td <3B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <56> Tj 5.5 0 Td <07> Tj 2.7 0 Td <24> Tj ET Q q 0 0 0 rg BT 90 79.8 Td /F2 10 Tf <08> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <320A> Tj 7.2 0 Td <14> Tj 8.4 0 Td <13> Tj 5.6 0 Td <14> Tj 8.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <51> Tj 6.1 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <2C> Tj 4.9 0 Td <0C> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <07> Tj 2.8 0 Td <51> Tj 6.1 0 Td <3007> Tj 4.7 0 Td <52> Tj 5.7 0 Td <07> Tj 2.8 0 Td <27> Tj 5.5 0 Td <23> Tj 2.8 0 Td <07> Tj 2.7 0 Td <1204> Tj 10.6 0 Td <07> Tj 2.7 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <04> Tj 5.5 0 Td <06> Tj 2.9 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <09> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <12> Tj 4.9 0 Td <13> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <53> Tj 6.6 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <51> Tj ET Q Q q 192.2 257.7 227.7 317.3 re W* n q 227.7 0 0 317.2 192.2 257.9 cm /Im5 Do Q Q endstream endobj 4 0 obj 25919 endobj 5 0 obj << /Type /XObject /Subtype /Image /Width 384 /Height 532 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter /DCTDecode /Length 20178 >> stream JFIFC    ' .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQROC&&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( ( ( ( ( ( ( ( (+_ݥ䡚;xW '8fikZ%8E Tţ]y9[ `֝ap1+Q>yN;rv:m+vMN&c TBIiR(nGLZ2psߥRZ$qYlhu+ sFr{Ԍx{Oy4B;;MMKhٗf#i9\hOLZìkbVwwFa;`uϙg93ڵVmFO0HCв2A |<7Rf3w7mݜzgw@-&fQ:ɒXFXv#fŬߥ\\\I!#NÁ@7'l-c\yr9rgoUkOw6C`AUey֚Zm*"ɭMb N6jIt,A-#p9lg=ia|Q^7jr$Z8  ?1s@RI>0jHf@A$<L:t7͕K.CD\@A߮3\ޏH-&\YjR=W>KNX`~9a1Mᦆk)"n_LZG3X ˻P]q{ik41\A VI@ƒj!H"i-@FQ ?{3Ү&a$x eRT͜ ;=qoAJLE| *(bɖۑ Hxb <{%W?!-~fɠ rkZ\wvϨ[ nIH13tkUO6 i8bbbʑ2q3tQEQEQEQEaxy ah3d!89?7Nz[sB#OJծ'`}oGHd޳E,vHiP7!{+Sr񪠌#0,A@9 @GErէtgRD`۱Y NbOSL֖vm4^3nۜT I5 ?gmT݌g#8]FiO2ĪZE 3ɠb(IlrFx GcgoYie oD^O$I$foܶ+&|1G$VP\vJ$jn 9 ) tv@4[|B9T0ǿnz+Hnmt3"ȍ2dyjz((((((((((ۿ(+/nJԠ((((((((|Wy-p-NnqmlQ$;F2[zuUomi)'&Iǘ*pNĞÿ$ nZ%E;x$/8Y(*9bh)QdE!;RQ@hLmĖ$r 8R8= s!DX9$'#c禠(((((((((( :_҉+R= J$J((((((((+~/5}|}FlxW!O͜txWZE+2{r 1?\]>=mT%T(b-Г}^(((rk;]f%s&pwh*Xt5Z/.,,D9Ld8p}++s/-aud |pEoQEQEQEQEQEQEQEQEQEQEK_Q%jV_/~D@Q@Q@Q@Q@Q@Q@Q@Q@޳QN~v2op~v$W=kWY,;& q2C@Q@Q@Q@srF+/[7v336ך.@0M3%qrA(((((((((( :_҉+R= J$J(((((((++ķiͲ6@#@1 zVszG:F[]ڌۃ $dؒ?+o*C9ljPEPEPEPTu=5M&Oh[e ` qW jGXՅ2I3 :Xp ҵQtkzY|ơ4 G +>=((((((((((/nJԬ:_҉+R ( ( (oVM"%0*o y\rO@^ҢNT^ծMdȒmǑꮩfAK$1-^2Ԝ`3+ M"D{Kȱ#XOͻr\U4I`_%ô ŲcG&/n {.duGŶHF jKn$ĈΩBe@$dppEeYWin.]Y>6GF zddxiUK1ɷD1C\tk:5~DlU8< z=e#eQ֧4]B=n#W!X0RG+ԃ}^o!mZ"=FX#I$sdp(~n5 cMmƭ-؞Q%% czǀ2IbTHl\J6R]CR@y|CaV.xeUv˷p9R1N0 `!l,~V#kzI9hEQEQEQEQEQEK_Q%jV_/~D@Q@Q@fzJjiV{ygʕ~`szzpF_i֮R@WI$3;( Ov8 u(-${[{n;+ٰGqsxh vyNs:vzi5(0}Q+9L e@*:㡢9kI[}#^4䑇"e!zB"Hy ~֦8eb%d]`Jが]hznl'KFl v%LFLA H=qCEk2V/)nRo 8x ]Mq=vY{inHx,9 <ֈ n]GnŖ;{(I9_ps0rshy|Oji^01G{g(Bёiiɨ A={+lH3=I7 Oe"1cu֛g☮&)6Z\Or msch h~Ϸsmgge:n\eqV玥ۏ7@W7qⴆw-_QH+q7`r5Ȍx{YU (pG9~F7hmܼ6}LSR28)'$gz)xf׭ `dBNH8=:J|&Z\(7HV5)uQ9r8 pjPɌwzFz)z b{H  dY98PEPEPEPEPEPEPEPV]Mmp7\#qCYi4&xNv(hтzB7EvPKcx(((((((( :_҉+R= J$J(((((+3+@ DH.xP@QִDrj:c qrqLpv:*Ŕrp8'{i5a`ᄑ f {zz((((((((׏ٷK漛dSuGXTn6PI6RzܗeL1y=yؠ((((((( :_҉+R= J$J(((((+Ѷj>)_ݲӡemuA4&Pi[xf $sPxjm7@iZ&̎%$uOZբ((X8]pI'E,sD$r.e9  ( .<ϳS0"((*mQLq9E^ g9yǛ,FG#=jzmwu}+j[uUw;I ' ~/CIN"NY%M?u_oG< ( ( ( ( ( ( (2= J$Jۿ(((((((*散cǝqDb* Gb,,./% ҸLd8p=kF٨WvkNpax?;?%9xE9k+  c}ZX\jIasfr\*[ P$$R7|W$šj[6Ktp1ĜcnO\c/4\ ֲ8<a`ʲ eO99:K[{# J2! Qz dz˥>Qs2wb@q1gw7_w+K fG2'#s+o򁑙!r8㡧EXElȓ\{dđqh;XOjldg Xd3kX{WUY$2xrI<ժ.BE, rN=xxRƅe <0#z֝sVtb#S|W@a t5OP-V2,KO&$0IV~ Ώumʅܮ'#*0ݦ讒ex.#B!"фsam#\\!kFϸnFs:FA-7<= J$J5 i/Qk_'J(/׿%O=GKM|z( #^?FA-7Ԣ2{Zo yǫR5 i/Vu[:j\{4(E!nHu8<8kk (;`('z ]G5Cр60 @lcMO4VV6nݐ\* Iׂz:UӵB0K'%A'] dj>5/RC۝ˌr;c{Zo yǪv~(Ӽ5 -J9ۑcwC+px[]hzK*F. FNKǓzqx4<{Zo yǩv~mp̞g^9+u@8Z4k_'׿%O=ZP_KM|zO&_ivAlG-q@kORqt#22 8>f<_mSv}8x<{Zo թEeǨ5 i/Vk_'׿%O=ZP_KM|z zXҭ.aF@|1Üۥ>{uc1l:(*/ mf/r~9=Y S{*6H"aOB;tP^ҿpڀv/i\;:`tQص`8!L5 ''p9$5=QEQE) A/8/zǰd髛Nݩ Zmdc((+3]SEi,# 41ª'< ' [' D沰tԁ9#1Gcr?4,s*yq+]ʣc@p8kb |Q$>wInKxCa?c' koR4 ]@'$ܜV_,';[P]ګG0#2TrpsQG IHUQp(2= J$Jۿ((((I>嵔˶whT઀C1p7&jm+o8 C8\k ޯqiqF7WdIA̕H-#T)[pu"wyU4@ 1%H8 s{;}:+K(Vxj"Ԓy$I&1[7A>[i]/n:G Q=3j/oC1%l$hj~ QEQE^ik{ -" +(`7 99Ð0 #v-4_I4r"]I,͒2K2ʓ@&t /`]Bk9fh/%ew`1;{ (4&ӧX,IDZXem>YdqOÖՆwu{ȰXr#6+>X^@^ò ( ( ( ( ( (9@͢%DɥG| 9`ICKȻ0<ph(H]2#5gخ_}ƙ;p6J>QEQEW/exl4;339>)+X5{$ܰ6$c'8<֦aoi6"N:I'9 tQErOO~ZsO;xb#8+ vg^k$pc2jo?Pg=/\?l綥+9@/~D\·c#4u `O 8rMi`mKWr5(?Qg=/\Ԣl綥+9G Կeq(Rڗ ?6R Jvhi\&2Bd8S{j_2㕃M&4!ew.ëC&b3ߌc c–rf77,bC!#AY6R{j_2Ee`mKWr?Pg=/\?l綥+9@V_ Կeq(ڗ ?jQY6R{j_2Ee`mKWr?Pg=/\?l綥+9@V_ Կeq(ڗ ?jQY6R{j_2Ee`mKWr?Pg=/\?l綥+9@V_ Կeq(ڗ ?jW=6{\[c΋ ʩ% =@ Կeq+mXk1Kz>t3O%T%'#vV_ Կeq(ڗ ?jTr1<k$l綥+9PgLh.7G-# :P? G&q7[1Y|PPG騢 ( ( (2= J$Jۿ((((({Nf<_ކcKcC#9"INч906/PM+HQgֲxbk-o7]cHKdp@PQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@VK 9K,w4NS21JEbR[]]fLFFv7uvєi0t"5"$%ebOrgc(((((/nJԬ:_҉+R ( ( (9 JP^NW3k=Aۥ!e2H8 q]5QEQEQEQEQEQEQEQEQEQEQEQEQEs~)>F m>dk`@A%fxMƅ{H*I0zQHk _h 0é@tQEQEQEQEQEe{AIZK_Q%jPEPEPP]\ii5iN =O\35K:>iXg ^hHQv$izaJ{ww ( ( ( ( ( ( ( ( ( ( ( ( ( 4 ~ sGs&q{de }}܎2ь`\_xnDe`"xaczSN -ֽ{1,V \giHXº۔$M@Q@Q@Q@cX6l6%mNs[P=gC-^ɐqÎEbq5J1Fxׯt4P9ox Op9M56Grx#⧼)6WzTqE1$Q"kUFv(((((((((((((((9xE9k+  ax0Id;˦IjJKw!(ˏӌ2if\KXn|i2Fm+y9[QEQEQEK_Q%jV_/~D@Q@/y_G]:ȳjqح |ӯFQG IHUQpRdm M=((((((((5&wTdUaNGλ񧆬˫T6a (N:CEsb[=7YULc ATF{>Zq.^(3a/s{ң|M='S&WU's]fܿ6s @gڟwx`x U A<;8랂<kk8&v N) .;mJKAQn<0P@8+3Dkm2"s!]1$( ( ( (2= J$Jۿ((8byeu8s3II\Ϗo 9 5 Ve9v ڍf'{I$[#@N: oOjzTE|W'}*88^Gkbi1p3zhrh󹵏@$;;<3ėİZ\NR 矙\tVݬpxV,,(2 ?3A-/5ono; qw68byeu8s3IgGoMƪY;Ö[ٷ>p3c1uM'LcZ[HWixaT$dN==y #999\x!At; g>܁k9c^Y@Ƿ<[cr\M颉{F+IH$ @r h dڮgrZͤb֖VkYa^vy+3~U_׿O3G7Mf-ZXDb6ma '| Y~~@7<{o $4EetIh0 a'׿O3@V_7Mf?^n ?jQY~~@7<{o $4EetIh0 a'׿O3@V_7Mf?^n ?jQY~~@7<{o $4EetIh0 a'׿O3@V_7Mf?^n ?jQY~~@7<{o $4EetIh0 a'׿O3@V_7Mf?^n ?jQY~~@7<{o $4cSvK8%"( pWO@G9\\Y7 })LK1)4dq2h<{o $4ytIh I-,mB{p7K2B($qp B;cZf(͹8 0I a'5 ٭4D c0Ƕ{PvkɩG+I&0X.IήJŜ@$vH%%P]CTWY)m%!_-ZDg'3> stream 0 w q 0 -0.1 612.1 792.1 re W* n q 0 0 0 rg BT 90 711 Td /F2 10 Tf <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <320A> Tj 7.2 0 Td <14> Tj 8.4 0 Td <13> Tj 5.6 0 Td <14> Tj 8.6 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <1204> Tj 10.5 0 Td <0F> Tj 2.2 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <1C> Tj 5.6 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <0C> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0D> Tj 3.3 0 Td <12> Tj 5.1 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <13> Tj 5.4 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <05> Tj 3.2 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <15> Tj 3.4 0 Td <0E> Tj ET Q q 0 0 0 rg BT 90 688.7 Td /F2 10 Tf <08> Tj 5.5 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.8 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <04> Tj 5.5 0 Td <2B> Tj 2.9 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.3 0 Td <120A> Tj 7.2 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.6 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <01> Tj 7.2 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.7 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <03> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <03> Tj 5.5 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <2A> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <09> Tj 5.5 0 Td <06> Tj 2.7 0 Td <06> Tj 2.8 0 Td <09> Tj 5.5 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <03> Tj 5.5 0 Td <02> Tj 5.6 0 Td <05> Tj 3.2 0 Td <2A> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 677.5 Td /F2 10 Tf <2B> Tj 2.8 0 Td <13> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.6 0 Td <12> Tj 5 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <320A> Tj 7.2 0 Td <14> Tj 8.4 0 Td <13> Tj 5.6 0 Td <14> Tj 8.4 0 Td <23> Tj 3 0 Td <07> Tj 2.7 0 Td <1204> Tj 10.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <32> Tj 5 0 Td <07> Tj 2.7 0 Td <12> Tj 5.1 0 Td <02> Tj 5.5 0 Td <04> Tj 5.5 0 Td <2B> Tj 2.9 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.3 0 Td <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <13> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <1205> Tj 8.3 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.3 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.3 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <33> Tj ET Q q 0 0 0 rg BT 90 666.4 Td /F2 10 Tf <06> Tj 2.8 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <09> Tj 5.5 0 Td <13> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <11> Tj 5 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.8 0 Td <08> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <04> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <120A> Tj 7.2 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <22> Tj 6.6 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <04> Tj 5.5 0 Td <05> Tj 3.4 0 Td <14> Tj 8.4 0 Td <04> Tj 5.5 0 Td <06> Tj 2.9 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <2B> Tj 2.9 0 Td <2B> Tj 2.7 0 Td <0C> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.5 0 Td <14> Tj 8.4 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.3 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.6 0 Td <1207> Tj 7.7 0 Td <13> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.7 0 Td <03> Tj 5.6 0 Td <02> Tj 5.5 0 Td <05> Tj 3.3 0 Td <2A> Tj ET Q q 0 0 0 rg BT 90 655.2 Td /F2 10 Tf <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <06> Tj 2.7 0 Td <09> Tj 5.5 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <13> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.7 0 Td <20> Tj 6.7 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <07> Tj 2.7 0 Td <52> Tj 5.8 0 Td <07> Tj 2.7 0 Td <26> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <03> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <06> Tj 2.8 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 644.1 Td /F2 10 Tf <0B> Tj 5.5 0 Td <09> Tj 5.6 0 Td <2C> Tj 4.9 0 Td <0A> Tj 2.2 0 Td <2D> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.7 0 Td <1202> Tj 10.5 0 Td <0B> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <02> Tj 5.5 0 Td <2E> Tj 4.9 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.7 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <03> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.7 0 Td <16> Tj 6.7 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <14> Tj 8.3 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <3E> Tj 2.3 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <05> Tj 3.2 0 Td <0C> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <19> Tj 5.5 0 Td <05> Tj 3.4 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <02> Tj 5.6 0 Td <03> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.3 0 Td <05> Tj ET Q q 0 0 0 rg BT 90 632.9 Td /F2 10 Tf <13> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <03> Tj 5.5 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <2A> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <06> Tj 2.7 0 Td <09> Tj 5.5 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <13> Tj 5.5 0 Td <1107> Tj 7.8 0 Td <17> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <3E> Tj 2.3 0 Td <4D> Tj 2.2 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 4.9 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <07> Tj 2.7 0 Td <52> Tj 5.8 0 Td <07> Tj 2.7 0 Td <26> Tj 5.6 0 Td <07> Tj 2.7 0 Td <35> Tj 5.8 0 Td <07> Tj 2.7 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.6 0 Td <07> Tj 2.8 0 Td <45> Tj 2.8 0 Td <07> Tj 2.7 0 Td <28> Tj 5.6 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <29> Tj 7.1 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <04> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <12> Tj 5.1 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <04> Tj 5.6 0 Td <11> Tj 4.9 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <04> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <1202> Tj 10.5 0 Td <2A> Tj 5.6 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 621.8 Td /F2 10 Tf <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <1D> Tj 6.7 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0E> Tj ET Q q 0 0 0 rg BT 90 599.5 Td /F2 10 Tf <08> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <06> Tj 2.8 0 Td <09> Tj 5.5 0 Td <03> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <09> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <3204> Tj 10.5 0 Td <14> Tj 8.4 0 Td <17> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <02> Tj 5.5 0 Td <03> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <09> Tj 5.5 0 Td <2C> Tj 5 0 Td <04> Tj 5.5 0 Td <12> Tj 5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <13> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <120A> Tj 7.2 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <110E> Tj 7.8 0 Td <07> Tj ET Q Q q 131.3 257.9 349.5 317.1 re W* n 0 0 0 rg 283.5 566.6 89.6 0 re f* 283.5 558.1 89.6 0 re f* 283.5 549.6 89.6 0 re f* 283.5 541.2 89.6 0 re f* 194.7 453.6 224.7 0 re f* 194.7 445.2 224.7 0 re f* 194.7 267.4 224.7 0 re f* 194.7 267.4 0 186.3 re f* 238.8 267.4 0 186.3 re f* 283.5 541.2 0 25.4 re f* 283.5 267.4 0 186.3 re f* 328.3 541.2 0 25.4 re f* 328.3 267.4 0 186.3 re f* 373.1 541.2 0 25.4 re f* 373.1 267.4 0 186.3 re f* 419.3 267.4 0 186.3 re f* BT 1.3408 0 0 1 132.2 560.3 Tm /F1 7 Tf <1A> Tj 1.3408 0 0 1 138 560.3 Tm <0E> Tj 1.3408 0 0 1 141.7 560.3 Tm <02> Tj 1.3408 0 0 1 147.4 560.3 Tm <0F> Tj 1.3408 0 0 1 150.6 560.3 Tm <0605> Tj 1.3408 0 0 1 155.8 560.3 Tm <0B12> Tj 1.3408 0 0 1 164.8 560.3 Tm <08> Tj 1.3408 0 0 1 170 560.3 Tm <0605100D> Tj 1.3408 0 0 1 186.3 560.3 Tm <09> Tj ET BT 1.3408 0 0 1 309.3 560.3 Tm /F2 7 Tf <22> Tj 1.3408 0 0 1 315.6 560.3 Tm <1E> Tj 1.3408 0 0 1 321.9 560.3 Tm <52> Tj ET BT 1.3408 0 0 1 348.6 560.3 Tm /F2 7 Tf <57232727> Tj 1.3408 0 0 1 366.9 560.3 Tm <27> Tj ET BT 1.3408 0 0 1 308.8 551.8 Tm /F2 7 Tf <22> Tj 1.3408 0 0 1 315.1 551.8 Tm <01> Tj 1.3408 0 0 1 321.9 551.8 Tm <52> Tj ET BT 1.3408 0 0 1 348.6 551.8 Tm /F2 7 Tf <27232718> Tj 1.3408 0 0 1 366.9 551.8 Tm <27> Tj ET BT 1.3408 0 0 1 315.6 543.4 Tm /F2 7 Tf <5352> Tj ET BT 1.3408 0 0 1 348.6 543.4 Tm /F2 7 Tf <18233728> Tj 1.3408 0 0 1 366.9 543.4 Tm <27> Tj ET BT 1.3408 0 0 1 132.2 526.6 Tm /F5 7 Tf <01> Tj 1.3408 0 0 1 138.7 526.6 Tm <02> Tj 1.3408 0 0 1 141.7 526.6 Tm <03> Tj 1.3408 0 0 1 149.6 526.6 Tm <02> Tj 1.3408 0 0 1 152.6 526.6 Tm <04> Tj 1.3408 0 0 1 158.6 526.6 Tm <02050201> Tj 1.3408 0 0 1 179 526.6 Tm <06> Tj 1.3408 0 0 1 185.5 526.6 Tm <0207> Tj 1.3408 0 0 1 191.6 526.6 Tm <02> Tj 1.3408 0 0 1 194.6 526.6 Tm <08> Tj ET BT 1.3408 0 0 1 315.6 526.4 Tm /F2 7 Tf <2252> Tj ET BT 1.3408 0 0 1 348.6 526.4 Tm /F2 7 Tf <18231857> Tj 1.3408 0 0 1 366.9 526.4 Tm <27> Tj ET BT 1.3408 0 0 1 132.2 518.1 Tm /F5 7 Tf <0902030201> Tj 1.3408 0 0 1 159.1 518.1 Tm <02> Tj 1.3408 0 0 1 162.1 518.1 Tm <07> Tj 1.3408 0 0 1 165.2 518.1 Tm <020A0A01> Tj 1.3408 0 0 1 182.1 518.1 Tm <06> Tj 1.3408 0 0 1 188.6 518.1 Tm <0205020B> Tj 1.3408 0 0 1 208.5 518.1 Tm <0C> Tj 1.3408 0 0 1 212.2 518.1 Tm <020D> Tj 1.3408 0 0 1 219.9 518.1 Tm <020A0106> Tj 1.3408 0 0 1 239.5 518.1 Tm <02> Tj 1.3408 0 0 1 242.5 518.1 Tm <05> Tj 1.3408 0 0 1 250.5 518.1 Tm <0204> Tj 1.3408 0 0 1 259.4 518.1 Tm <0C> Tj 1.3408 0 0 1 263.1 518.1 Tm <0C> Tj ET BT 1.3408 0 0 1 315.6 518 Tm /F2 7 Tf <2452> Tj ET BT 1.3408 0 0 1 348.6 518 Tm /F2 7 Tf <27232757> Tj 1.3408 0 0 1 366.9 518 Tm <28> Tj ET BT 1.3408 0 0 1 132.2 509.7 Tm /F5 7 Tf <0E> Tj 1.3408 0 0 1 138.8 509.7 Tm <0203> Tj 1.3408 0 0 1 149.7 509.7 Tm <02> Tj 1.3408 0 0 1 152.7 509.7 Tm <01> Tj 1.3408 0 0 1 159.2 509.7 Tm <0F020702100211> Tj 1.3408 0 0 1 188.7 509.7 Tm <02> Tj 1.3408 0 0 1 191.7 509.7 Tm <09> Tj ET BT 1.3408 0 0 1 315.1 509.5 Tm /F2 7 Tf <29> Tj 1.3408 0 0 1 321.9 509.5 Tm <52> Tj ET BT 1.3408 0 0 1 345.4 509.5 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 348.6 509.5 Tm <27232757> Tj 1.3408 0 0 1 366.9 509.5 Tm <27> Tj ET BT 1.3408 0 0 1 132.2 472.9 Tm /F5 7 Tf <1213130203> Tj 1.3408 0 0 1 154.8 472.9 Tm <0214> Tj 1.3408 0 0 1 164 472.9 Tm <020D> Tj 1.3408 0 0 1 171.7 472.9 Tm <020A0215> Tj 1.3408 0 0 1 184.8 472.9 Tm <0102> Tj 1.3408 0 0 1 194.3 472.9 Tm <0D> Tj 1.3408 0 0 1 199 472.9 Tm <020A> Tj 1.3408 0 0 1 205.7 472.9 Tm <04021502160C1701> Tj 1.3408 0 0 1 245.7 472.9 Tm <06> Tj 1.3408 0 0 1 252.1 472.9 Tm <02> Tj 1.3408 0 0 1 255.1 472.9 Tm <11> Tj 1.3408 0 0 1 259.8 472.9 Tm <0201> Tj 1.3408 0 0 1 269.3 472.9 Tm <0F> Tj 1.3408 0 0 1 275.9 472.9 Tm <020D> Tj 1.3408 0 0 1 283.6 472.9 Tm <02160C> Tj ET BT 1.3408 0 0 1 132.2 464.5 Tm /F5 7 Tf <18> Tj 1.3408 0 0 1 137.4 464.5 Tm <191A> Tj 1.3408 0 0 1 149.1 464.5 Tm <1B1C1A1B1D02> Tj 1.3408 0 0 1 177.7 464.5 Tm <03> Tj 1.3408 0 0 1 185.6 464.5 Tm <021E> Tj 1.3408 0 0 1 193.6 464.5 Tm <131307> Tj 1.3408 0 0 1 202 464.5 Tm <0A> Tj 1.3408 0 0 1 205.7 464.5 Tm <0405> Tj 1.3408 0 0 1 219.6 464.5 Tm <1E> Tj 1.3408 0 0 1 224.6 464.5 Tm <130D> Tj 1.3408 0 0 1 231.9 464.5 Tm <1E> Tj 1.3408 0 0 1 236.9 464.5 Tm <130C17> Tj 1.3408 0 0 1 251.1 464.5 Tm <1F> Tj 1.3408 0 0 1 254.8 464.5 Tm <07> Tj 1.3408 0 0 1 258 464.5 Tm <20> Tj ET BT 1.3408 0 0 1 214.4 447.4 Tm /F2 7 Tf <32> Tj ET BT 1.3408 0 0 1 257 447.4 Tm /F2 7 Tf <4B> Tj 1.3408 0 0 1 261.7 447.4 Tm <30> Tj 1.3408 0 0 1 263.5 447.4 Tm <30> Tj ET BT 1.3408 0 0 1 302.7 447.4 Tm /F2 7 Tf <4B> Tj 1.3408 0 0 1 307.4 447.4 Tm <30> Tj ET BT 1.3408 0 0 1 338.7 447.4 Tm /F2 7 Tf <4B> Tj 1.3408 0 0 1 343.4 447.4 Tm <07> Tj 1.3408 0 0 1 346 447.4 Tm <54072627> Tj ET BT 1.3408 0 0 1 374.1 447.4 Tm /F2 7 Tf <12> Tj 1.3408 0 0 1 378.8 447.4 Tm <02> Tj 1.3408 0 0 1 384.1 447.4 Tm <1305> Tj 1.3408 0 0 1 392.5 447.4 Tm <0313> Tj 1.3408 0 0 1 403 447.4 Tm <05> Tj 1.3408 0 0 1 406.1 447.4 Tm <04> Tj ET BT 1.3408 0 0 1 214.2 438.9 Tm /F2 7 Tf <27232727> Tj 1.3408 0 0 1 232.6 438.9 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 438.9 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 438.9 Tm <3B233B26> Tj 1.3408 0 0 1 277.4 438.9 Tm <57> Tj ET BT 1.3408 0 0 1 303.8 438.9 Tm /F2 7 Tf <27233757> Tj 1.3408 0 0 1 322.1 438.9 Tm <57> Tj ET BT 1.3408 0 0 1 348.6 438.9 Tm /F2 7 Tf <27232727> Tj 1.3408 0 0 1 366.9 438.9 Tm <27> Tj ET BT 1.3408 0 0 1 391.6 438.9 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 438.9 Tm <18> Tj 1.3408 0 0 1 400 438.9 Tm <2357273A> Tj ET BT 1.3408 0 0 1 214.2 430.4 Tm /F2 7 Tf <27232757> Tj 1.3408 0 0 1 232.6 430.4 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 430.4 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 430.4 Tm <57232618> Tj 1.3408 0 0 1 277.4 430.4 Tm <18> Tj ET BT 1.3408 0 0 1 303.8 430.4 Tm /F2 7 Tf <27233B3B> Tj 1.3408 0 0 1 322.1 430.4 Tm <3A> Tj ET BT 1.3408 0 0 1 348.6 430.4 Tm /F2 7 Tf <27232827> Tj 1.3408 0 0 1 366.9 430.4 Tm <26> Tj ET BT 1.3408 0 0 1 391.6 430.4 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 430.4 Tm <18> Tj 1.3408 0 0 1 400 430.4 Tm <23373B38> Tj ET BT 1.3408 0 0 1 214.2 422 Tm /F2 7 Tf <27232627> Tj 1.3408 0 0 1 232.6 422 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 422 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 422 Tm <3A233726> Tj 1.3408 0 0 1 277.4 422 Tm <18> Tj ET BT 1.3408 0 0 1 303.8 422 Tm /F2 7 Tf <2723283A> Tj 1.3408 0 0 1 322.1 422 Tm <39> Tj ET BT 1.3408 0 0 1 348.6 422 Tm /F2 7 Tf <27233B38> Tj 1.3408 0 0 1 366.9 422 Tm <28> Tj ET BT 1.3408 0 0 1 391.6 422 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 422 Tm <3A> Tj 1.3408 0 0 1 400 422 Tm <23272738> Tj ET BT 1.3408 0 0 1 214.2 413.5 Tm /F2 7 Tf <27232657> Tj 1.3408 0 0 1 232.6 413.5 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 413.5 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 413.5 Tm <18233728> Tj 1.3408 0 0 1 277.4 413.5 Tm <28> Tj ET BT 1.3408 0 0 1 303.8 413.5 Tm /F2 7 Tf <2723183B> Tj 1.3408 0 0 1 322.1 413.5 Tm <38> Tj ET BT 1.3408 0 0 1 348.6 413.5 Tm /F2 7 Tf <27233928> Tj 1.3408 0 0 1 366.9 413.5 Tm <39> Tj ET BT 1.3408 0 0 1 391.6 413.5 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 413.5 Tm <18> Tj 1.3408 0 0 1 400 413.5 Tm <233B5728> Tj ET BT 1.3408 0 0 1 214.2 405 Tm /F2 7 Tf <27231827> Tj 1.3408 0 0 1 232.6 405 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 405 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 405 Tm <18232638> Tj 1.3408 0 0 1 277.4 405 Tm <37> Tj ET BT 1.3408 0 0 1 303.8 405 Tm /F2 7 Tf <27232628> Tj 1.3408 0 0 1 322.1 405 Tm <27> Tj ET BT 1.3408 0 0 1 348.6 405 Tm /F2 7 Tf <27233728> Tj 1.3408 0 0 1 366.9 405 Tm <37> Tj ET BT 1.3408 0 0 1 391.6 405 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 405 Tm <18> Tj 1.3408 0 0 1 400 405 Tm <23262638> Tj ET BT 1.3408 0 0 1 214.2 396.6 Tm /F2 7 Tf <27231857> Tj 1.3408 0 0 1 232.6 396.6 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 396.6 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 396.6 Tm <26235739> Tj 1.3408 0 0 1 277.4 396.6 Tm <28> Tj ET BT 1.3408 0 0 1 303.8 396.6 Tm /F2 7 Tf <27232728> Tj 1.3408 0 0 1 322.1 396.6 Tm <38> Tj ET BT 1.3408 0 0 1 348.6 396.6 Tm /F2 7 Tf <27233737> Tj 1.3408 0 0 1 366.9 396.6 Tm <28> Tj ET BT 1.3408 0 0 1 391.6 396.6 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 396.6 Tm <26> Tj 1.3408 0 0 1 400 396.6 Tm <23573837> Tj ET BT 1.3408 0 0 1 214.2 388.1 Tm /F2 7 Tf <27233A27> Tj 1.3408 0 0 1 232.6 388.1 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 388.1 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 388.1 Tm <26232618> Tj 1.3408 0 0 1 277.4 388.1 Tm <37> Tj ET BT 1.3408 0 0 1 300.6 388.1 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 388.1 Tm <27232718> Tj 1.3408 0 0 1 322.1 388.1 Tm <26> Tj ET BT 1.3408 0 0 1 348.6 388.1 Tm /F2 7 Tf <26232727> Tj 1.3408 0 0 1 366.9 388.1 Tm <27> Tj ET BT 1.3408 0 0 1 391.6 388.1 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 388.1 Tm <26> Tj 1.3408 0 0 1 400 388.1 Tm <23261837> Tj ET BT 1.3408 0 0 1 214.2 379.6 Tm /F2 7 Tf <27233A57> Tj 1.3408 0 0 1 232.6 379.6 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 379.6 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 379.6 Tm <27233839> Tj 1.3408 0 0 1 277.4 379.6 Tm <39> Tj ET BT 1.3408 0 0 1 300.6 379.6 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 379.6 Tm <2723273B> Tj 1.3408 0 0 1 322.1 379.6 Tm <39> Tj ET BT 1.3408 0 0 1 348.6 379.6 Tm /F2 7 Tf <27233738> Tj 1.3408 0 0 1 366.9 379.6 Tm <38> Tj ET BT 1.3408 0 0 1 391.6 379.6 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 379.6 Tm <27> Tj 1.3408 0 0 1 400 379.6 Tm <2338393A> Tj ET BT 1.3408 0 0 1 214.2 371.2 Tm /F2 7 Tf <27232827> Tj 1.3408 0 0 1 232.6 371.2 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 371.2 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 371.2 Tm <2723573A> Tj 1.3408 0 0 1 277.4 371.2 Tm <39> Tj ET BT 1.3408 0 0 1 300.6 371.2 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 371.2 Tm <27232627> Tj 1.3408 0 0 1 322.1 371.2 Tm <26> Tj ET BT 1.3408 0 0 1 348.6 371.2 Tm /F2 7 Tf <2723373A> Tj 1.3408 0 0 1 366.9 371.2 Tm <28> Tj ET BT 1.3408 0 0 1 391.6 371.2 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 371.2 Tm <27> Tj 1.3408 0 0 1 400 371.2 Tm <23573A27> Tj ET BT 1.3408 0 0 1 214.2 362.7 Tm /F2 7 Tf <27232857> Tj 1.3408 0 0 1 232.6 362.7 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 362.7 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 362.7 Tm <27233A57> Tj 1.3408 0 0 1 277.4 362.7 Tm <37> Tj ET BT 1.3408 0 0 1 300.6 362.7 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 362.7 Tm <27232618> Tj 1.3408 0 0 1 322.1 362.7 Tm <3A> Tj ET BT 1.3408 0 0 1 348.6 362.7 Tm /F2 7 Tf <27233938> Tj 1.3408 0 0 1 366.9 362.7 Tm <38> Tj ET BT 1.3408 0 0 1 391.6 362.7 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 362.7 Tm <27> Tj 1.3408 0 0 1 400 362.7 Tm <233A5726> Tj ET BT 1.3408 0 0 1 214.2 354.2 Tm /F2 7 Tf <27235727> Tj 1.3408 0 0 1 232.6 354.2 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 354.2 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 354.2 Tm <2723183A> Tj 1.3408 0 0 1 277.4 354.2 Tm <3B> Tj ET BT 1.3408 0 0 1 300.6 354.2 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 354.2 Tm <2723263A> Tj 1.3408 0 0 1 322.1 354.2 Tm <39> Tj ET BT 1.3408 0 0 1 348.6 354.2 Tm /F2 7 Tf <27233926> Tj 1.3408 0 0 1 366.9 354.2 Tm <18> Tj ET BT 1.3408 0 0 1 391.6 354.2 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 354.2 Tm <27> Tj 1.3408 0 0 1 400 354.2 Tm <23183A27> Tj ET BT 1.3408 0 0 1 214.2 345.8 Tm /F2 7 Tf <27235757> Tj 1.3408 0 0 1 232.6 345.8 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 345.8 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 345.8 Tm <27232657> Tj 1.3408 0 0 1 277.4 345.8 Tm <28> Tj ET BT 1.3408 0 0 1 300.6 345.8 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 345.8 Tm <27232628> Tj 1.3408 0 0 1 322.1 345.8 Tm <38> Tj ET BT 1.3408 0 0 1 348.6 345.8 Tm /F2 7 Tf <27233828> Tj 1.3408 0 0 1 366.9 345.8 Tm <27> Tj ET BT 1.3408 0 0 1 391.6 345.8 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 345.8 Tm <27> Tj 1.3408 0 0 1 400 345.8 Tm <23265727> Tj ET BT 1.3408 0 0 1 214.2 337.3 Tm /F2 7 Tf <27233B27> Tj 1.3408 0 0 1 232.6 337.3 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 337.3 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 337.3 Tm <27232627> Tj 1.3408 0 0 1 277.4 337.3 Tm <3A> Tj ET BT 1.3408 0 0 1 300.6 337.3 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 337.3 Tm <27232657> Tj 1.3408 0 0 1 322.1 337.3 Tm <28> Tj ET BT 1.3408 0 0 1 348.6 337.3 Tm /F2 7 Tf <27233B3B> Tj 1.3408 0 0 1 366.9 337.3 Tm <57> Tj ET BT 1.3408 0 0 1 391.6 337.3 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 337.3 Tm <27> Tj 1.3408 0 0 1 400 337.3 Tm <23273737> Tj ET BT 1.3408 0 0 1 214.2 328.8 Tm /F2 7 Tf <27233B57> Tj 1.3408 0 0 1 232.6 328.8 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 328.8 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 328.8 Tm <27232738> Tj 1.3408 0 0 1 277.4 328.8 Tm <3A> Tj ET BT 1.3408 0 0 1 300.6 328.8 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 328.8 Tm <27232657> Tj 1.3408 0 0 1 322.1 328.8 Tm <39> Tj ET BT 1.3408 0 0 1 348.6 328.8 Tm /F2 7 Tf <27235739> Tj 1.3408 0 0 1 366.9 328.8 Tm <38> Tj ET BT 1.3408 0 0 1 391.6 328.8 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 328.8 Tm <27> Tj 1.3408 0 0 1 400 328.8 Tm <23273827> Tj ET BT 1.3408 0 0 1 214.2 320.4 Tm /F2 7 Tf <27233827> Tj 1.3408 0 0 1 232.6 320.4 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 320.4 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 320.4 Tm <27232757> Tj 1.3408 0 0 1 277.4 320.4 Tm <38> Tj ET BT 1.3408 0 0 1 300.6 320.4 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 320.4 Tm <2723263B> Tj 1.3408 0 0 1 322.1 320.4 Tm <26> Tj ET BT 1.3408 0 0 1 348.6 320.4 Tm /F2 7 Tf <27235727> Tj 1.3408 0 0 1 366.9 320.4 Tm <38> Tj ET BT 1.3408 0 0 1 391.6 320.4 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 320.4 Tm <27> Tj 1.3408 0 0 1 400 320.4 Tm <23275757> Tj ET BT 1.3408 0 0 1 214.2 311.9 Tm /F2 7 Tf <27233857> Tj 1.3408 0 0 1 232.6 311.9 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 311.9 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 311.9 Tm <27232757> Tj 1.3408 0 0 1 277.4 311.9 Tm <26> Tj ET BT 1.3408 0 0 1 300.6 311.9 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 311.9 Tm <2723263B> Tj 1.3408 0 0 1 322.1 311.9 Tm <28> Tj ET BT 1.3408 0 0 1 348.6 311.9 Tm /F2 7 Tf <27232818> Tj 1.3408 0 0 1 366.9 311.9 Tm <3B> Tj ET BT 1.3408 0 0 1 391.6 311.9 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 311.9 Tm <27> Tj 1.3408 0 0 1 400 311.9 Tm <23272837> Tj ET BT 1.3408 0 0 1 214.2 303.4 Tm /F2 7 Tf <27233927> Tj 1.3408 0 0 1 232.6 303.4 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 303.4 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 303.4 Tm <27232728> Tj 1.3408 0 0 1 277.4 303.4 Tm <37> Tj ET BT 1.3408 0 0 1 300.6 303.4 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 303.4 Tm <2723263B> Tj 1.3408 0 0 1 322.1 303.4 Tm <3B> Tj ET BT 1.3408 0 0 1 348.6 303.4 Tm /F2 7 Tf <27233A28> Tj 1.3408 0 0 1 366.9 303.4 Tm <3A> Tj ET BT 1.3408 0 0 1 391.6 303.4 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 303.4 Tm <27> Tj 1.3408 0 0 1 400 303.4 Tm <23272838> Tj ET BT 1.3408 0 0 1 214.2 295 Tm /F2 7 Tf <27233957> Tj 1.3408 0 0 1 232.6 295 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 295 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 295 Tm <27232757> Tj 1.3408 0 0 1 277.4 295 Tm <27> Tj ET BT 1.3408 0 0 1 300.6 295 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 295 Tm <2723263B> Tj 1.3408 0 0 1 322.1 295 Tm <37> Tj ET BT 1.3408 0 0 1 348.6 295 Tm /F2 7 Tf <27231857> Tj 1.3408 0 0 1 366.9 295 Tm <37> Tj ET BT 1.3408 0 0 1 391.6 295 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 295 Tm <27> Tj 1.3408 0 0 1 400 295 Tm <23272839> Tj ET BT 1.3408 0 0 1 214.2 286.5 Tm /F2 7 Tf <27233727> Tj 1.3408 0 0 1 232.6 286.5 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 286.5 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 286.5 Tm <27232757> Tj 1.3408 0 0 1 277.4 286.5 Tm <3A> Tj ET BT 1.3408 0 0 1 300.6 286.5 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 286.5 Tm <27232638> Tj 1.3408 0 0 1 322.1 286.5 Tm <18> Tj ET BT 1.3408 0 0 1 348.6 286.5 Tm /F2 7 Tf <27232638> Tj 1.3408 0 0 1 366.9 286.5 Tm <28> Tj ET BT 1.3408 0 0 1 391.6 286.5 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 286.5 Tm <27> Tj 1.3408 0 0 1 400 286.5 Tm <23275726> Tj ET BT 1.3408 0 0 1 214.2 278 Tm /F2 7 Tf <27233757> Tj 1.3408 0 0 1 232.6 278 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 278 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 278 Tm <27232757> Tj 1.3408 0 0 1 277.4 278 Tm <3B> Tj ET BT 1.3408 0 0 1 300.6 278 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 278 Tm <27232638> Tj 1.3408 0 0 1 322.1 278 Tm <28> Tj ET BT 1.3408 0 0 1 348.6 278 Tm /F2 7 Tf <27232739> Tj 1.3408 0 0 1 366.9 278 Tm <39> Tj ET BT 1.3408 0 0 1 391.6 278 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 278 Tm <27> Tj 1.3408 0 0 1 400 278 Tm <2327573A> Tj ET BT 1.3408 0 0 1 214.2 269.6 Tm /F2 7 Tf <26232727> Tj 1.3408 0 0 1 232.6 269.6 Tm <27> Tj ET BT 1.3408 0 0 1 255.8 269.6 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 259 269.6 Tm <27232757> Tj 1.3408 0 0 1 277.4 269.6 Tm <37> Tj ET BT 1.3408 0 0 1 300.6 269.6 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 303.8 269.6 Tm <27232638> Tj 1.3408 0 0 1 322.1 269.6 Tm <38> Tj ET BT 1.3408 0 0 1 348.6 269.6 Tm /F2 7 Tf <27232727> Tj 1.3408 0 0 1 366.9 269.6 Tm <27> Tj ET BT 1.3408 0 0 1 391.6 269.6 Tm /F2 7 Tf <41> Tj 1.3408 0 0 1 394.8 269.6 Tm <27> Tj 1.3408 0 0 1 400 269.6 Tm <2327573B> Tj ET BT 1.3408 0 0 1 132.2 491.3 Tm /F2 7 Tf <51> Tj 1.3408 0 0 1 138 491.3 Tm <0752> Tj 1.3408 0 0 1 146.1 491.3 Tm <07530754> Tj 1.3408 0 0 1 161.3 491.3 Tm <070D> Tj 1.3408 0 0 1 167.1 491.3 Tm <0741> Tj 1.3408 0 0 1 172.9 491.3 Tm <22> Tj 1.3408 0 0 1 179.2 491.3 Tm <07> Tj 1.3408 0 0 1 181.8 491.3 Tm <54070D> Tj 1.3408 0 0 1 191.3 491.3 Tm <26> Tj 1.3408 0 0 1 196.5 491.3 Tm <0741> Tj 1.3408 0 0 1 202.3 491.3 Tm <074F> Tj 1.3408 0 0 1 211.2 491.3 Tm <15> Tj 1.3408 0 0 1 214.3 491.3 Tm <55> Tj 1.3408 0 0 1 218.8 491.3 Tm <0D> Tj 1.3408 0 0 1 221.9 491.3 Tm <22> Tj 1.3408 0 0 1 228.2 491.3 Tm <1E0735> Tj 1.3408 0 0 1 242.7 491.3 Tm <0718> Tj 1.3408 0 0 1 250.6 491.3 Tm <15> Tj 1.3408 0 0 1 253.7 491.3 Tm <074507> Tj 1.3408 0 0 1 261.6 491.3 Tm <0D> Tj 1.3408 0 0 1 264.7 491.3 Tm <0D> Tj 1.3408 0 0 1 267.9 491.3 Tm <0722> Tj 1.3408 0 0 1 276.8 491.3 Tm <1E> Tj 1.3408 0 0 1 283.1 491.3 Tm <073507181507> Tj 1.3408 0 0 1 304.9 491.3 Tm <54> Tj 1.3408 0 0 1 308.5 491.3 Tm <070D> Tj 1.3408 0 0 1 314.3 491.3 Tm <22> Tj 1.3408 0 0 1 320.6 491.3 Tm <1E> Tj 1.3408 0 0 1 326.9 491.3 Tm <0735> Tj 1.3408 0 0 1 335.1 491.3 Tm <26> Tj 1.3408 0 0 1 340.3 491.3 Tm <15> Tj 1.3408 0 0 1 343.5 491.3 Tm <15> Tj 1.3408 0 0 1 346.6 491.3 Tm <0756> Tj 1.3408 0 0 1 354.5 491.3 Tm <0722> Tj 1.3408 0 0 1 363.4 491.3 Tm <0145> Tj 1.3408 0 0 1 372.9 491.3 Tm <3B> Tj 1.3408 0 0 1 378.1 491.3 Tm <0754074F> Tj ET BT 1.3408 0 0 1 393.3 491.3 Tm /F4 7 Tf <01> Tj ET BT 1.3408 0 0 1 396.8 491.3 Tm /F2 7 Tf <073507290754> Tj 1.3408 0 0 1 420.7 491.3 Tm <074F> Tj 1.3408 0 0 1 429.6 491.3 Tm <07> Tj 1.3408 0 0 1 432.2 491.3 Tm <35> Tj 1.3408 0 0 1 437.8 491.3 Tm <0724> Tj 1.3408 0 0 1 446.7 491.3 Tm <0715> Tj ET BT 1.3408 0 0 1 132.2 481.4 Tm /F2 7 Tf <51> Tj 1.3408 0 0 1 138 481.4 Tm <30> Tj 1.3408 0 0 1 139.8 481.4 Tm <07> Tj 1.3408 0 0 1 142.4 481.4 Tm <52> Tj 1.3408 0 0 1 147.9 481.4 Tm <0753> Tj 1.3408 0 0 1 156.8 481.4 Tm <0754> Tj 1.3408 0 0 1 163.1 481.4 Tm <070D> Tj 1.3408 0 0 1 168.9 481.4 Tm <072207> Tj 1.3408 0 0 1 180.4 481.4 Tm <54> Tj 1.3408 0 0 1 184.1 481.4 Tm <070D> Tj 1.3408 0 0 1 189.9 481.4 Tm <26> Tj 1.3408 0 0 1 195.2 481.4 Tm <0741> Tj 1.3408 0 0 1 200.9 481.4 Tm <074F> Tj 1.3408 0 0 1 209.8 481.4 Tm <15> Tj 1.3408 0 0 1 213 481.4 Tm <55> Tj 1.3408 0 0 1 217.4 481.4 Tm <0D> Tj 1.3408 0 0 1 220.6 481.4 Tm <22> Tj 1.3408 0 0 1 226.9 481.4 Tm <1E> Tj 1.3408 0 0 1 233.2 481.4 Tm <07> Tj 1.3408 0 0 1 235.8 481.4 Tm <350726150745070D> Tj 1.3408 0 0 1 263.4 481.4 Tm <22> Tj 1.3408 0 0 1 269.7 481.4 Tm <1E0735> Tj 1.3408 0 0 1 284.1 481.4 Tm <26> Tj 1.3408 0 0 1 289.4 481.4 Tm <15> Tj 1.3408 0 0 1 292.5 481.4 Tm <0756> Tj 1.3408 0 0 1 300.4 481.4 Tm <0722> Tj 1.3408 0 0 1 309.3 481.4 Tm <014518> Tj 1.3408 0 0 1 324 481.4 Tm <0754074F> Tj ET BT 1.3408 0 0 1 339.2 481.4 Tm /F4 7 Tf <00> Tj ET BT 1.3408 0 0 1 342.7 481.4 Tm /F2 7 Tf <073507290715> Tj ET Q endstream endobj 7 0 obj 33620 endobj 8 0 obj << /Length 9 0 R >> stream 0 w q 0 -0.1 612.1 792.1 re W* n q 0 0 0 rg BT 90 711 Td /F2 10 Tf <08> Tj 5.5 0 Td <09> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <2D> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <41> Tj 3.4 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <1111> Tj 9.9 0 Td <02> Tj 5.6 0 Td <13> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2B> Tj 2.7 0 Td <02> Tj 5.6 0 Td <05> Tj 3.4 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <13> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <02> Tj 5.5 0 Td <03> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <13> Tj 5.6 0 Td <44> Tj ET Q q 0 0 0 rg BT 90 400.4 Td /F2 10 Tf <22> Tj 6.6 0 Td <2E> Tj 4.9 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.6 0 Td <05> Tj 3.4 0 Td <14> Tj 8.3 0 Td <13> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <14> Tj 8.4 0 Td <17> Tj 5.5 0 Td <0F> Tj 2.3 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <1107> Tj 7.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <11> Tj 5.1 0 Td <23> Tj 2.7 0 Td <07> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <13> Tj 5.5 0 Td <2B> Tj 2.9 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.3 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2B> Tj 2.7 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <09> Tj 5.6 0 Td <05> Tj 3.2 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.8 0 Td <2C> Tj 4.9 0 Td <09> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj ET Q q 0 0 0 rg BT 90 389.2 Td /F2 10 Tf <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.8 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <04> Tj 5.5 0 Td <2B> Tj 2.9 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.3 0 Td <120A> Tj 7.2 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.6 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <01> Tj 7.2 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <12> Tj 5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <1C> Tj 5.5 0 Td <09> Tj 5.6 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <16> Tj 6.6 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <03> Tj 5.5 0 Td <02> Tj 5.5 0 Td <05> Tj 3.4 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <1106> Tj ET Q q 0 0 0 rg BT 90 378.1 Td /F2 10 Tf <13> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <12> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <12> Tj 5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <23> Tj 2.8 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <04> Tj 5.5 0 Td <2B> Tj 2.9 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <12> Tj 5.1 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.6 0 Td <07> Tj 2.8 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.7 0 Td <22> Tj 6.6 0 Td <01> Tj 7.2 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <0B> Tj 5.5 0 Td <13> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <32> Tj 5.1 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <11> Tj 4.9 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.3 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <4D> Tj 2.2 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <47> Tj 7.2 0 Td <0B> Tj ET Q q 0 0 0 rg BT 90 366.9 Td /F2 10 Tf <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <32> Tj 5.1 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <320A> Tj 7.2 0 Td <14> Tj 8.4 0 Td <13> Tj 5.6 0 Td <14> Tj 8.6 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <58> Tj 8.2 0 Td <07> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <09> Tj 5.6 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <1E> Tj ET Q q 0 0 0 rg BT 90 355.8 Td /F2 10 Tf <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <01> Tj 7.2 0 Td <07> Tj 2.7 0 Td <1102> Tj 10.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <09> Tj 5.6 0 Td <3E> Tj 2.2 0 Td <13> Tj 5.5 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <4D> Tj 2.2 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <0A> Tj 2.3 0 Td <11> Tj 4.9 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <02> Tj 5.5 0 Td <03> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.5 0 Td <05> Tj 3.4 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <11> Tj 4.9 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.4 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <08> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.3 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.3 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.7 0 Td <1C> Tj 5.5 0 Td <09> Tj 5.5 0 Td <13> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <06> Tj ET Q q 0 0 0 rg BT 90 344.6 Td /F2 10 Tf <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <31> Tj 5.7 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <19> Tj 5.6 0 Td <05> Tj 3.2 0 Td <04> Tj 5.6 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.8 0 Td <16> Tj 6.6 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.7 0 Td <06> Tj 2.7 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <09> Tj 5.5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <05> Tj 3.2 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.3 0 Td <07> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <0C> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.3 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <13> Tj 5.4 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <32> Tj 5.1 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <1106> Tj 7.8 0 Td <07> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <17> Tj 5.5 0 Td <02> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <0C> Tj 5.5 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 333.5 Td /F2 10 Tf <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <1206> Tj 7.8 0 Td <0A> Tj 2.1 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <09> Tj 5.5 0 Td <05> Tj 3.4 0 Td <09> Tj 5.5 0 Td <03> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.1 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <04> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <120A> Tj 7.2 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.6 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <01> Tj 7.2 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <11> Tj 4.9 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.6 0 Td <0C> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <14> Tj 8.3 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj ET Q q 0 0 0 rg BT 90 322.3 Td /F2 10 Tf <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.4 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.4 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <0C> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <05> Tj 3.4 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <12> Tj 5 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.8 0 Td <07> Tj ET Q q 0 0 0 rg BT 90 300 Td /F2 10 Tf <22> Tj 6.7 0 Td <13> Tj 5.4 0 Td <07> Tj 2.8 0 Td <06> Tj 2.8 0 Td <02> Tj 5.5 0 Td <06> Tj 2.7 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <1104> Tj 10.5 0 Td <07> Tj 2.8 0 Td <3A> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <12> Tj 5.1 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <3223> Tj 7.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.6 0 Td <11> Tj 4.9 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.3 0 Td <12> Tj 5 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <320A> Tj 7.2 0 Td <14> Tj 8.4 0 Td <13> Tj 5.6 0 Td <14> Tj 8.4 0 Td <23> Tj 3 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <18> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.3 0 Td <05> Tj 3.2 0 Td <04> Tj 5.6 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 288.9 Td /F2 10 Tf <12> Tj 5 0 Td <02> Tj 5.6 0 Td <04> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <0A> Tj 2.3 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <0D> Tj 3.3 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.6 0 Td <23> Tj 2.8 0 Td <22> Tj 6.6 0 Td <01> Tj 7.2 0 Td <15> Tj 3.4 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.3 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <0E> Tj ET Q q 0 0 0 rg BT 90 266.6 Td /F1 10 Tf <1B> Tj 7.2 0 Td <0209> Tj 9.4 0 Td <0C> Tj 5.6 0 Td <1C> Tj 3.4 0 Td <0B> Tj ET Q q 0 0 0 rg BT 118.3 266.6 Td /F2 10 Tf <3C> Tj 7.2 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <0A> Tj 2.1 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <1D> Tj 6.7 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <23> Tj 2.7 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <09> Tj 5.6 0 Td <2B> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <121C> Tj 10.6 0 Td <0C> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2D> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <2A> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.3 0 Td <05> Tj 3.2 0 Td <04> Tj 5.6 0 Td <12> Tj 5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <14> Tj 8.4 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 255.4 Td /F2 10 Tf <12> Tj 5 0 Td <02> Tj 5.6 0 Td <04> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <0A> Tj 2.3 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.6 0 Td <07> Tj 2.7 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <1C> Tj 5.5 0 Td <13> Tj 5.6 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 5 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <09> Tj 5.6 0 Td <2B> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <1C> Tj 5.6 0 Td <0C> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <57> Tj 5.6 0 Td <27> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <12> Tj 5.1 0 Td <02> Tj 5.5 0 Td <04> Tj 5.5 0 Td <2B> Tj 2.9 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.3 0 Td <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <22> Tj 6.6 0 Td <1E> Tj 6.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.6 0 Td <09> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 244.3 Td /F2 10 Tf <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <41> Tj 3.4 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <11> Tj 4.9 0 Td <13> Tj 5.6 0 Td <1123> Tj 7.8 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <04> Tj 5.5 0 Td <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.8 0 Td <09> Tj 5.6 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <2C> Tj 5 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <09> Tj 5.6 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.5 0 Td <12> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <12> Tj 5 0 Td <1C> Tj 5.5 0 Td <0A> Tj 2.3 0 Td <2B> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <11> Tj 5.1 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <13> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <14> Tj 8.4 0 Td <17> Tj 5.5 0 Td <0F> Tj 2.3 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <33> Tj ET Q q 0 0 0 rg BT 90 233.1 Td /F2 10 Tf <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <32> Tj 4.9 0 Td <0A> Tj 2.2 0 Td <19> Tj 5.6 0 Td <14> Tj 8.3 0 Td <04> Tj 5.7 0 Td <07> Tj 2.7 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <19> Tj 5.6 0 Td <14> Tj 8.3 0 Td <04> Tj 5.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <110E> Tj ET Q q 0 0 0 rg BT 225.6 210.8 Td /F1 10 Tf <1D> Tj 7.2 0 Td <0D> Tj 6 0 Td <09> Tj 3.2 0 Td <0E> Tj 3.9 0 Td <0C> Tj 5.5 0 Td <07> Tj 5.4 0 Td <0B> Tj 2.8 0 Td <08> Tj 5.5 0 Td <07> Tj 5.5 0 Td <1A0C> Tj 11.6 0 Td <10> Tj 5.6 0 Td <09> Tj 3.3 0 Td <07> Tj 5.6 0 Td <0B> Tj 2.7 0 Td <03> Tj 6.1 0 Td <0C> Tj 5.6 0 Td <0B> Tj 2.7 0 Td <05> Tj 2.8 0 Td <08> Tj 5.5 0 Td <0B> Tj 2.8 0 Td <140203> Tj 21 0 Td <04> Tj 5.6 0 Td <05> Tj 2.7 0 Td <06> Tj 2.8 0 Td <07> Tj 5.5 0 Td <08> Tj 5.6 0 Td <09> Tj 3.3 0 Td <06> Tj 2.8 0 Td <02> Tj 6.1 0 Td <0A> Tj ET Q q 0 0 0 rg BT 90 188.5 Td /F2 10 Tf <08> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <120A> Tj 7.2 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <11> Tj 4.9 0 Td <13> Tj 5.6 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <0B> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <1113> Tj 10.6 0 Td <2B> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.9 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <09> Tj 5.5 0 Td <1107> Tj 7.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <13> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <20> Tj 6.7 0 Td <0B> Tj 5.4 0 Td <07> Tj 2.8 0 Td <04> Tj 5.6 0 Td <2B> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <04> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <03> Tj 5.5 0 Td <02> Tj 5.5 0 Td <05> Tj 3.4 0 Td <2A> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <11> Tj 5.1 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj ET Q q 0 0 0 rg BT 90 177.4 Td /F2 10 Tf <05> Tj 3.4 0 Td <09> Tj 5.5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <14> Tj 8.4 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.8 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <13> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.4 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.4 0 Td <0C> Tj 5.5 0 Td <11> Tj 5 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <06> Tj 2.8 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.5 0 Td <2D> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <05> Tj 3.3 0 Td <02> Tj 5.6 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.3 0 Td <0F> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <09> Tj 5.5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <03> Tj 5.5 0 Td <09> Tj 5.6 0 Td <110E> Tj ET Q q 0 0 0 rg BT 90 166.2 Td /F2 10 Tf <16> Tj 6.7 0 Td <02> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <2B> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.4 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <03> Tj 5.5 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <2A> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <3E> Tj 2.3 0 Td <4D> Tj 2.1 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 4.9 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.6 0 Td <05> Tj 3.4 0 Td <14> Tj 8.3 0 Td <13> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <09> Tj 5.6 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.5 0 Td <12> Tj 5 0 Td <07> Tj 2.8 0 Td <13> Tj 5.6 0 Td <0B> Tj 5.4 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <17> Tj 5.5 0 Td <05> Tj 3.4 0 Td <0C> Tj 5.5 0 Td <1104> Tj 10.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 155.1 Td /F2 10 Tf <05> Tj 3.4 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <320A> Tj 7.2 0 Td <14> Tj 8.4 0 Td <13> Tj 5.6 0 Td <14> Tj 8.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <03> Tj 5.5 0 Td <02> Tj 5.5 0 Td <05> Tj 3.3 0 Td <2A> Tj 5.5 0 Td <23> Tj 2.8 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <4D> Tj 2.2 0 Td <04> Tj 5.5 0 Td <1106> Tj 7.8 0 Td <07> Tj 2.8 0 Td <33> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <4D> Tj 2.1 0 Td <0C> Tj 5.5 0 Td <1209> Tj 10.6 0 Td <05> Tj 3.3 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <09> Tj 5.6 0 Td <320A> Tj 7.3 0 Td <14> Tj 8.3 0 Td <13> Tj 5.6 0 Td <14> Tj 8.7 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <13> Tj 5.5 0 Td <07> Tj 2.7 0 Td <03> Tj 5.6 0 Td <02> Tj 5.5 0 Td <05> Tj 3.3 0 Td <2A> Tj 5.5 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <09> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <17> Tj 5.5 0 Td <17> Tj 5.6 0 Td <02> Tj 5.5 0 Td <05> Tj 3.4 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <33> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.1 0 Td <2D> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.8 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 143.9 Td /F2 10 Tf <3E> Tj 2.3 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <2D> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <2A> Tj 5.6 0 Td <3E> Tj 2.2 0 Td <09> Tj 5.6 0 Td <1204> Tj 10.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <11> Tj 5 0 Td <23> Tj 2.8 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <32> Tj 5 0 Td <07> Tj 2.7 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <1211> Tj 10.1 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <09> Tj 5.5 0 Td <05> Tj 3.3 0 Td <09> Tj 5.6 0 Td <03> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.7 0 Td <3E> Tj 2.3 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <2D> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <05> Tj 3.2 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.6 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <320A> Tj 7.2 0 Td <14> Tj 8.4 0 Td <13> Tj 5.6 0 Td <14> Tj 8.6 0 Td <07> Tj 2.8 0 Td <09> Tj 5.6 0 Td <13> Tj 5.5 0 Td <32> Tj ET Q q 0 0 0 rg BT 90 132.8 Td /F2 10 Tf <12> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <0E> Tj 2.6 0 Td <07> Tj 2.8 0 Td <08> Tj 5.5 0 Td <04> Tj 5.6 0 Td <1107> Tj 7.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <4D> Tj 2.2 0 Td <09> Tj 5.5 0 Td <17> Tj 5.5 0 Td <17> Tj 5.6 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <1204> Tj 10.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <03> Tj 5.5 0 Td <02> Tj 5.5 0 Td <05> Tj 3.4 0 Td <2A> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.7 0 Td <08> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.4 0 Td <07> Tj 2.8 0 Td <04> Tj 5.6 0 Td <11> Tj 4.9 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <02> Tj 5.5 0 Td <03> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <13> Tj ET Q q 0 0 0 rg BT 90 121.6 Td /F2 10 Tf <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <06> Tj 2.8 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <09> Tj 5.6 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <04> Tj 5.6 0 Td <3206> Tj 7.7 0 Td <05> Tj 3.4 0 Td <0C> Tj 5.5 0 Td <14> Tj 8.4 0 Td <0A> Tj 2.2 0 Td <06> Tj 2.8 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2D> Tj 5.5 0 Td <13> Tj 5.6 0 Td <0A> Tj 2.1 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.6 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <08> Tj 5.5 0 Td <4D> Tj 2.1 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <06> Tj 2.8 0 Td <09> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <1106> Tj ET Q q 0 0 0 rg BT 90 110.5 Td /F2 10 Tf <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <17> Tj 5.5 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.7 0 Td <33> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <09> Tj 5.5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <0E> Tj 2.8 0 Td <07> Tj ET Q q 0 0 0 rg BT 90 88.2 Td /F2 10 Tf <1F> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <07> Tj 2.8 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <33> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0B> Tj 5.5 0 Td <02> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <1204> Tj 10.5 0 Td <06> Tj 2.8 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <0C> Tj 5.6 0 Td <06> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <02> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <02> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <2B> Tj 2.8 0 Td <09> Tj 5.6 0 Td <1204> Tj 10.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <04> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <13> Tj 5.5 0 Td <0A> Tj 2.3 0 Td <05> Tj 3.3 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 77 Td /F2 10 Tf <13> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <2E> Tj 4.8 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.5 0 Td <05> Tj 3.4 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <03> Tj 5.5 0 Td <02> Tj 5.6 0 Td <1111> Tj 10 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <0C> Tj 5.5 0 Td <17> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <11> Tj 5 0 Td <23> Tj 2.8 0 Td <07> Tj 2.8 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <02> Tj 5.5 0 Td <11> Tj 5 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <03> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.1 0 Td <06> Tj 2.8 0 Td <0C> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.5 0 Td <05> Tj 3.4 0 Td <11> Tj 4.9 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <1209> Tj 10.6 0 Td <14> Tj 8.4 0 Td <03> Tj 5.6 0 Td <05> Tj 3.3 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj ET Q Q q 109.9 431.6 392.2 266.1 re W* n 1 1 1 rg 109.9 697.7 m 502 697.7 l 502 431.7 l 109.9 431.7 l 109.9 697.7 l h f* 0.90196 0.90196 0.90196 rg 153.8 687.8 m 431.5 687.8 l 431.5 437.1 l 153.8 437.1 l 153.8 687.8 l h f* 0 0 0 RG 153.8 437.1 m 431.5 437.1 l S 153.8 452.7 m 431.5 452.7 l S 153.8 468.4 m 431.5 468.4 l S 153.8 484.1 m 431.5 484.1 l S 153.8 499.7 m 431.5 499.7 l S 153.8 515.4 m 431.5 515.4 l S 153.8 531.1 m 431.5 531.1 l S 153.8 546.7 m 431.5 546.7 l S 153.8 562.4 m 431.5 562.4 l S 153.8 578.1 m 431.5 578.1 l S 153.8 593.8 m 431.5 593.8 l S 153.8 609.4 m 431.5 609.4 l S 153.8 625.1 m 431.5 625.1 l S 153.8 640.8 m 431.5 640.8 l S 153.8 656.4 m 431.5 656.4 l S 153.8 672.1 m 431.5 672.1 l S 153.8 687.8 m 431.5 687.8 l S 153.8 437.1 m 153.8 687.8 l S 167.7 437.1 m 167.7 687.8 l S 181.6 437.1 m 181.6 687.8 l S 195.4 437.1 m 195.4 687.8 l S 209.3 437.1 m 209.3 687.8 l S 223.2 437.1 m 223.2 687.8 l S 237.1 437.1 m 237.1 687.8 l S 251 437.1 m 251 687.8 l S 264.9 437.1 m 264.9 687.8 l S 278.8 437.1 m 278.8 687.8 l S 292.7 437.1 m 292.7 687.8 l S 306.5 437.1 m 306.5 687.8 l S 320.4 437.1 m 320.4 687.8 l S 334.3 437.1 m 334.3 687.8 l S 348.2 437.1 m 348.2 687.8 l S 362.1 437.1 m 362.1 687.8 l S 376 437.1 m 376 687.8 l S 389.9 437.1 m 389.9 687.8 l S 403.8 437.1 m 403.8 687.8 l S 417.7 437.1 m 417.7 687.8 l S 431.5 437.1 m 431.5 687.8 l S 153.8 437.1 m 431.5 437.1 l S 153.8 656.4 m 431.5 656.4 l S 153.8 652.2 m 153.8 656.4 l S 167.7 652.2 m 167.7 656.4 l S 181.6 652.2 m 181.6 656.4 l S 195.4 652.2 m 195.4 656.4 l S 209.3 652.2 m 209.3 656.4 l S 223.2 652.2 m 223.2 656.4 l S 237.1 652.2 m 237.1 656.4 l S 251 652.2 m 251 656.4 l S 264.9 652.2 m 264.9 656.4 l S 278.8 652.2 m 278.8 656.4 l S 292.7 652.2 m 292.7 656.4 l S 306.5 652.2 m 306.5 656.4 l S 320.4 652.2 m 320.4 656.4 l S 334.3 652.2 m 334.3 656.4 l S 348.2 652.2 m 348.2 656.4 l S 362.1 652.2 m 362.1 656.4 l S 376 652.2 m 376 656.4 l S 389.9 652.2 m 389.9 656.4 l S 403.8 652.2 m 403.8 656.4 l S 417.7 652.2 m 417.7 656.4 l S 431.5 652.2 m 431.5 656.4 l S 153.8 437.1 m 153.8 687.8 l S 153.8 437.1 m 153.8 687.8 l S 149.6 437.1 m 153.8 437.1 l S q 0 0 0 rg BT 119.8 433.8 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <38> Tj 5.3 0 Td <23> Tj 2.6 0 Td <27> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 452.7 m 153.8 452.7 l S q 0 0 0 rg BT 119.8 449.5 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <3B> Tj 5.3 0 Td <23> Tj 2.6 0 Td <57> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 468.4 m 153.8 468.4 l S q 0 0 0 rg BT 119.8 465.2 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <3B> Tj 5.3 0 Td <23> Tj 2.6 0 Td <27> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 484.1 m 153.8 484.1 l S q 0 0 0 rg BT 119.8 480.8 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <57> Tj 5.3 0 Td <23> Tj 2.6 0 Td <57> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 499.7 m 153.8 499.7 l S q 0 0 0 rg BT 119.8 496.5 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <57> Tj 5.3 0 Td <23> Tj 2.6 0 Td <27> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 515.4 m 153.8 515.4 l S q 0 0 0 rg BT 119.8 512.2 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <28> Tj 5.3 0 Td <23> Tj 2.6 0 Td <57> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 531.1 m 153.8 531.1 l S q 0 0 0 rg BT 119.8 527.8 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <28> Tj 5.3 0 Td <23> Tj 2.6 0 Td <27> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 546.7 m 153.8 546.7 l S q 0 0 0 rg BT 119.8 543.5 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <3A> Tj 5.3 0 Td <23> Tj 2.6 0 Td <57> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 562.4 m 153.8 562.4 l S q 0 0 0 rg BT 119.8 559.2 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <3A> Tj 5.3 0 Td <23> Tj 2.6 0 Td <27> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 578.1 m 153.8 578.1 l S q 0 0 0 rg BT 119.8 574.9 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <18> Tj 5.3 0 Td <23> Tj 2.6 0 Td <57> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 593.8 m 153.8 593.8 l S q 0 0 0 rg BT 119.8 590.5 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <18> Tj 5.3 0 Td <23> Tj 2.6 0 Td <27> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 609.4 m 153.8 609.4 l S q 0 0 0 rg BT 119.8 606.2 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <26> Tj 5.3 0 Td <23> Tj 2.6 0 Td <57> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 625.1 m 153.8 625.1 l S q 0 0 0 rg BT 119.8 621.9 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <26> Tj 5.3 0 Td <23> Tj 2.6 0 Td <27> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 640.8 m 153.8 640.8 l S q 0 0 0 rg BT 119.8 637.5 Td /F2 9.3 Tf <41> Tj 3.1 0 Td <27> Tj 5.3 0 Td <23> Tj 2.6 0 Td <57> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 656.4 m 153.8 656.4 l S q 0 0 0 rg BT 122.9 653.2 Td /F2 9.3 Tf <27> Tj 5.3 0 Td <23> Tj 2.6 0 Td <27> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 672.1 m 153.8 672.1 l S q 0 0 0 rg BT 122.9 668.9 Td /F2 9.3 Tf <27> Tj 5.3 0 Td <23> Tj 2.6 0 Td <57> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0 0 RG 149.6 687.8 m 153.8 687.8 l S q 0 0 0 rg BT 122.9 684.6 Td /F2 9.3 Tf <26> Tj 5.3 0 Td <23> Tj 2.6 0 Td <27> Tj 5.4 0 Td <27> Tj 5.2 0 Td <27> Tj ET Q 0 0.4 0.8 rg 153.1 449.3 m 167 496.2 l 167.7 495.9 l 168.3 495.7 l 154.5 448.9 l 153.1 449.3 l h f* 167.7 495.9 m 167 496.2 l 180.9 534.2 l 181.6 533.8 l 182.2 533.6 l 168.3 495.7 l 167.7 495.9 l h f* 181.6 533.8 m 180.9 534.2 l 194.8 564.5 l 195.4 564.2 l 196.1 563.8 l 182.2 533.6 l 181.6 533.8 l h f* 195.4 564.2 m 194.8 564.5 l 208.7 588.6 l 209.3 588.1 l 209.9 587.7 l 196.1 563.8 l 195.4 564.2 l h f* 209.3 588.1 m 208.7 588.6 l 222.7 607.3 l 223.2 606.8 l 223.7 606.3 l 209.9 587.7 l 209.3 588.1 l h f* 223.2 606.8 m 222.7 607.3 l 236.7 621.6 l 237.1 621 l 237.5 620.5 l 223.7 606.3 l 223.2 606.8 l h f* 237.1 621 m 236.7 621.6 l 250.6 632.4 l 251 631.8 l 251.3 631.1 l 237.5 620.5 l 237.1 621 l h f* 251 631.8 m 250.6 632.4 l 264.6 640.3 l 264.9 639.6 l 265.2 638.9 l 251.3 631.1 l 251 631.8 l h f* 264.9 639.6 m 264.6 640.3 l 278.6 645.9 l 278.8 645.2 l 279 644.5 l 265.2 638.9 l 264.9 639.6 l h f* 278.8 645.2 m 278.6 645.9 l 292.5 649.8 l 292.6 649 l 292.8 648.3 l 279 644.5 l 278.8 645.2 l h f* 292.6 649 m 292.5 649.8 l 306.5 652.3 l 306.5 651.6 l 306.6 650.9 l 292.8 648.3 l 292.6 649 l h f* 306.5 651.6 m 306.5 652.3 l 320.4 654 l 320.4 653.2 l 320.5 652.5 l 306.6 650.9 l 306.5 651.6 l h f* 320.4 653.2 m 320.4 654 l 334.3 654.9 l 334.3 654.2 l 334.3 653.4 l 320.5 652.5 l 320.4 653.2 l h f* 334.3 654.2 m 334.3 654.9 l 348.2 655.4 l 348.2 654.7 l 348.2 654 l 334.3 653.4 l 334.3 654.2 l h f* 348.2 654.7 m 348.2 655.4 l 362.1 655.6 l 362.1 654.9 l 362.1 654.2 l 348.2 654 l 348.2 654.7 l h f* 362.1 654.9 m 362.1 655.6 l 376 655.7 l 376 654.9 l 376 654.2 l 362.1 654.2 l 362.1 654.9 l h f* 376 654.9 m 376 655.7 l 389.9 655.6 l 389.9 654.9 l 389.8 654.2 l 376 654.2 l 376 654.9 l h f* 389.9 654.9 m 389.9 655.6 l 403.8 655.5 l 403.8 654.8 l 403.7 654.1 l 389.8 654.2 l 389.9 654.9 l h f* 403.8 654.8 m 403.8 655.5 l 417.7 655.4 l 417.7 654.7 l 417.6 654 l 403.7 654.1 l 403.8 654.8 l h f* 417.7 654.7 m 417.7 655.4 l 431.5 655.3 l 431.5 653.9 l 417.6 654 l 417.7 654.7 l h f* 0.59999 0.2 0.4 rg 154.2 687 m 168 677.9 l 167.7 677.2 l 167.3 676.6 l 153.4 685.8 l 154.2 687 l h f* 167.7 677.2 m 168 677.9 l 181.8 670.8 l 181.6 670.2 l 181.3 669.5 l 167.3 676.6 l 167.7 677.2 l h f* 181.6 670.2 m 181.8 670.8 l 195.6 665.5 l 195.4 664.8 l 195.2 664.2 l 181.3 669.5 l 181.6 670.2 l h f* 195.4 664.8 m 195.6 665.5 l 209.5 661.5 l 209.3 660.8 l 209.2 660.2 l 195.2 664.2 l 195.4 664.8 l h f* 209.3 660.8 m 209.5 661.5 l 223.3 658.6 l 223.2 657.9 l 223.1 657.2 l 209.2 660.2 l 209.3 660.8 l h f* 223.2 657.9 m 223.3 658.6 l 237.2 656.5 l 237.1 655.8 l 237 655.1 l 223.1 657.2 l 223.2 657.9 l h f* 237.1 655.8 m 237.2 656.5 l 251 655.1 l 251 654.3 l 251 653.6 l 237 655.1 l 237.1 655.8 l h f* 251 654.3 m 251 655.1 l 264.9 654 l 264.9 653.3 l 264.8 652.6 l 251 653.6 l 251 654.3 l h f* 264.9 653.3 m 264.9 654 l 278.8 653.3 l 278.8 652.6 l 278.8 651.9 l 264.8 652.6 l 264.9 653.3 l h f* 278.8 652.6 m 278.8 653.3 l 292.6 652.8 l 292.6 652.1 l 292.6 651.4 l 278.8 651.9 l 278.8 652.6 l h f* 292.6 652.1 m 292.6 652.8 l 306.5 652.6 l 306.5 651.8 l 306.5 651.1 l 292.6 651.4 l 292.6 652.1 l h f* 306.5 651.8 m 306.5 652.6 l 320.4 652.4 l 320.4 651.6 l 320.4 650.9 l 306.5 651.1 l 306.5 651.8 l h f* 320.4 651.6 m 320.4 652.4 l 334.3 652.2 l 334.3 651.5 l 334.3 650.8 l 320.4 650.9 l 320.4 651.6 l h f* 334.3 651.5 m 334.3 652.2 l 348.2 652.1 l 348.2 651.4 l 348.2 650.7 l 334.3 650.8 l 334.3 651.5 l h f* 348.2 651.4 m 348.2 652.1 l 362.1 652.1 l 362.1 651.3 l 362.1 650.6 l 348.2 650.7 l 348.2 651.4 l h f* 362.1 651.3 m 362.1 652.1 l 376 652 l 376 651.2 l 376 650.5 l 362.1 650.6 l 362.1 651.3 l h f* 376 651.2 m 376 652 l 389.9 651.9 l 389.9 651.1 l 389.8 650.4 l 376 650.5 l 376 651.2 l h f* 389.9 651.1 m 389.9 651.9 l 403.8 651.8 l 403.8 651.1 l 403.7 650.4 l 389.8 650.4 l 389.9 651.1 l h f* 403.8 651.1 m 403.8 651.8 l 417.7 651.7 l 417.7 651 l 417.6 650.3 l 403.7 650.4 l 403.8 651.1 l h f* 417.7 651 m 417.7 651.7 l 431.5 651.6 l 431.5 650.2 l 417.6 650.3 l 417.7 651 l h f* 0 0 0 rg 153.3 657 m 167.2 669.6 l 167.2 669.6 l 167.3 669.7 l 167.7 669 l 168.2 668.5 l 154.3 655.9 l 153.3 657 l h f* 167.3 669.7 m 181.2 678.2 l 181.2 678.2 l 181.3 678.2 l 181.6 677.6 l 181.9 677 l 168 668.4 l 167.7 669 l 167.3 669.7 l h f* 181.6 677.6 m 181.3 678.2 l 195.3 683.7 l 195.4 683 l 195.6 682.4 l 181.8 676.9 l 181.6 677.6 l h f* 195.4 683 m 195.3 683.7 l 209.3 686.9 l 209.3 686.2 l 209.4 685.5 l 195.6 682.4 l 195.4 683 l h f* 209.3 686.2 m 209.3 686.9 l 223.2 688.3 l 223.2 687.6 l 223.2 686.9 l 209.4 685.5 l 209.3 686.2 l h f* 223.2 687.6 m 223.2 688.3 l 237.1 688.5 l 237.1 687.8 l 237.1 687.1 l 223.2 686.9 l 223.2 687.6 l h f* 237.1 687.8 m 237.1 688.5 l 251.1 687.8 l 251 687.1 l 250.9 686.4 l 237.1 687.1 l 237.1 687.8 l h f* 251 687.1 m 251.1 687.8 l 265 686.4 l 264.9 685.7 l 264.8 685 l 250.9 686.4 l 251 687.1 l h f* 264.9 685.7 m 265 686.4 l 278.9 684.7 l 278.8 683.9 l 278.7 683.2 l 264.8 685 l 264.9 685.7 l h f* 278.8 683.9 m 278.9 684.7 l 292.8 682.6 l 292.6 681.9 l 292.5 681.2 l 278.7 683.2 l 278.8 683.9 l h f* 292.6 681.9 m 292.8 682.6 l 306.7 680.4 l 306.5 679.7 l 306.4 679 l 292.5 681.2 l 292.6 681.9 l h f* 306.5 679.7 m 306.7 680.4 l 320.5 678 l 320.4 677.3 l 320.3 676.6 l 306.4 679 l 306.5 679.7 l h f* 320.4 677.3 m 320.5 678 l 334.4 675.6 l 334.3 674.8 l 334.2 674.1 l 320.3 676.6 l 320.4 677.3 l h f* 334.3 674.8 m 334.4 675.6 l 348.3 673.1 l 348.2 672.3 l 348.1 671.6 l 334.2 674.1 l 334.3 674.8 l h f* 348.2 672.3 m 348.3 673.1 l 362.2 670.5 l 362.1 669.8 l 362 669.1 l 348.1 671.6 l 348.2 672.3 l h f* 362.1 669.8 m 362.2 670.5 l 376.1 667.9 l 376 667.2 l 375.8 666.5 l 362 669.1 l 362.1 669.8 l h f* 376 667.2 m 376.1 667.9 l 390 665.3 l 389.9 664.6 l 389.7 663.9 l 375.8 666.5 l 376 667.2 l h f* 389.9 664.6 m 390 665.3 l 403.9 662.7 l 403.8 661.9 l 403.6 661.2 l 389.7 663.9 l 389.9 664.6 l h f* 403.8 661.9 m 403.9 662.7 l 417.8 659.9 l 417.7 659.2 l 417.5 658.5 l 403.6 661.2 l 403.8 661.9 l h f* 417.7 659.2 m 417.8 659.9 l 431.6 657.2 l 431.4 655.7 l 417.5 658.5 l 417.7 659.2 l h f* 0.23921 0.92156 0.23921 rg 154.3 578.5 m 168.2 564 l 167.7 563.5 l 167.6 562.8 l 167.6 562.8 l 167.5 562.8 l 167.4 562.8 l 167.3 562.8 l 167.1 563 l 153.3 577.5 l 154.3 578.5 l h f* 167.7 564.2 m 181.6 562.9 l 181.6 562.2 l 182 561.7 l 182 561.7 l 181.9 561.6 l 181.8 561.5 l 181.7 561.5 l 181.5 561.5 l 167.6 562.8 l 167.7 563.5 l 167.7 564.2 l h f* 181.1 562.8 m 195 573.8 l 195.4 573.3 l 196 572.8 l 196 572.8 l 195.9 572.7 l 182 561.7 l 181.6 562.2 l 181.1 562.8 l h f* 195.4 573.3 m 194.9 573.7 l 208.8 590.6 l 209.3 590.1 l 209.9 589.7 l 196 572.8 l 195.4 573.3 l h f* 209.3 590.1 m 208.8 590.6 l 222.7 607.5 l 223.2 607 l 223.7 606.5 l 209.9 589.7 l 209.3 590.1 l h f* 223.2 607 m 222.7 607.5 l 236.7 621.7 l 237.1 621.1 l 237.5 620.5 l 223.7 606.5 l 223.2 607 l h f* 237.1 621.1 m 236.7 621.7 l 250.6 632.6 l 251 631.9 l 251.3 631.3 l 237.5 620.5 l 237.1 621.1 l h f* 251 631.9 m 250.6 632.6 l 264.6 640.5 l 264.9 639.8 l 265.2 639.2 l 251.3 631.3 l 251 631.9 l h f* 264.9 639.8 m 264.6 640.5 l 278.6 646.1 l 278.8 645.4 l 279 644.7 l 265.2 639.2 l 264.9 639.8 l h f* 278.8 645.4 m 278.6 646.1 l 292.5 650 l 292.6 649.2 l 292.8 648.5 l 279 644.7 l 278.8 645.4 l h f* 292.6 649.2 m 292.5 650 l 306.5 652.5 l 306.5 651.8 l 306.6 651.1 l 292.8 648.5 l 292.6 649.2 l h f* 306.5 651.8 m 306.5 652.5 l 320.4 654.1 l 320.4 653.3 l 320.5 652.6 l 306.6 651.1 l 306.5 651.8 l h f* 320.4 653.3 m 320.4 654.1 l 334.3 655 l 334.3 654.2 l 334.3 653.5 l 320.5 652.6 l 320.4 653.3 l h f* 334.3 654.2 m 334.3 655 l 348.2 655.5 l 348.2 654.7 l 348.2 654 l 334.3 653.5 l 334.3 654.2 l h f* 348.2 654.7 m 348.2 655.5 l 362.1 655.7 l 362.1 654.9 l 362.1 654.2 l 348.2 654 l 348.2 654.7 l h f* 362.1 654.9 m 362.1 655.7 l 376 655.7 l 376 655 l 376 654.3 l 362.1 654.2 l 362.1 654.9 l h f* 376 655 m 376 655.7 l 389.9 655.7 l 389.9 654.9 l 389.8 654.2 l 376 654.3 l 376 655 l h f* 389.9 654.9 m 389.9 655.7 l 403.8 655.6 l 403.8 654.9 l 403.7 654.2 l 389.8 654.2 l 389.9 654.9 l h f* 403.8 654.9 m 403.8 655.6 l 417.7 655.5 l 417.7 654.8 l 417.6 654.1 l 403.7 654.2 l 403.8 654.9 l h f* 417.7 654.8 m 417.7 655.5 l 431.5 655.4 l 431.5 654 l 417.6 654.1 l 417.7 654.8 l h f* 0.85098 0.85098 0.85098 rg 447.1 589.7 m 493.6 589.7 l 493.6 540.9 l 447.1 540.9 l 447.1 589.7 l h f* 0 0 0 RG 470.3 540.9 m 447.1 540.9 l 447.1 589.7 l 493.6 589.7 l 493.6 540.9 l 470.3 540.9 l h S 0 0.4 0.8 rg 450.3 587.5 m 458.3 579.5 l 457.2 578.5 l 449.2 586.5 l 450.3 587.5 l h f* q 0 0 0 rg BT 460.4 579.8 Td /F2 8 Tf <4B> Tj 3.8 0 Td <30> Tj 1.5 0 Td <30> Tj ET Q 0.59999 0.2 0.4 rg 450.3 576 m 458.3 568 l 457.2 567 l 449.2 575 l 450.3 576 l h f* q 0 0 0 rg BT 460.4 568.3 Td /F2 8 Tf <4B> Tj 3.8 0 Td <30> Tj ET Q 0 0 0 rg 450.3 564.5 m 458.3 556.5 l 457.2 555.4 l 449.2 563.4 l 450.3 564.5 l h f* q 0 0 0 rg BT 460.4 556.7 Td /F2 8 Tf <4B> Tj 3.8 0 Td <07> Tj 2.2 0 Td <54> Tj 3.1 0 Td <07> Tj 2.2 0 Td <26> Tj 4.3 0 Td <27> Tj ET Q 0.23921 0.92156 0.23921 rg 450.3 552.9 m 458.3 544.9 l 457.2 543.9 l 449.2 551.9 l 450.3 552.9 l h f* q 0 0 0 rg BT 460.4 545.2 Td /F2 8 Tf <12> Tj 4.1 0 Td <02> Tj 4.1 0 Td <13> Tj 4.3 0 Td <05> Tj 2.6 0 Td <03> Tj 4.4 0 Td <13> Tj 4.3 0 Td <05> Tj 2.6 0 Td <04> Tj ET Q Q endstream endobj 9 0 obj 54771 endobj 10 0 obj << /Length 11 0 R >> stream 0 w q 0 -0.1 612.1 792.1 re W* n q 0 0 0 rg BT 90 711 Td /F2 10 Tf <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <1123> Tj 7.8 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <04> Tj 5.5 0 Td <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.8 0 Td <09> Tj 5.6 0 Td <2C> Tj 4.9 0 Td <04> Tj 5.5 0 Td <1207> Tj 7.8 0 Td <17> Tj 5.5 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.2 0 Td <09> Tj 5.6 0 Td <14> Tj 8.4 0 Td <19> Tj 5.5 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <11> Tj 5.1 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <14> Tj 8.4 0 Td <17> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <08> Tj 5.5 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.3 0 Td <0C> Tj 5.6 0 Td <06> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <02> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <11> Tj 4.9 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <17> Tj 5.6 0 Td <17> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <09> Tj 5.5 0 Td <03> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <13> Tj 5.5 0 Td <11> Tj 5.1 0 Td <11> Tj 5 0 Td <0A> Tj 2.2 0 Td <07> Tj 2.7 0 Td <03> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0B> Tj ET Q q 0 0 0 rg BT 90 699.8 Td /F2 10 Tf <09> Tj 5.5 0 Td <13> Tj 5.6 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <1107> Tj 7.7 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <0A> Tj 2.2 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <2D> Tj 5.6 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <09> Tj 5.6 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <09> Tj 5.5 0 Td <13> Tj 5.6 0 Td <32> Tj 5 0 Td <07> Tj 2.8 0 Td <2C> Tj 4.9 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <1107> Tj 7.7 0 Td <33> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <05> Tj 3.2 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <02> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0C> Tj 5.6 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <1D> Tj 6.6 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <12> Tj 5 0 Td <13> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 4.9 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.7 0 Td <05> Tj 3.4 0 Td <0C> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.1 0 Td <19> Tj 5.6 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <14> Tj 8.4 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 688.7 Td /F2 10 Tf <2C> Tj 5 0 Td <0A> Tj 2.1 0 Td <04> Tj 5.6 0 Td <13> Tj 5.5 0 Td <3207> Tj 7.7 0 Td <2D> Tj 5.6 0 Td <05> Tj 3.3 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <14> Tj 8.3 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.7 0 Td <11> Tj 5.1 0 Td <0E> Tj 2.8 0 Td <07> Tj ET Q q 0 0 0 rg BT 278.9 644.1 Td /F1 10 Tf <1E> Tj 7.2 0 Td <020A10> Tj 17.7 0 Td <05> Tj 2.8 0 Td <0D07> Tj 11.6 0 Td <06> Tj 2.8 0 Td <020A> Tj ET Q q 0 0 0 rg BT 90 621.8 Td /F2 10 Tf <29> Tj 7.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.6 0 Td <09> Tj 5.5 0 Td <17> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <0C> Tj 5.5 0 Td <11> Tj 5 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0C> Tj 5.6 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.4 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <0C> Tj 5.6 0 Td <06> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <02> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <0C> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.6 0 Td <09> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <02> Tj 5.5 0 Td <2D> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <12> Tj 5 0 Td <0A> Tj 2.2 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.7 0 Td <1D> Tj 6.7 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <3C> Tj 7.2 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.7 0 Td <1204> Tj 10.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <0A> Tj 2.3 0 Td <11> Tj 4.9 0 Td <09> Tj 5.5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <11> Tj ET Q q 0 0 0 rg BT 90 610.6 Td /F2 10 Tf <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <14> Tj 8.4 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.4 0 Td <14> Tj 8.3 0 Td <0C> Tj 5.8 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <03> Tj 5.5 0 Td <13> Tj 5.6 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <11> Tj 5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.4 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <0C> Tj 5.6 0 Td <06> Tj 2.8 0 Td <1C> Tj 5.5 0 Td <02> Tj 5.5 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <0E> Tj 2.7 0 Td <07> Tj 2.8 0 Td <08> Tj 5.5 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <14> Tj 8.4 0 Td <02> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <09> Tj 5.6 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.1 0 Td <02> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <11> Tj 4.9 0 Td <0A> Tj 2.3 0 Td <14> Tj 8.3 0 Td <17> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <04> Tj 5.6 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <04> Tj 5.5 0 Td <05> Tj 3.4 0 Td <14> Tj 8.4 0 Td <04> Tj 5.6 0 Td <06> Tj ET Q q 0 0 0 rg BT 90 599.5 Td /F2 10 Tf <2A> Tj 5.5 0 Td <4D> Tj 2.2 0 Td <09> Tj 5.5 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <07> Tj 2.7 0 Td <09> Tj 5.6 0 Td <12> Tj 5 0 Td <1219> Tj 10.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <04> Tj 5.5 0 Td <1206> Tj 7.8 0 Td <04> Tj 5.6 0 Td <14> Tj 8.3 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <33> Tj 5.5 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <09> Tj 5.6 0 Td <05> Tj 3.3 0 Td <09> Tj 5.6 0 Td <14> Tj 8.3 0 Td <19> Tj 5.6 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <11> Tj 5.1 0 Td <04> Tj 5.5 0 Td <12> Tj 5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <2F> Tj 5.6 0 Td <13> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.6 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <07> Tj 2.8 0 Td <06> Tj 2.7 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <1107> Tj 7.7 0 Td <2A> Tj 5.6 0 Td <4D> Tj 2.1 0 Td <13> Tj 5.5 0 Td <0B> Tj ET Q q 0 0 0 rg BT 90 588.3 Td /F2 10 Tf <17> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2B> Tj 2.8 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.2 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.7 0 Td <07> Tj ET Q q 0 0 0 rg BT 90 566 Td /F2 10 Tf <08> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <11> Tj 5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <12> Tj 5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <1D> Tj 6.7 0 Td <09> Tj 5.5 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <04> Tj 5.5 0 Td <11> Tj 5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.3 0 Td <11> Tj 4.9 0 Td <17> Tj 5.6 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <03> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.7 0 Td <11> Tj 5 0 Td <02> Tj 5.6 0 Td <13> Tj 5.5 0 Td <11> Tj 5.1 0 Td <07> Tj 2.7 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <1204> Tj 10.5 0 Td <0B> Tj 5.6 0 Td <12> Tj 4.9 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <36> Tj 7.8 0 Td <0B> Tj 5.5 0 Td <13> Tj 5.6 0 Td <07> Tj 2.7 0 Td <36> Tj 7.8 0 Td <04> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <04> Tj 5.5 0 Td <05> Tj 3.3 0 Td <09> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <07> Tj 2.8 0 Td <16> Tj 6.6 0 Td <13> Tj 5.6 0 Td <03> Tj 5.5 0 Td <0F> Tj 2.1 0 Td <0A> Tj 2.2 0 Td <1207> Tj 7.8 0 Td <08> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <12> Tj 4.9 0 Td <04> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <1204> Tj 10.6 0 Td <07> Tj 2.7 0 Td <04> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <04> Tj 5.5 0 Td <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.8 0 Td <31> Tj 5.5 0 Td <06> Tj 2.8 0 Td <05> Tj 3.3 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 554.9 Td /F2 10 Tf <13> Tj 5.5 0 Td <06> Tj 2.8 0 Td <0A> Tj 2.1 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <0C> Tj 5.5 0 Td <07> Tj 2.8 0 Td <12> Tj 5 0 Td <02> Tj 5.6 0 Td <14> Tj 8.4 0 Td <14> Tj 8.4 0 Td <04> Tj 5.7 0 Td <07> Tj 2.8 0 Td <03> Tj 5.5 0 Td <09> Tj 5.6 0 Td <11> Tj 4.9 0 Td <04> Tj 5.6 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.4 0 Td <07> Tj 2.7 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <12> Tj 4.9 0 Td <09> Tj 5.6 0 Td <0F> Tj 2.2 0 Td <12> Tj 5 0 Td <13> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <11> Tj 5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.5 0 Td <0C> Tj 5.6 0 Td <05> Tj 3.3 0 Td <02> Tj 5.5 0 Td <2A> Tj 5.4 0 Td <2E> Tj 4.9 0 Td <0B> Tj 5.6 0 Td <09> Tj 5.5 0 Td <14> Tj 8.3 0 Td <0A> Tj 2.2 0 Td <2F> Tj 5.5 0 Td <13> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <0E> Tj 2.8 0 Td <07> Tj 2.8 0 Td <08> Tj 5.5 0 Td <4D> Tj 2.1 0 Td <09> Tj 5.6 0 Td <13> Tj 5.5 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <06> Tj 2.7 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <11> Tj 5 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <03> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <17> Tj 5.5 0 Td <02> Tj 5.5 0 Td <13> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <13> Tj 5.5 0 Td <0B> Tj 5.5 0 Td <04> Tj 5.5 0 Td <07> Tj 2.8 0 Td <06> Tj 2.7 0 Td <04> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj ET Q q 0 0 0 rg BT 90 543.7 Td /F2 10 Tf <12> Tj 5 0 Td <02> Tj 5.6 0 Td <02> Tj 5.5 0 Td <17> Tj 5.5 0 Td <0C> Tj 5.5 0 Td <05> Tj 3.4 0 Td <09> Tj 5.5 0 Td <06> Tj 2.7 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <0B> Tj 5.6 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <0A> Tj 2.2 0 Td <11> Tj 4.9 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.5 0 Td <06> Tj 2.8 0 Td <07> Tj 2.7 0 Td <33> Tj 5.5 0 Td <07> Tj 2.8 0 Td <09> Tj 5.6 0 Td <14> Tj 8.4 0 Td <0C> Tj 5.5 0 Td <0F> Tj 2.2 0 Td <0A> Tj 2.2 0 Td <02> Tj 5.5 0 Td <05> Tj 3.3 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <07> Tj 2.8 0 Td <0F> Tj 2.2 0 Td <09> Tj 5.5 0 Td <07> Tj 2.7 0 Td <17> Tj 5.5 0 Td <04> Tj 5.6 0 Td <05> Tj 3.3 0 Td <2B> Tj 2.8 0 Td <02> Tj 5.6 0 Td <05> Tj 3.3 0 Td <14> Tj 8.4 0 Td <09> Tj 5.6 0 Td <0B> Tj 5.6 0 Td <1204> Tj 10.6 0 Td <07> Tj 2.8 0 Td <2A> Tj 5.5 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <07> Tj 2.7 0 Td <2C> Tj 5 0 Td <02> Tj 5.5 0 Td <0A> Tj 2.2 0 Td <0F> Tj 2.1 0 Td <04> Tj 5.6 0 Td <11> Tj 5 0 Td <0E> Tj 2.7 0 Td <07> Tj ET Q q 0 0 0 rg BT 282.5 521.4 Td /F2 10 Tf <41> Tj 3.4 0 Td <41> Tj 3.3 0 Td <41> Tj 3.4 0 Td <41> Tj 3.4 0 Td <41> Tj 3.3 0 Td <41> Tj 3.4 0 Td <41> Tj 3.3 0 Td <41> Tj 3.4 0 Td <41> Tj 3.4 0 Td <41> Tj 3.3 0 Td <41> Tj 3.4 0 Td <41> Tj 3.3 0 Td <41> Tj 3.4 0 Td <41> Tj ET Q Q endstream endobj 11 0 obj 14014 endobj 13 0 obj << /Type /Page /Parent 12 0 R /MediaBox [ 0 0 612 792 ] /Contents 1 0 R >> endobj 14 0 obj << /Type /Page /Parent 12 0 R /MediaBox [ 0 0 612 792 ] /Contents 3 0 R >> endobj 15 0 obj << /Type /Page /Parent 12 0 R /MediaBox [ 0 0 612 792 ] /Contents 6 0 R >> endobj 16 0 obj << /Type /Page /Parent 12 0 R /MediaBox [ 0 0 612 792 ] /Contents 8 0 R >> endobj 17 0 obj << /Type /Page /Parent 12 0 R /MediaBox [ 0 0 612 792 ] /Contents 10 0 R >> endobj 18 0 obj << /Length 19 0 R /Filter /FlateDecode /Length1 15948 >> stream x{ xTչZkޓL^$ ψ2y I $1 ($L2afBÂ[ТEj)R9=VQioRZ+m#^j-&%Zwwo63{=_kZF &o˦m!Cu.(IyOw]K}өzT^Wo&Dn $>ygNȐ?nQ8G|䆆ȊvF_Z*!$9&3Zy'ΕfoU8! GkL?[B9_ !l8423Mffu8]q IC>B!)d/y:\^+diŕ7I4^ i@N^9$W 9$rVc3eAR/ʧ49,aϱ̀7%9AFN> # QP!)K>B*ho&+x$R%gq}Fе,y dr1 y x)y }HB2ɗP$20$J2~)ķ}BE#g*T췷+׮U,Sآ,u?d|3V,Tx u%V|˸)*!uj\vc1n%1|IMl$ tM"3]g&9G:3F:Gɤ; )Ƙ/2E,,;8),9d/`1|33 },VǙcI3& 3/r͘S#LСPl.vƒd9i! 3RdHtTa \Brqi(=&=rbLG#!]:^2ԕI3~΍gYLO2:VC9%]xNh-m'OId2I79g`^Usy/0?uf!s Kvd4 dE-tFLʾQѹc^{ XqOwN`,i#lJF)t8޽Ww_=b]&tSF`RL,^|H9.gs䔑N'94=^P h Kܗ|O73aV30f\4jP$*X F1J&lHPy(XaPLI͑f34C1PT"""P',G'hYa1a,MoFKsz:M8;eqz]˗|@ƻP*Qi(ȗvdPpl' d^vM<|h"Vd{cÎ`5b<BR &xc]N gfveGA>OoVo.D q#1$k%7Zɍ,"FGtjLeVn_@h+QIH*Quz쉞;XFp;g.y:V"w&$ )p'}t#VN߰i:N%Zk/?\rZٯMZipݱyHe q.0_wDTi\u x1|_[7H QҔɮi]cG ?\_[xs9XRTL'|dz]d"QKj ݘ_{隡~N>Em ?H@?H aQgȞ//` ww)($ClFrCpJ$~>ܟIqSd`OJBE )Мl@;Ewi>w^qxw+{mr-i/xgRǯ|0/<Fk5FcFe.9D3Y#.'ѕ/ӧLvbwtZvե|j_>o^H_G7Ks ԭ3v+mf,&x9m[h6f sP|l5 .ǙO +I168H3f`TӘ3Ǚo`jU^}K;975&xP ^""KƦH08hB1-!wF]Q/S%_[ջzZSVs;s;<]\LwRtgaV1{ V`jd`NY|l%@Naaϊ:81c%9YvΊa"vjA=* τK|weQ('!I 4C Lt4ΖX663a&OSi4MXǥ|r`&21X;sԼ͘,"YDK4d11F"cj"DjrX'X ,k1["SLAk0&<1ёayGwf]>ep6.ɛEw[X d;*^KW5KYp)1ʥ*¶]̰ b 9W屳Ttoǘxctjݎ曘@~b6`Sh0T"[y9&L[Zޯyc%KȚDi c&MeMElV`/K˥6VȶKO.J 2! jn4N)ƉZZ6pNvhEcRz>7FoBZQfŊ7_f RHR'!|+[#"ņ {ǜI=j׉azcwDɷᣕ|w'6hdSuiu44:״}T'ejڬ5ɴκ]*=ʞ6uXS &ьW4TaEHcacmkUSd:ns 7''[[gً;~Ka)Z.`͍nhNj*j O:iu}+J#G ;LXwbwm?z9T/4K t!Y}}Cl}F̈l)"pTqB-VOHDzNMj+^DzkE'Ync7Z;I8ރ%B:+4mMqIٚ+0@E)L3&\,{oӊ=G-O 󟓧4n܇N}8nnꢹ+$2g8"mC̮[!{%>+y%YiXm\mZ:_m]i[m_:vcskWd>:s(#Ktg _G=ȌQ $oNż޴%Ha}uaWmsjJdJ0+֓*LqLiv5eخavyEfYҬY),84i J`y2#ӜvF\+K. ?Rc'Hw|'Owc&N-Kc BQfr=TwQM/"VxLTc__v?YDҴ}-i3)Q%I%Ff5Z@iINr?nɃ%ʍ6,wZ%R% O)J2XS*^%Kt@5C)Ɛbhg9oq^;`?o&Ƒ{G9(1{:\꾀h+Gy{ɝiJSM#.v_j䶂w9֒5Ӷy )Cg)m53fWRZ^Y!=%Dއ`>ov;$c A߻eBnf$̶`Vۥ& CWKypR8c }l>6(649QGʹ8Xd}LѴ+D,g1},?1#C,WdYmHXsZVd>FY[C2v=qbRӮ"HmTJkFCJZe( !RmWY IY&n]9zaūDB^K " ڲjYo%r=Uj Á`3oH>m}J]kz *v `Mh4#ZdCFJ]֢<-" 1PoFI!"2 /S|&sae ((UH7O+8 [BA_k_P@Mk/xp S 468'mHC54tB>iѶ4-5pCf?`H @Vu!舮:A! uf$}A%T­5K鸱1 6\p.7h5nzkB͗ !*KKh{Jbu!#f;@`3zFHi \H(+&o;ټt? Z'ԇ[!䬵|pY0R懸zkIrLI:4og|aCەWGqB~,*m!Gk̷CivtCI+ SGMmE;pWD0noK 74 4x#J7|ܧ6t4Mol8ȣ[ʫ4,1lG09ۻRIcVG]^VTϮ-ңT) J =JZ^2JW+QWVH)-R斔f**R)WQZ%eEJ>++VJKT#rqTGUy* q_RZR(S]R]qFyJE^euIҼJb~eEyq"ڲٕH3σB E%Eՙx3ʼBϼʹrR Y%P< R%ғ7r:_VW]R^{PRRPW2/S)̛W#tqy i!$D4QV=BHrpT G '4L\-!<҈sWXCȯQQ~7n%r$b#|I$򫧣g'kBn>s!rIݿGYN,fZjN*&1A܏o{~]zAq.9:X'8)x .-S"p?<ƣ8# N+(hkr &԰G1phF|fwv/4aA~'aW-)+H/N~p(1Gyc!mB#~AO'|HUǍOH>W2ݸuW'mUik% MV~&aϨ[F̯#W )VZjN㶥ף#O6oE! u(CHxkXߜFxsM,EZO\ޠfZA'8Fh~ҋX"G١^W3B3GK!WV>4`SY!EA]]['2ǝm}y^DDLG3?g?mEOEPt֊X\T*۬FKԠR"͇4(/e|<+9Hg>[nFq. Y=g iJ+q3|6!OONmL{ i)4 tg2ݺ.^U&b#򄭫z0[<<,jr6P8}ܡhBO:Uxk\DzJ޿Prn@Ei\ߪw}oZ G-kwOZOR:Tn_}nM/,j'L8uMjE~JG.תݒCnYQYC-+ 4,oDk}:{M}[.ܗrܧ[<(,߮ߵqdNiڗ*\f<g-3Tv@UU pQ?eGGp/T> φ;=uWWw* Ξ)bgW"8vZߤS*JPTsr8{GpB9[f"S ^W*¿sM*'^ʫSW-f ,Z2 ?*~~>8^Q{?b?ʀ.x~*Q*.حa?ȆbYB]SggTxO=̞O8ؓc*֨Z{Wbjフ leܭB +b-ЪB*B*, -*UhVq$ܥRg>[ZVA=NTSV*a*|W侮h- -p[b2-0)χV5*9qV*PB<+SaJU;sUS`sd8E*OP gW!Uț nfp.vK<<3삙7LX*Pax6*L`a+)V<r=ʲUdl&X!ke9`2a܍lnb7fX aeb! 7BZ,D9G@0EavHE rC2NU$T x(1TW!NTp|pXĨ`%2 6%U*̤1 >qSFH\$K:@;oCt 67?ڜ endstream endobj 19 0 obj 9046 endobj 20 0 obj << /Type /FontDescriptor /FontName /FAAAAA+BitstreamVeraSans-Roman /Flags 4 /FontBBox [ -183 -235 1286 928 ] /ItalicAngle 0 /Ascent 928 /Descent -235 /CapHeight 928 /StemV 80 /FontFile2 18 0 R >> endobj 21 0 obj << /Length 376 /Filter /FlateDecode >> stream x]n@$, 'qџdąo_8G7s~mz*WN.Urji\v yoZ.}O}\zwSU ؓ| ׮^e^ʳ}=$6 D>n(٪KWVJ{[a]{baX}nL!3`&Dh N)ov9kfc+怜1ެyl+ "EDŽ1M 4}L S}l>@T'I9}}r6hm>JuunX)c\.wm3endstream endobj 22 0 obj << /Type /Font /Subtype /TrueType /BaseFont /FAAAAA+BitstreamVeraSans-Roman /FirstChar 0 /LastChar 32 /Widths [ 600 684 317 837 636 837 684 336 636 686 390 636 390 500 698 694 636 500 685 274 655 360 685 837 549 611 633 411 634 615 524 400 400 ] /FontDescriptor 20 0 R /ToUnicode 21 0 R >> endobj 23 0 obj << /Length 24 0 R /Filter /FlateDecode /Length1 29796 >> stream x}{|Tܻ{{7}&E@D0A#Y Y͋dCV@*ZڒZE,G_Z/Zj-(+=Q8%ß!\ ,P# [Q&5hƏn7Cу~+z } Ǩ 5(AB:vDoo 7OaT U*T.~塛=c6tm020߈P3zdI"AW=Ž؝!z-U= #-CkQBQclcO"5JB9 SK 0/.CG0_/Q]3fwo(>? " HdQ{I?i'F >G[7OososQn;7>˯qLBUj1 uOSNg6bhl |Wt5h[A'?'H|}VH rZ\WK8w]v|?39d*@$D#9D^!ocH༜-qq=04{(:w{;VssAj^ UyPjRS5QE+|^IWMNy 4;Z9QbSPyd **HAd(ZQ)!ڮ&Db8ſ&GՏ=hyK%pw߷;Ux=O\;׀C E F oGW(ѯ{o]`wgX(Qfz-ζztAR;P^_NT@$= ߎ `*Cau aż^rʴt9t-ĒXhjG@Ի-?Z|kx?3<+b8*Џs+zuxlI>v,\jjQ^Um_xfІ~G` ƅQ]7.AKq 5q|2e'hXG`m8q9: v`| Sz^_cPQ; m HƓ jMLFmǙ\Zt)jz|ƟHUsfgVrۘؽRxHayEx*F,W.bey%s y9پLoGrIOKMq9d[b6 zVjkR}ދ.*eo**ZT՞KZt. 4%6K _JW8^wI_6KS _= 7T쬖UniKKCڂ|tPTX;1CfA4*⭮T(Ul_TS4G6(.-eDKF ٠hC_m^t ƭ:>)B֥Mfr5ΰDû%M[=4on>dն7$\Ð Ub~!o iR%+[4)Qzg4%EG)5pcL6c.YrRlI(Ѥ zl$40FNӚT"2p&$M^@?`pT\:l^H)TeJCS[TjY!R?v5h£~4/l 2.f҂d,zmya=. P)QІQ$LN$-;Z[O;@rTg2ۓj:F_4u ޺K5I5ín)%L)X4iiJribZhG,fN)Yj֋y h8qH+1\*Fgpt"qي*V@@6cX ðY3 I$'iqY|9́IJ0. c J+ZԢFE6fѭ|^I'-C'Cڏϴq%/1 MI.0$n~MYM(vj7PMjN{RI+8EYEJ=Em2I0_$pZQ5X6N-D8=O^EA6b86ѝYTɱZhh JYخ#A5GtNO @Jz5>t7W"e>즊@+*+]Bk^U?E&&~NZM~AM-ҖaLT7cU:m4`u]>~12nwI'I$/wURDl^켛ܣGs~\/'U'̏h~BC%jPs: g'Q@\HiMK%Fr4U9+N4ox)TyblZ$asvAeR:^ J!oF/fW24fW}8{c c鮞;鹋d܌ñ?sB0 {kYl]k_lNGWTCrk9W_\WmtR*] Q'ML\ql2[9fƕT1k+N#X>M-0SCXֆapj7Yy%013W>GuO{~t'vU_M8 3}^CO{o<7wlG.NKDVI FZg$]E~ RrlTJu_4 d*3eޯzD{X> ls9J<Y4K%]{͕g}YARaAptMk9zAAtL.f*O%,i?X[FdFXEB T`<-Pl_p&A at}^?23d]6e.O+ؑkv_޾t-dM`iNf.#8nEAf!(=uѩ3Uj&OJxQF=+C 4ʹmWQU}RUP | W6J`!PZa\df, M +hbHvQqR<*~(b] ` (܍8Uj)x 2&ܲS+ OIDvBI?ؙ,}x Q k k/R[^Mcvwy`aÄe;O gs k !ÝdL*Yۘee!kbF][nXe,22}eROiF4SPkU4d322Bf?bۚ9w0K3'V{Wg2(05<3eW +˩\e3j31ܑb3Ԟ S5?(`匬rz y\e\V m=yFdJ>i9: ]9d!C,eBnzGwI32\O!)Ic=ހ]Nsv;;xn"Y3=ώ F89b36Lb%@pY.2N j==C2ԚD[!CCGvRW&'yAoRA[|6ݜ>Mchv  p6>eUZaR1YsU9k+[нɟ(qN~- P8a-//8E&iP&=ў KԴ%XePמRbwC-Y{?_1̲ku|ӱ񛯿8̥qҲKj~f-qfW,Z[+ XKnS}ΠʹWkZh\nl6 daMaذwEmBG=c~4ӣJ#8up(BB/89ú&ҶvƵv؎NTfIboslx].}\\ޡ>j0:p* =ʶ3݅qbcA .xKfYՓ _rx857w׎Pmo`G{eHZ<hjM=JMn^)>;I爓9O;ɇN|z zvx=> r({SfzdUVO%@CZ {'lIc'3/)_֦z}d׍ܼ'v^/Ϙ_1g1Z6ZRqڥ :Rg9Iնّ6fӊ$/9|ߎ5 5N2*_ĥKۓXS[HG/.ʋk WoF圻UX4UjPY>+MzܪI~ɐ+9 ,}"/l֣VjF>QفG ,8 %8kYZA̹Z Tu@+wP[.aq;-xWU6_zV񾻯.[aգ?;K8̒Tig$n!6bL2!1 õ&jL:^5V-9iqtwkyUz 1Y[y1Glш}Nt}2A‰7%"hNXU^Drm&ͣԔApX2[ҟ,vWu //͙ek+.{&Si [k[]w/_r={KT iArr{Y e2'72R`ɵ}]4I-`g59MaGV@dCYƈ&!`Z "E *xl<)?D?j9у.M*2H⃝mUWw6bSϿC>(ih#\[1ܠI) 4SLC3n<~l tI) X4^KS@Nﴜ]T:rP.v!QN+`5b9՟L nCA6#ŬԮrqR,xRӮ9)vlҗ",.ppc߹T ʚPY]?k9SOаʢ{HctghCm4{bx^P@ Q xS9/BHr$;!U('b伩ëo֮1hv;=ᜍC7[P(vI%226y͸{~m!3#[nxuꌥ+ !V73i1HA.^ǎN%z׹IH)TZ`Ev,E $vx(x9c Ot~w`8l_J;{5s"b؜]?kH"yA3l-ԑ酊ݧN$`? .Tl}/}UۣIt^JGe Y˵,hݻp:CISROsb(w,/}Xs.YvzZn킋պkp.bǒeE p7onq%eEk~ذ4#g#@ ?OQGՓj^ϋ%ox=Nx˘ۖ2ݴvF<[`7": -k/bK9rzKݑ k-뽋;+bz񊎊_ʊUe>qRuhՏw>˴7<|snefӒW != dE( j>iVMګ5wG܇ԏOGs5ܢzhx6w\;XJBJ=E([ydA<l R@@QkٿLʖ|+튩c8Y>B,$rjpn؟Įv:Ȟs\?and]ŵ^>`Nzdz%: c'Tί,}}q͚WsVaER{={lv3 l=+ 7@cެěJ#T#>iCg-! ބO 'iDgԷIce.~ JGߔˬ$`*ҖjCmyύ5Ɏ@Y{amR9em>Oŏ dLuɉ &ѸXs!,6yV36>ޔOܬ?\0{% k;Ž#]Ҍ-K eerpsW_;n.=E6ܸ1u}Z}0zHx9wWŲ'*+fTƪ;FY{ ]qU8Ub8 RO2w[).).-~jx7hnvJCɅ .J"Wn(O Vs ˒S*ROzT ^e&WYrFlf/t~γ%)z֬}pHܢZߌky߿rؙ[W~Kdž7m=Pml؛kξM=ͱG vr/Vdȩ5.ΡࠌƬJn<&B91 yBD(%6O_b%TXBvɺz]БݤHbiDS ecCC@,a1fB'2Z[2,#JEfU؝g5/-^ 0.)]f |AJa@s%=ͨ~{M󖆃Svnf;rjt{W9"C&3$@$ R[=#A 2 'B>yJ" h# R#'<&I%']6 [ljFzm^@ӧerHNAա3l9SM=X6[}GU(r Z׊8B>,UDu@c-qdʫWK$^-q gg_%HŲr_APWNi@-0u=Y.T9"T_$!Cթ٨}3-Wc1)^1`CHP5Y~^CqXIpGKA?W dɾݣ~Y9s81KrmAՠxJ7\$R 9J ߫[|N7JNmGr&Pj :,5Fh ֛*6l 9r@˙>4E"b8%g$bm`9*M'@Zn(1!q}Q[4ؽ$_nW6o/*ɏF6?JR/;=νWDk{?Yb_;_+MӸ4۸]>뻹]{@0>aql%Z:}WR'HjH<r \ iԹ6Cmu.z'@ҩ֢媗]B:t7CN2|]p7<D(䘏$\-7}BЯ٢@B:H{aCܸtf[-^fA<#|E +]zjD=ƔriDJ'H5 Ρ&lVppUՀߡz?#} .ark9IuhףMOhUp#tŴͶ)8F*sě+8KGZs޼EՀ_`ޣdƢRp- Z+Mzl7%Z :II0Ontܭ{?ө<}nFSI} =~ KY@#A^Shؼ.QpZVm~5Pĺ6.F@(TD^8̓Pft!`լ>SѴdj.48M3u&ƛS VGd0~v P.acA΅hih-e`Zj:%}A~h}垷 m,gi؏::\Ԇ@[a)d:Li"JkgV@ `= ATCVxvqL}@RQ!&qÊ0+ +YK'bɟ6@>ȤNX$UK$),P_LxT龝y6l)}lHY KL MFJ=#:m}CL7PP&fK5eyZb}wJJ=UvDH_@!0DmJ 4e+iSI=fe԰2z=h(io*3 3AV.&}b*Lυuf*Eڠ6$eN鬝& +6dO^ެh;L2[%Cb:lSfVb4}l%q&f2ۻӞEW2Lꛛ;]rtҌF># |n~mXLfm)Rnamwx:=#JHfgY$f imu3mUuzScIۃLt %aSO|) ASȨfGB.a Z| ai# 1IІf"}#Q|Y} 4@N}B jೂ6"ܦhjd4p_$>E3>b3SvZmӱ-3h3q4~JPFKh:&ڬFWf%nލcFfbtt )+.4,~Dܡ5 BzY_]n`1!2=JP6չJD/zGm4Y4v)Pb?j ٭_EH9e>s%wI4VN:%{fŶqi$igEgg5EfOU9 1_Ŭ9:g({6qBdwN'!lV"jBUէL=ׇՌfc-7u{NH9%f81|L:N}h3; ٧WasS̉uYbh -/C Q4{{|gj+ƭ}`[HVFJZ{{B: ohgRCo J .iuxcgd@ZoW]Kzڧ\j$Zpmv]RDYnΐ̦`F`URoǿ\m DBv)#EtMTH>qP KP'Ns:*$U=)o[ ] uvipPjD@U JDBT@ wHƞ|)16 ?$uv{@|3li@!6Hж? j B0PlJWt=!i(djm# H(u`.2ꉄC@`Biws?􇂑nh m`:c1(A=6Ձ֮lMPo=*6 @ {iP'\ uFz!F>(u:'-$ʒB[`2ݡm|b( i@ 86p)ЦA*`տ SaRz3 ʘ{B;1xuEJ@_Wp+r} 혒v ;#EECCC݊vuF#u҉a(!ƲrUeKZ).^feCTuꚚ5+ Z:5bjfa=cLawrQo=upKp`_X~=@ QO,3nл.## !N!0\j?;wg&b$|` 5kBSB#Obz95](a>uj0'%r{P[g.{Q`{{xe?閭  n2dCP7t:8WB ?op^ECcfr4zm a {+r3vXCáD)X2}&Mb-2cc:"ue"O3(^ FR5 U ,JesEqMTϝ@^6L*_Z^ZnU/#-)uՐrHGُYmAl{vssKJMcvR^䞅s|mk/_|_6 |mk/_|_6ï ?{h`[{Y9_lEsj{P } AݹOm:_Ǚֵ M6綟R쾃VlT?a/|~/u|l7Lm擨%<hf)gӫ>'zlA%ڧ]7uoJ.C"m_3 i4 0RoqChe(hp!9%s&̇AwjSD#9jMbd17VA" |d,=屩9S)Cߨ9F;.44rC#F!_P(Ug'1E'?xUy:[O~Fal4nR7x 'xh#8?jɒFE RGX%UYyJ.~ 0sde|$|EPin26j"DG )(JϐP ~oԗ|naId4mҒo&c"+ypvg=A=LΒ }\qVqA>Nʒ 2iTe& (, 9 ii/V9yB0y4*h$}lH"!}W!]j"! A>>}}>rG+pG+hVhVAmVQQ8ꁣ8G=pG=㐁C8d! 2pȌC8dQ Q Ō88G1pG1㐀C 8$!pHC 8$a3p8a3pg8ǁ8pgǁ8p8pd wrXQrXQ`9XQ`9L=”AmAi$; ; w $(pD#8(pDG8e#1#18Fc8Fcq0D9N6 7i`s%;p. nCdh_A;18| B F[Ge*;UCꅴHBAR97 YAu@8.zzYHU(t+˷C!$D dX%  l9%}_y<\% 1" do2_bL<=$@A R HYܬ. g eC@nբ'_ãGWxz4{JOlz Ox`}?h.ph*^ޗu~ g=]辥`\_obCwJ19ɽ]p,u_~qy)w=t f50kXr_ oY3T$1z>7/kql2aH !]iƨkF5D46~˕65jHӜgМ$~` AQ4#u Kp]t m7xDZuQw ZP]ݸ_-E˚b|K3Fɍ568>#1c_onFNJgu(I& cXE}>FpM^ :rHf1,Z4CN8)y"٠uѼ|!jn©:cuEf<> ~Gpcwd-ܺ2*DRKzh/,z& O)MпPf%l)dO֞=e#Y##ej A{JGq(Rfo0޷G#ϫگ>Pb^X)$P8bTXX c*o; endstream endobj 24 0 obj 15723 endobj 25 0 obj << /Type /FontDescriptor /FontName /BAAAAA+Arial-BoldMT /Flags 4 /FontBBox [ -627 -376 2032 1047 ] /ItalicAngle 0 /Ascent 905 /Descent -211 /CapHeight 1047 /StemV 80 /FontFile2 23 0 R >> endobj 26 0 obj << /Length 363 /Filter /FlateDecode >> stream x]Mk@a!ـC?0 u]VsWmBEy}᤻Ixovh*Diei!qK]GButC~5}m\[y?vY:BxK8Ylj8ZE,*UWc'= u\(jיϵy{oOjy4)  FS7dk}!|?YYCZOC]Z-jߏ CR2!b8b$C@2!#ɰCi{$G'g( DYQ  |b$yO>+H;> zO2'E|" 0>Q]zgfh.K^龱f0ϵendstream endobj 27 0 obj << /Type /Font /Subtype /TrueType /BaseFont /BAAAAA+Arial-BoldMT /FirstChar 0 /LastChar 30 /Widths [ 750 833 610 610 556 277 277 556 556 333 610 277 556 610 389 333 556 556 666 722 889 277 666 610 610 237 610 722 333 722 722 ] /FontDescriptor 25 0 R /ToUnicode 26 0 R >> endobj 28 0 obj << /Length 29 0 R /Filter /FlateDecode /Length1 41516 >> stream xԼw|e?<ٙ^f7eB A+Az'4ATN vPCDÊ`=S]CN>R~￿yi;3Sޟ2`IHAAY3Bm¢4"O;e' B\ӔK&w+!Bߙ:iĪ-Mi*lx1y`=w] o.9g?u`>5~cqX?kR'ߛ;gͨ0Ѓ ?wޤ-yEm D?t0, $EYP8'ƋڵPܱSE.]nVwG^wS5j:lF"/>9ecoi-nmG;4p.t57Deh-hrf=:ǎDȅ= ZTZ4ݍ {'@l47FIݟz=0oڐ N~>I3@3~i*pchzI85%+A t!qI˘+ORJat>$̍MդN \c1ChS z w>t<"0ɶjJhR=sNJ8[9PG498kr;L+lԍ tR }}G2KǞdS@n3νpw.?VE%%7'$S_"'4{3p.Vv>\@qx:n_‡J?=$`s{RNn$`L" d4ɯ d >L,`0&sE2L)Vf6>8v!8 7{YI& p_P#ڇ^^Yf%Ӌه!K~&258lrLr|WD8J.L cx<4UQ+{]żo'? ڃk)f4s 3VnJcj ^aqPy4hx ~0\fR!*; j9^)Toг lw74v=fDt83 aG)ZN2y$yasCTh jHDKQx beςv[ƔahWV :m?HAݙ|140m=M Z]#-h gƠubNASϢRS胵eW^Nކ HxכzڑS2l؃%uPTژ;4Ct:O\/s&ݩ\x3hpT6L4F/n7TuRٹcqyhn$'f>r:6f1IDX`T+һ>obc}x0 M!4B=R#'בzHX UvE^PӉP =x 5P/Ԟ&\{{6="=&n]ܑ6:ݫnDn٫I?v^=p]&cB&7A=4=2iiІ#7h212qQM:z k۳ɽ*Ǩ3{ykCM~o.7\]7\z#\ՄW%CISoRR?=$EnL]?Ʒ YRgWhQpS?R7g`dWy]n͚&n%Q;3zUbzG~M !Qxt13Z?3: g5M$_uM\T"-|T .哫B"BSnzyE-$Z.0 -:VJ-=Hk"tϑ+{+{^Nn6I]Z4.M{RzG Z_maYK|u_d1Lc/0ثӕQJ/o0A4P&ozY''ӳilz߬ 0F_/fZ2 p<6*фdFے:ҙu&HփޔÝL>;E~}H[RDBZdr]?WiIo꽱h5wi6' fB yH#= Y`ayaQGvjv UC_ akv9s GGN<(-6:FgOge_|eОߛWfYyeZdZެXz?eZ_MYybjyAufVZ-V"5\2HU8$>oF y<Y ̏P\&7!DvOȐt<@ &J[e\UVwZs8\;ֱ'W>(ˢnh].7ȜBy+9Jf=P8`ΆYRk\naړX$b͝:"'c,}냚R=]՛>T;8%~0ـ;$-dJ+]Էl //zMO٫#:q ?M˴..rO/g,7V%l ,n4Qe;%S0øae&3$Tdwɑ+shY !:c? FʊoE::*(O&ZCSyjC: {1CUmąyP5Ɠ"͵(ÉRk0['N'Mssoz#ƞh幼>>)Bnx0XDo;taE1\ȼ+,ZUpJ{IꅹBI`hmBpD8%A2ypݓӏJԹ Uˡkqjoq [# xAhU,Zj}x~ZIO 03yƶlO4Ju rH m!f0wkX {'HM %|T{$U*Rw)WPi5Pz={2}bOvg{EeleQ?o.>Y_UT~Q[+̘:䖹Kϸ9 \m׼՜2s[ͻ?9<<8ʓK`` kQ4BZbZ,+qtLlU$*q;*'|5O0^hՀ.&Z/T}sT¬TZ|Nk(ޣTbe:USy!]B^7R v\M^0 j߷|)׺Kq :+p#99 a9 µ(h ab=d BC^ Sv U%xP^|aǞ$Me gH ҽhYV [7kyFq.j)p6~Lj t8hq 3[3%y7Dy㟱mNխ|dvpk @T*$qhZv!v>Ÿ^MyO8ANXTj8Jt[1DV:e.ʝA81\Kq,L4_28WZ^#<5cJO<JlΙ,|}?H6\p\-52 ݯψafWǤ¬XASeO]֘FLLN.X[5/wgocֆژ׬՚3eK^DLzPs. {_Cq?kP9C\oShPm%X ށ΅p"q] r﨑Ӏ Pm x[Ĺִ´ek(exCVtH Ɩr}x6GWPaz~^ ӓD {W'mԿ|2g`AVy_H<}rGy|˨}?'ɻ?6q)~ ? ƿ^juǰ7Lן?f'+mchP{9/}Ow4>y_=g>z͝o'k(Jn]ܿc7' J+cMctq4]nLWcyXn^nAriblbp4'?ܟ`O;S̕^-X9Z̋*2 Ŝ}@;;λ{[93^6{x္iXDç&ʉUF[=ha~l,p l)ۇ}^)}#‘/*OB_Oח)!%%E\K o+|뼁(Bu5g8$Υ}܃#(fl]c5GR\;X6G('*byY?ֲStB#)8;=>]ow?BaV֞)ꕧitn2WmTUI}R(#9gee`jQ=6m# Y,&I{`K9Oѹ)`/=)` ,H˄Ȩ;ҹuޅPHZ+;h QmeR3U~|t?k_wyW^ӫ߃W_>"&+w=1||j3Jg+t`HzQ\Re 8W yk|OJW#eRH:(zx=W]Q>V3ȋxUH~DaCaJШrCk Fщe l<͏65|>m z:R @q| 8&@R;({='}*}] HHbH0;&u#>&MmQu}&+>Ot E4ŧCheXkon/LPkhkRϯUh VA ̊s(V? [I}g妋AA¹'Jzy+e]c3uyɞŋkBJJ>׈$k$ Xɂ27[fb~= "WJFVܐt5'Y׏~RJqk'Yg8Hc6lFn}m1aNM_x>h -;9{eS[J^0K% CS#+pGZ蝺r]Cܫ!ùOSg(KmKw۾}?S^5l'~-eiAC<RgZ5  0jPk!Odgtp(HECd%] wj2!+K\ݽ`%Uڅt<-qjm騵yv,;%伨3wlBASj >G}psGܹ{Մ#j=~wzw>}>Xl71tVPnl<7gkXCFܢ o^71/[#p!e!:SNB=:a{m8;JI~(w7^E4ρ7= PZ`y*Q'N~gieѶ[,ЌvBdHbhz3%UCmh(GH#Xi'Atzl$6ڬҬM$E89US x4EDlV+} , 8oMy M5e&A81WVi_R5kǎؕ ܿ2iI]ܹ6FacA  a^Et8j^"K`M*Ac/UO\_gP$?&gJ'7|m?ylbchRKO^0&h.pV=\&Ė-77Ck ac ,˱|ԇ|;y|+P>q Q,U:%I%Cq}cieaX +0Qwϰl'`bGdB2ۂ-{=2oUS(۫@^Q 1ib"-&/}P"&VUQ1R_RQV$feUɪ=!N'!y1>udO mأUXSf)!(^9E pT 8=qΰǥDk_" `ø)m"^jH}@Dl9Ӌ9p/g\:nѪX %  >"aij%7.2׵JXqW('CsR P<ը7 Q3*Z-zHUGԿyڻm?mkozCpcS߰ U |fpW^9Sd;o(S'ݜrI.d)0:4"2<:4]aYbZ.,Ώa֛R[V_l Fsͪ ~QY8x.ow/Vjx.@\m .N|7I1T |% l(v0&9gnO016Й3ujARNR?>fDgdF~`Fnl7y~hخəM_5AMOTvƟj\c'67kJ=>^Ԥ9MJ{VTZ:#E O_<PF?};p3QR+wwI#yRj&Ȓ9XpBsIp߅d$JD0jZ}Jk, ЌK0Bid6FR?v^C"aŒ=PŐȨ_h{O?(<'{x[| |':Zm>A | c*cf``.P: qh6\H_GK?miORDȒN̉ b5c@Ti>;W+Bh^˲##"#U?ͷ+7i\+ $n  0Q0: jO)`F*׻37"Ig4i+}fᒴn=0Lbߞ?y{G61;|7}c=FwN`݁I7?[wqkrM9 J,He~;Pa!BC+ ϣ!23]82}hsW6ۙ/Ej鲳m2%e4_1j- DEK#qX!-9K?W)ZzL7s8ἦ 68j2ɨ_np \ja{[e/yk Gk~5!p]0`軅גuu7͜$<}&o0XX ai}s޿/2-7=Ǧ,>_AUuϗG_LcDMʃ)+PH0]h@ u7|wf`]6FCy1F#V E{8'>\r߁˖q^7:L&s?Sub> *wR*+;7n3@=03EUbX8,sB""x.#C[/ߢge-BW='R&4˅MhUQFB3Fp G<~!^}mؖjBŪ+%,kbI# RC7V29*bT9T4V*zR @.[R~bmywǏ7'goz&fNN}- Z dz ud5UY 3Y}]=e;jeYB>ZeQG8F:Gxr3nm=p$C#ޯ_9~tQCΎh]ړ\ )W^joGHy:E+`ְ1Yյ:Z _IR$yұ-;m p3o[Ě7^zj+fN̿&wzwGAhtH-޹GGS&/륌.UFd$qex$ou`Gʮ(r?N';fr l\)0>"AA"XY hb5:4+/ ^l~d+q1V_U\"s:$ٺsр%Cz<ѥ` ־եhrNۗ,,Jʗbr%*>su(i2LӤV|+Y".nd sN\/=H/'WnM'4H| ]dQL!nsqI-QJCdM8YFr:p ux#.5eh}:fz":1}> m \"]Xy5dc55"r*WhR_Jùh'lmՔ9un(^o2q"S1KYެ"SQ4urd!2M5*4uth[)ܩwWi„Ƣy߆guxg ݜ FS b#وSV.׻sEPd4Z*G=SnuwͺXpdj9i9cIYlKexE eWr\TjlH9#bN۪mpDQi"N./Oe*`:/j>Im=|Ko-8i| 4^/0y?#H@Hk ` ]2(B,2.հT-ϔ䩝Nj!)ߖo몳lӜKERRjuum.yvz'Mő mYm6UndXUd$m6E1LkA-@:^ @ g6Bjn#lڈ߸߂sP/Lw,!be*)OsxXR-쉃F`qx 5G+ 9Jr魌&ȧg~L,U>f`M6"j-XzK, w5`k SF:~c J9'/.E JN#bׁ=%|_{0;O~:XF3{qQӝc0Aބ 7.9UVV{LbHN32?[L/ [wG{gWr% ı cX4bEL(̃D(I QX*CQY`ٰz#[:|:_79Nr.;IY \JjR_K?QNd,Y"#וZH%g2fOVeww{•|8'\)+"*(In*4ga ^|˧{otw$'S|c饤..@oFoR&ktk叕2 4gojN4$4AGst/ٮIϲHqhd\l\vSĩܙǖ +#C\cURXڮ[II|tDMmp0\4Yw5?SS=_wt؂+OٱFBVZ8 AՂ4PF5A+)p6ޫ0^8D3(]xjĤ_0jbTx.l%/2ٺן(\白k&j}/_3w+[y ӎW.Zܮ qشj}m3{cOrOSYZ.~dBl4["lN2+d2rtúPZB.Q"tdy|o߿ۓ:{<X?>{~'7vlcrsQ&Q$ y X^470!ʫ/y^cˊd,{cW 5ZbOTѺ+\UjJNO6+1-e(D=jV,0찇Xa0aEP Q. 5yW>F.Z_x MIrk^\V ߲ꣷ;w#/ⶳ71=G?} w\\\=otgOoh۰ f0QnZ . >?tY js^( SZZUujJͥRTfQH4m*)Rs+n!{+ː/~늪2&oDҒ1J%[\ _ϐ̥~3Ft~ ~xJsۭV}<]b==mKgw/y}?^w׵<* hJq1jA ݱH/;K7׽g8ča;1t/+$+*3p] g̰0v02_!|Vt"3D%:~q}tÚ;pYnI<\2c|N{}) RiTKӑF0#e}V7z29w1r6^rQ+[ʭ8q#zʙƚV&nOQԨ,o2lSi1y펝J 1P3QuRdq5kiZML,j~,t5oᴔivɚԜNK?؏~!sٱ Hȉ1jp!k?MFk?J ӊ,8f1Y16?'|+XgNE1S]nf{w41mv1yfjasU`ϋYZα6}8@SWEJ3p ĉϝ8AkRߐJCG ={bA~f+!":%oJvRh. Nᤕ;6%GyJFq/ón]8p![ cX+-eZ +]A-cyE~kX&dm3! MY\ Ÿ ]ĮL^j>֛lc,Cl3L- A~O%)dGj9ߒg*lk-̃sx;nzVهoJ߲Z]6(e8IEȚjiI![%O,[̡?Z1$Xm8'8eEfEEN39D`cEU1Uf(&Al΄츨^/B1 ϑWDn!uiϱ74o2__lB"iK4]ۜa!(m&:>7eլ9 .#ٜ:Ռ-! нSQ:[ 6o*5jB(Ֆsj%D[lI#_܃:+]繍󬩳{WcԇmfZkLG;.H mۨf?yjtǁ7ߕl>lsַ-o /&]>IDQA۠1(v.*foY徵 CxH#F!j]GqFD8WN8iU= H4\L#Wu!m a`M+[tb҇&{^yS`;f=(> +q dE2ⳀB%e[НuQbx P_Et.R(o(SY6G1cEbZU4NT; |F,o!1v9b`QQbN } Dͬ!Q"F$긇uY䐮0aA2 l%pRCXZȈC\}ZVJgZy!Q%o_ﻺr.<4-]7mj?J^AJ0ǀI?*/`W5nLfj7>4 lmw|^QONvb4lXq[\<-0w(9bWrwҿ[sۗٳB0A%M5F}e#4x Wǚq8fab?a2PG!trįiL#]zb>xZț"T.Aw oNɗ:hR{b?i6#R6O mxx~+p*g?cƼ_֜e^0yII&,G1L0[$8nxq \bi@n3cdFy3g^1ޅ 4kmAR@F45j'+|"-X v .Wc"}9M ֎LCi660"v }LJItoFvnY]u-_ZH:mY2~F+{ow֣-a=ʶZOKeԲ%l,\-+" C! ٌ& K`dìM`8!,8d v-k9[~dfc?lT[u9_Ko`>pΈv-R"9EOK)rˊ+܂<6~ tgeH֘ޖ~[:%JqϹCpl\Q<:݇0^ϩj X1 i;`k?w?Ο>q;L_x+>79N]i rhoLoXn8]ԍN x']v᫸ RQS*l {Ҭ6;1neyUF{ʵ.g0pǕT1ܢaueZ}Ce g?P~&}wܔ-9˓{r.WzInyNnuIђr0E#'yhGN=Ok{cTvs~Ik"oy?(sВ؎_qj tImfMKGt\ܲ{A|Z+;q.' ؚ <@>\Ф.(||-l d;'wjLVmiE%+9+*iq:KB':p(; gvLܱeռ쵙gyK;stZgnnpSɹx٦32(yd?D) ƨV:j3A>htcU|nڭ]s8aVI<giN+΋;|?+˘4fc)ә1yslI my>gsP OS֤BJRȒVwdSǪy/g g\}^驙+@y3Ѐ2V.{]zLp )C5H8ʝK9:)TC!fbh{gSR,`:կJV͇ab㠀Qq|->::\lj"غ[ $-oJod^ѦN2=' hzR?E5 -x[&Ȉ &Ig7aş*4y7l*shI[?~m3ߒne3rtBzc)3xϖXſ,Q N?a:_1EVs M ~+>VlV1ͳY-u&V0g)1?mTc,G̎Z|cO\iPs- K6<8`;{e8iik_{knne]oRXT{KXv֮^u_M>o4) 2ne71O%ݥ[[`ncs%K,UFm9$̓6Y^J1~OfW6՚WjOwWUy4}<ԟJ[K?/5HZ$ek24qE݇wX1sXE{y>vO^F|^gs: q̃YƉ OvFf~Ox?A\b^?]pnxNWukKqۢkgLux1mxB;u޳wR{u-sų@~'oU/2s|ܧZ6K_Ƀw]yWޜy+j_;|&Zs?<~f3}23&*ٻ^[}IIgWps\I, dCu3M¼7δfl 6t^V. V!0eeG+E~ϼ͕j^[ >Uu $hq|j|>I (k&y{/j8E9PN*󿧖[ Jk\+(X6E+^oCcӕ?VTխ]9ܳ1r}\zw|-R TUVӢ/W<]zf#[s~g,/(kSz핚" x`="!(Y0 G٭oH"̼ ~;9\1;Ϗʯ{`+| { *Q柉iPvvt<;Y-~E'Շg^l7fN k%fs-j]+MH-p+m㓉YS;$=R;/v]嫲eg WPiwnA~p+pO,a*kD^:)(G{MkĵN6:*StcI $(YYtJӨ\%4Q{p5 m2NҎ FϣAI%w@IhQ)SDC9E}T~(5(jj=!%~j!kPH7,j$8=%+ wDM(T7B4J2룲(L-,(t8HnDH\l{RN2C#DьP3qR5keaqG- %/ $龳l`!Ν$vbJtD,3L{NGs{KHf >3*b$Dl=4l{D_ڛ2c#D9 ⌤MG/BJB1'T+>>1Rhr+43,rʨVgKϷKNm؋4աԐvT!U6J+ٱtaY9{I6(f:5asDؓsFȜ9ru:2nScK v>+Q.yhLQ֜I`>&_s{HV5"#mCW} CژiuDΑw*(VqF'ơ=47esgWE/(u.4;_R3y~;NhL?G.nSR>92,6cO"|?ic@9ᗲx]O q)@USP;/?o``l `?>2&jϑ^r<1}O4 p H8ǂam$obfږp(!Qm0[T-6cQm5"{HPm6!=ȶ5|b5Z` cD576tw@}Ɛ٥?k-b 1#bia-[hӺ7h]5>ܧ1:d5ɜ၈>2867#hpxA^zc00j= um:WcӢ:Hhp`Z3*=Cሡ Ƈa`_ =Հ` Ї5A#PA#`Da(+CYaÆ6 >L8F h",6j ǂPGj4txAױdž (3"B<xPHp/QU1WhQ,ň "  akFh${ " ׵C2@v##q8`@!(,"TfiP(N H1ш5xLi#_C!GT,vU) "#!}@.8 Y@)4H1,S}X>`1bH> )XlvttfHlM ҁ& R]\uXJX1]pldEFPkF[`(o\P5,i\\n uK,] n% ZeM˚>1S`!%'6a&Ҵ!A>1#QK%K/._\ҿqI%K/._\pI7~qN5ZZ.XC7=ɯ^N ӣn>nASWM}Il-Yj׬2jw֏H?ޖ#簟xr\.29g^J߻P h G6_uIoi`rouI?jL-ޒ^lh?BHU@-;~ZoVx_MiUꤟ )dSl` 뀽x` i^4C:lPLB1+U޶韤Y.KC$/_ 釓^xi\x"w-K:[ `U:&-!g $c[ 6k^ 8>[+wﺛC:kCwNuuδ7O/*6tZ[4 R)F"TA޾=YYŻ5U|Y>? >~x/|ǟ q&?(R>k?-Lڰ]L$Zf]ғ&q~1 *[peyP]< N`'qf%~Ի`|#+‚'Zt>I+JEBW2y_!,]ųR ,5ks9=>VW&?-NoN` Xob>^ ~#2VJ_?YxW=30a暈'NKڴ' !v˵*<ՈHa " "ހa_*Ì: OLfU ^? y^m1a:`D+يB*ta1eam۶ٺlmj[k+زUR34աUUTIej6SVۓ . "~[&> endobj 31 0 obj << /Length 605 /Filter /FlateDecode >> stream x]n@EHC/36R#Xe?pO'&UuBֻͮkG31}ͱ!^Ck|k$iQt2_/c<,Ӊ18\ss~_C۽_=_O.r|[}n?q8toq:Yd,t[aG, vy+(p R`3\ׂ'gI*ZPq!\PmyF) RȓFU@6|J'JR|V| O(xu`xi[|c,>^->;8Y|zi>$SҶ(S*S= ):J982ulɆOA>G?iX>G#)O>$Hu g|u𩨃OIj|w>6:BQр>0| E!G>Ն[Jsp[ڿZ{vsG^ҟz@endstream endobj 32 0 obj << /Type /Font /Subtype /TrueType /BaseFont /CAAAAA+ArialMT /FirstChar 0 /LastChar 88 /Widths [ 750 722 556 556 556 333 277 277 556 556 222 556 556 333 277 222 1015 500 500 556 833 333 666 556 556 556 943 500 556 666 666 277 666 722 666 277 666 610 556 556 556 722 556 277 500 556 500 556 190 556 500 556 943 583 777 556 556 556 556 556 722 556 222 833 777 333 583 354 277 277 722 722 556 833 277 500 610 222 500 666 666 610 583 666 389 469 556 556 833 ] /FontDescriptor 30 0 R /ToUnicode 31 0 R >> endobj 33 0 obj << /Length 34 0 R /Filter /FlateDecode /Length1 1492 /Length2 32825 /Length3 0 >> stream xctdm.[;۶m[fcvбmvltܹ9w}~qG;<|W-JRuFQs'S )'G7FV&dJJqW ͂ jPr|,,|17ۧ@ d t;9{XYwGgwS{9`u4cbL]m̭,LH@W 9ӿ6n6@Olsp?7h23$Ք%4jj5Yi O kd t}ff 4 ib04A H6f 0;?Q?svH;yX::|&,3$\m  `gOd Ghja/?4J8٘ظYy4fϯ"Л<ܴim:g?,G"8YkP/'rq| 3s~r~~_r7'c]7W+ nsTM0 q? nMD6V6"Ogl@n$3p~J3&V}:Z:xci?{13R$@s'G{o?JNnue'[]?8l?k[e݀uZIxYظY,jOadeQ5s\->GP۩`4՜>fۿ+? _WNSt5 ML 2#;ߠ4m\-d%,\<.~v_}f-m> kaea\+#S1DuLP֠7nMGT:j|f1L{iȡ=cfpm#1L"JpÅ} (h+Q-aHcR-~!s̞RuzI)n>[PjotgW܋o,f=84jmF8H/pz gξ$|ͫt96sGQY:x!n-ZЌVsyZAsfуi1D4oJjeB mq*فEFntj_ JtZ׺!v;$g ;|i}4p#=iU-ҚErZK @C%A/=1_ȵEmǫDgs9 ~KL"mra`TCZU)A$`'sL1WV>|RWSn@#W%jտ4oxCABh˙KΡkEqs@'D3NkJ'ч;~GzCT>w+ڙ^g҈XDh{3+>1)hT{9WX_,A緪^{ WʫJqd<:ˉ&D̒HBQ% 3̿1-j5Emf۰ Ю t+;6aې̶-:k<y ̴b0>gU=wx >`D>k+'62Qx!e\@2dU>CZ4[}l(-e|~l4>~!S:h!O ڦq"3]2{ړvRܸUw0siH6Đܠaa[>!ܢ@^<o7$~`THTÔӦõ{r["ĪaR7a{@ѿ(ѳ{|L{! 96}\MhG5>\Hz$bl^xN~ w0 w"xx1ԺG/;5'Wf=P񔏤fxR|(ZZ M)axr.q)tb ܭ͹_2(o0ݐ,9 j^#}BPgs"s80S1 k$8V;E1Hg/9}àٿXC4N"ENlrIDlwV4 F{,!L5aٓ$C͖ JI2U3}%> ἼIYN7tJ tS8{tDhF-9nbKE'A{2 vٛ{E_tQf z)ݩyVSm5 ̷E<׽rI:Iٮ];6Zhˢ\Qԓg{n1N1#87 ;ϢJְBIGV$FC˧-X Bߵ|߱+>+<̮hH*}I.Ԍ/>f AX{5 ڊ8X(v+@ J2~u+]]UX >' ݹ-4L)&K4e\"?u+m`| =NXK󅇳A_^Ә`BMQ+}j'<(@*Rֻ-"ca]͑ӯ"Bj*؉? [Mw>zIz1І^TJTՌ+)v;/H4 $I 1,qz"cݓ*]`lY6مY;vkB ׈*} l2KbxBv_S/-lID\D]<*9.RX2bkٷ Ė6A*RIx]!TZi,🴫MN>@wP0IsC5}u33 1s*d|L^J117 ןX% YޟlR^PGr!1NtlʮȼR1wPwޒ428AMJcϿ~I{n ~nˍ-ƷQGzќN&\>)IR*~;m2qB0.h@lx\INg.#+T(ru=0{]8/Cpm7`ڕ+Im"^eyN>J)p2٨Iì[* |Y5{`XGߘ:ɍ =u 췵wIfV*@jGbs{HLWk)꾷i-MGOJ{[%9Pxo&zuRz3&Dwj{D2S\yX?i_elH8HἹ7A[p-VZ)C`Co; A;)Xy/$CJ|M}zp_"8UHDž L$̞U|+/^RfXydM<,faȓr!npE8ВcgL7M[fՑ >wcBIۂymJzJede7Ew;)r}K.Y>%J^ot¹o%ԤNf fQ8m`4y 3$Z_kC62/oUժ#t k'pbN`2W f>V ן@샰ZJ]vgWS?5(1%~:fQ ޥ zB2쨑tR%7Ӫ68UBG[2dZP`|/>kߗb+ Suwj9́O>rs:e!gˣAH&$(wn#v: )h@۲%mŜ! zՋq.z6J9G9e~>&gg\6_P aPL˾l 5p3S$}5h_VJx-?S?.5P_nJR.t#1Ru4 N'¾o}k>\H^\be(C# κ 䴤-/QVF+55NUUvǶ8ƪIRaHAKͱfG;{}뉏Xݰ!LZDA⢶keF9__h6 f` eN0zH#n*~m9D.|Iİ qw^guP\qt _I3?QV«+fM;||cԚINeDN7$)8Y;YSQP^/EnL-N6tԩBR >n1ntwS]ѵk`7ovՇ_%60kw#WT1sZqMQu I )3f B: DR҉ӬBp::lC+6ݷQœ\~((1fGPҳ>ڥP)]+G9ql3>U9C,f-P\{YXuSe= ~KEY G! ,]@5۾ԠUm ;H36ɗ]y(2*}& c SZX4/^tQ֡h y W*$ s:jNc; eB Ř eOvHK<{Ձ*VAQwc49FEکK9v#rko=kv&m6 Q lNq|9 fl Pv'l9-q:OiOg۹{Euu:lO;(&ǥ' H'ȃꜢk7\^շ]P6mޑj5\ qBɺMA2ޚmF2뽂 Fwu,AM68>Q)l̆j/)?@br\ V ];0 $NOw}WVyް˧'SZz`P V`A\cNa e*4|ܲBj\E6)'}ϦГ h7TyeT0S6+oG!1->) %:i\Zf~|ҹDAQshD0Tj"Y0|H$)ڲ8䝣3K"b2a ׊r igcV|NbT[9xֺ `J^{sfoNK O\^_D|GprN,fG>ECJo n2|G#ݳ,h3]HU\T &zs4~,%7mJ>).u'[BڃB.9`VRńyda1k.rnZC%v}rSXGhDŽ vT~mc-C52N\٨GHngM"O,~ߘuo>zZk.SĀĕdPhu!!a%m$|ָ bv)ZRֻ'Fu0ۤSv bmXN$|b() s`cO}(z 9t84wA cm1G⫳n+,RQ1,g2hexS$#j=y;pq¿TxI ^)7n~W)ꁤuf_rmLYUƤjrY\?+S#q9~Woч~iLL~nA5½hZq h2ըR!`egw+IQGb,<&fnِ~k2I!AanpGLeᲔRN s* :]/QG\$٭4i~ݸq&*{@.IsQ.GӪTy 6LQ:f?ȉ ~rcOIX,{6FMB퍭Ԡ}*S(!oپ9PP W w/pBҿ!#/\sG65T ̷:BֈP4ђ+:~Pv7K,LURөe9L\$]IEr昩Ww+a)c&"abwY]ig"}T932)Ou 3 FB? t[]-,r!sbhF R6]ڎwD6 qk s2ߟъV1 [-=r8x u ٍ>̐@9qtPArhuO:YV uT#!<R >v ER$lE@Md?\Pø?EŨä{:1> 1{lv%+_:(a` L#w5剠_y| .ʸg]%M&7;(>O/_u$S7fAg?Wo`*Gzп۰QHuiJ=A9|fl;S"&IS4x=@a83F/RNbQkǾt-qp c>7 ZEy ^&;z3R9r/x•ۂ3R\:Zu%W3cp*~~ON8<}єn*ouΎg2f-Or*GBz8SĴqnWPS <súq%V$`ܻ}9KOtm7%{p7xm%#uvCH: F SJOKbWMSJ̷@#L*i1%XGuR=Yu.5rz"̭M>]ٌj Y܆X>Ia٠ ZFI"!6w:?\qeJaq0u?')4ӸrltMў\̢E]V}G=5*yڈW9;-`RfDSGJ+F:sfk]jN8h87pr588d[ը4BeV=%yIy,7+ٵfv!F!gc7i!R4~ . .--N5v9Иp{z, &OM08m*h MF^h,DhaXj3Zė?f; U~M Doύ!\Lu;SY0Pvh>+|A 'G}UI{FBИ)X'?bG^>Ĵ8T1 hKXeP^/ 6h.wD" ׻12h>)J6t7ttu ube~QKwbgo{lQO.3]R! *K?ed[ŨFAJۙY92Y Nm#@L1ҍd NHh>9%/ʛqq tWTVdmN1`K^- w>˂Y.RV Q GT~;5_ՇI-?\,>t`v0, %mQh!V)@s]>Α:ܗ[CL8]]&>W><1}qI4q׉^?n HcAߟJu3h9*5(xq#cO5NBy*o7_Vp_t;7]Q_yG&#H}`=xhgnifo|mR\flhwl}u _sR"k vh^,cYɕ"Qc6_'GxK{L噀W)=U,TƖch`4xfx<݊Q%;RF&¯9>02_`0hhx@cgPVydR)UrDDllb9őSj$'BaE!I@;-:lNIzPuNJQo"X$$j%ш0VQ8͢a;;eBM?-bQeNx^ɚg2?믖h:2R<%N &rOHGYyZKKx:ݴӢPi)Lp]9xUV_`WHD%:MeJy D0C}7ݶfڻ%[ xeC}*J?B$ݔojDOVfGƍBozLM\9--qI*ӱtrr ޯEӈ5{:RGkt`[AhʌKCo/bq"ٌXyqi<قу~QS>tl5uA9c}Kn1DǓ԰dDmKS¥J=Ydw]Je=Pp\A{-h8>|_Y$Ngj>8ݖ1 :Nmt ưb+n[pn͚ψ/p<LJyAW5_!>IN`Մ2&Y4'[ϓI,\V];/__ k6y\3L@߱`)ŢODЍB2Z}ửS9Tc.Y̘o31x]`5Me5_7kFnοK4)d1QRkAU7cҀ\o2KTXhwمO8bjdEaI:5STm@<kr˹/Q2ڬ(ڋ~MOGA,oe[='>_ œ™n qejK4vMe o / YH.DuJ&BTí)⧞">GMg!K(7("9@<A;VDzZ153]ێ/5W^ DTwBzc:8.ZEVMIP~`P-GbS[bx)6g) Q0K]yl[(YfD.#؅DSq4Wr*EK$ѓR_̛6[ݤp(4w,lcçŦW]qQo &M4':MA12gV #VSe EvavBٱYLBtb2fFh[cbVb(x@So1.rm G26AȪEI:|&vw 'ti\!eYw]V߈mni&eM?^?f' &3N.x FQBkWh.-fy 뤉U:Yh<:oڎ,5o=g:}AѓH(OD 9|*55V0dFQ~Qw+|l-A.II~ĪE?ja@1eQX/tl \b説vY 0%?o ל252Lk_|L6˖D:4y4F~?rydD@bu4L3aŊ\"OР'gGHA;PIU T3fIlƨ:X11~eVԗiR?& qjT)pQwzs:(NR1{Jg XTa&KsT,ȹ6!9vHEm2jhaNv-r /9< ݪ61So,)Gk*}Or5xGBʺk U$R*m%:]^b}tVP.J0^@[5>hִ\lLЈSZ&G(Y tΡv9]6]! lgb?2: tNd̗:AS9 ]ήz\90{S2v$핢-bz#yG $rM+\{;ςI! >V;ng?& Du@ϭ]`=/rYŏ|L4K縬EVKQPݑX /#s3Ҹ&p+-UY7$~M+u3<kA-'u7+2-bx>O+oE\y-N5EKuf'oYp'tM8a8FϹێ> v|\DzyS9A)ٲM$%T,ޭqYwS6`^,o?")V4'JhRy , lU3sDćYV,ѶmHI'gHB$#%ѥ/ѳ{I@|a ѡw9LpFrMUk ~4'٣'S7ZhD,^\%|q!+tؿA_$I\lB:gc"WsYƝV5nW}HS; #MEfQ·4o'sNrM|68ّ%P=a ͐~Ie U:d{xU[UMId)0s4:rx"nwY,#:2Ua߉.eGyE/]fA xc>/0pF|&-Y"CԍmW#GqBXBm1!g]Wb_T,<ò5Ž%z8m❶`[G|+Z-wĞ&Ugy aʭoq4t dgDg&ǾҕoGMհᬪ0M~`kM/v^cPƇBu+ח-˩41|K} Ť z ǑG Mt\Hh"(B}?q1ު܇zqz[8@;WZQcQԫP#嶡 Y*J9i;#0V)~lR '%H΄0ۤAz O0XHdQRAiIw]!v/;_u`%Է? -[ Rbo\Q A>~ӍÏ/۴.$ɩci::K~&Zhh%, ߾Wy<9Ghٵ{h5Ҭp2@jGQBxVqZ$aQz9˭[(o~dEs1 x<5d,%"L uJI=*oUMnpDڡ9Lٸ|_/^in?UgX' d akPUR0 dkV/Rh.,oj Od64YT{0"i0 !>^un=y,-kS$dIbc]CXz-Ks_kBjU C!w."xk4,4yt"~'>Y wpYS =%՚IiqvYȜMx{h2 ȹOيGrZ/tmNRNJwRal,f:ɂ](9\L @ /Hj ,'TIsIj%!gq-x.6~ c\:kN1ƨa?´iDLr<Tħb԰E-pDŞu3D}FP{Czl[G$93TKWY+Fۋ<Qtr^WE<Y-g*%멭ʄ d_0uvqeyRQ];gj[%J"8}Ľ\@"FQjAogz4: \'&e,4K? u19YۉMɊ~}pq0" v͋-Rri=SWt[ I=f9y@Zv<@U-/ pv4e[ȺƼD~3g$ԪSX0 ۰a*u9,Z-RL#l 36eܤ AT$9?)F@PQy/Z5Ϋa!~.U@8+M{{ߤp62ˠjAP9w u/ <6q$rpYD6{02y!Yk?_Uc3)Z,|w+_Hкw >6Q9` la -7#(2v6YA4  sh{z_ъ =:Crg dB !AFzFa!nަ{+܁qf-/'OWv$_փnfBLE mLSp@@]=% IѿQh@.0O(.A>"O%ئ>aA9uAbݺ԰w,cnCEĦ܄"A5Geh"&#\AkXK?CVý x(X~-r?#&f4޴Y`Nyܼ œ_M2@Ѳ ɟn+ k719B0'PM}*mӏ5Q42޶yZboAQ: oR# B&o,o&xYa"YW_^ @g{ތBR3mЫE1;EO򔾝ln$P  $H&P _RӘ >4N){>Qg(wG~o#@:*)FWjTSW&~˱t,b>Yt Wqme/<jw)E[=9=kuvNg^a0;ov7)mv]#!ׂt*\?(/h\4h1[Û8rd"Evu) >4nV͢l_ız.rkM0_9'2z>Jm;c^~i W7.wV K`Z l>AXsYK0WV 5R%q8"B=1S!k(;hƴv]NBm`=g9L~(}:ɞ@VQȧd+EJB_}᫄\l]Ṳ̌~"|o)d\񺼦KbqGI\4ά;䘣FgЌ#:ݥlyKzfsRd,͖&X|ꂟCfӁvnz>C8{>C2*~v;ECM URj$kk> Zu:m'k[=hK;5pDzf--AxǒB8፡zX2~Gq}.T,RzXX=3*qeSkDuB9Ę#U[]qL̝}NXդTC<'̮u)F24{:?V8|;?i1ygE|raݨ|T zMوX=p.Tmsh֬idY?Pc6}ݠ S瑇qںyFA]sAob&مD:Gx$>qzxZcߛ|['"m|)"P%\1![ԍ1Y *"2UzUӕ68T^Hp?vC +%>wO dp-Tlp?;S= g-Y,yױ.b{/jƂ"^Tc M”L}j#ztZ_|Z6jSX5 =O"_Ͽ3~T eN6|C/]5giI"t|MQj"f74MlK6g)*4D}0Gbb/o֮tP;w_4֒ՙ#6Ea;_`kj;c LwgmxFi"xn~=%ߡjYeGdLwXva% ^*Z ^lg*Ŗqxsvb6 P|]/ũqjSI{Ҁ_]Ms^(IEܕYlPR|211' 7cª=BE:->[k1;shĭmr|7*: !/ngʯ/`W 5Ŕ ~vvIuAx؋&Vsӏ9NZ4T{3 QYy]~]9?kTZb60q 3 *Z= 0I1'j{ucA&<PKoEgZS\ "Bqj,{e 7Q_Z[{ cҹd>:(!t>ayUFF|-$.(<1 9 s{ZH/(4Gcjn.6WWqy nNzͬ8/.J0 o"AS)m Nd[IuwK>̑%(Y80H R= rGx/J7H ~EJ+~FuyO@ .Q}FC#&6&.6"f|Z]:zQx3MZnwL%_^ ipDd'G  FO{%IkNb{Lc]g>)NR48 ٘ (A$LN\tmZ_d;`LA\yohȴ+HH?v}6>^I1맹]_䫱$1iDJ^!52luyc9wJ0IT~;c^I_3*;)W3UOZd쉋y"K¨vIK}=7b"+ȐmpG#fkhhq;{3=ol;ʺLp m%`OW`[%}muJtJسC⺛ 9]!s,sG|.5xC SY}Ry+Xdёo_mȆ: Hؙ oixbd5ISv:}hw/v9S(~I|OXs8#ɊVlde˓L=d}y+Ш|*F% ^[qvIZ>?CAVj@BsbmhqMu@02kZ:RΪM _6yGcYf8-?Q|Pkە(3tz~M9h6[&ɢب :"m(A ryk+}RŒNd}+̵tG rWEP3*s Z9b;4j7%PpXP. E䋖r ),J#ݡ|X2m!:Qo{|o,TlzoI,\Li4Kc /pMYvEii=>z(S!L:O Ɓ{7PyXmu_v㻠/7FFb.[PN-OD8 rXTyL$3zҒMS3\ 0K3Wsgv`I$䅓Ur~_]BȄ O^qNO~yk_PT wj4'ӓeL,ܱyޗ/8lsE-Vn׊/z0ᅼ.\)ƎgQ9־TK[B,s[ nH^E)5Oxdf,Uofp?y1dlgQz¢ ]8N'/8ueZyb߫Wʥ#?1W&ױ!d)DKHܡ) _@ήکf6GCcv8y 6?sna mFf OL]^l ibg0|(:0[yl[ j"?rWON+Mgכ>XS+Dr)\`([I ܜ!ID6X/։6[M~hjO\LA-Pmmm$Yw= FDs3+;UT+G ~B s?zf3觪Y6H)-pS0G2:Nv;KEE;żAɹ(AwBs?85UWHtTx;"q1\Rᇜl.3h:BHBɳsW!oюwjڭY R*h_nLVJO[@4N;wx]C41SF*2ptai&\l4V  4].#G͓)@Vd ‚c$hyz^rS\2Xl*%zTl j>W?Y+Uk`ҹ+̬{d+lQ{'<'N ↎z=i |:Xy_BaC捔6_v(t')ܙMG M6nQcGgU>*,A5XAe1ytq`wz z1 GnҜX?%o6X 9.ܫzQR~2~9TCZ[du6IkX_>Ƿ:۽Gjђ·u^oO OƂ"?TsUD1+W$?wgYH 4CrB_R?Y92H*v3i$njw8up'i}( y0!rc=F8GpuQԣDk6b"Qmdc扪S.Չ BPs}e}o뺃cDŽ*lL6 crGBNp)=)s A2dmDB4-"'8(sb݇K[Y*q628Ҙ'^Ybj:5ȃ <+lT21gRR#E fۧrƝTlV]I/vYeIߴCErqȫpW):DѺ`@|:~*^ 'Eh2}`ϺeEXiK«Pccv 7 B'& ܳ-E @:?F-&WjYm)ɕJ?H t$( XsΠ0M٭B(?QHᗆyUz{[Ù'a@@1%ǫL)ߖ6O^ȑc="-Qp|8L8VNqt]q<^ڸ#Im)E綜lN-aQ T sv"~pz,f1%ۦ8]"VNzFfqL\YLhKFoz[BwڼQ"YΦqj$|'5Wv`T/֝UA%a>>Jª^hP#*!r/ 0bљɊCP!ޞ^iו.4uײcI`Um1Eυ+C_МR ۻLWI+zY!1sMjj O.nEtM&KtEC'ć8+ Jj 3\UBQ) a17+)BI.b\žndnKwJh6!ubͽLA z=%9SqbcgwG|ߪ0#0*8FԀ0',xE?x n3 pߛe%E!Nhp95gqa.,1d!Z,B>3 $=?_p+АCAvy..l$q.a΁KB09_Z0 tH qtc_Unl~z:x ,"B]0wOTڧ_lVGOzZ65$x0ۧVU#vl.}+ D_&avu =h$GnoLoX͞2Jm T:SvB1,uq̔΂[Hqf_)x >9>(: * k U&@-&}?ar!OswD):,oE AW1ƨPQx_:"}+3n>&Ӡ{'nwBF }ހrѕKXb4}1 OOb[Юwt9@C7MΦR5e= PCA Sd֐mjdEyC5w#"d7|>uy'?ax+c vrDzQ\?K-~oX~>`7;|X4i!J5./U@^\e [Af?'cf ko nq^Lx'ÞxR=M*-Sa}E 9s\c.T?+n>-J\@۩wd& &#Vnkw+$ôQ۫ ʂ'AɐsF"vq檘BHZ(GR} {ac{Jk09](߰Hi`||{&R[7@\^Z YL`LDRIÛrNFK&(jGG\E=Wb-gghIͅc))vkօr Ϗ/*2wB szkZ% ?)fWx34;!Cޜr1y=82lگqaw42/*ǀ1i78ѡr7xw{8U >N?O-x ^$z(VFd,+E5xvSBnIP춨ꜿlsϴD|e|k& bfIp'' 2m )+K!MBkP9(6I522Od;?wMGA^dߝ+0:ao@z?d.{[}~vpTp"Aa>DZ}T]Q NEq;R.lQw0q&^xtX\(DIڇ=  y}:A0S 0ĐvkM1öZUq|k2>UDh0 h%4 R3m*qaA1 fJPvȳc^HE#L4; I^%VXFkƃ k y FĈjti M~^U7/Z(8eeU_+Yv9ӪnF0% QH@Y>u4;i/r%jop2D=2}&Dcpin\Uc2)N0@2XmLMNݩ,9C0TﵹCEщ: ݷXvR[uAaY3|gWo\s&#z2, @ +OlpUÓmr mj/kρ<֐d`&G"׌ ,ST_^KD%0} 9x.Ҷ@6)n $qՋ(Fc͗ ;@A~N &&"1uWJr5KĻ*kSЯXwZ#zW. Ȋ̐`34t_TU?94`7$IdxΖӅurewMҳ֣U=@ʽ|e# Icf̸#Yc1jHTpąhډV~{qxflnMI !琍 wTJ0i/H_O 1eOM?vg| 6 g7F:{x? V풕 ZV޸a;ڬCńWtb,cZAx@WIk2p&ZRCQti08il\RQbė>PCӿȠI' { h&7RNeXReLK{-*ޞg?j/"7<{H;@1~V]Eo\Y1 &j?H:qB5{Jؿ8xhiϬTNȄFIFQ|ED%[Qc]8c*"-N`T{"DzB_R"ɀQPq ʐ@CWxdLW_?nf3X uSd'b/@C[E[m z: :lJ_OF\6Y٨r+vqzᎿhJi\TmަE01᳦^Mdh olJ-B{#}=f: 3~2id#&_U];GRx6z8$귂E-/6@A߭&JBS ,2& _TT̈D[Ё5(mnp 2N6kvxU=$n^ѥi3YFǜ2JtJҳm#=@$X&;5dǯY,skV:;Ή}e=kr=%ڶ=]K4~ ֘W>P>^Q_EwTCDnQc[ʹ[Oޯ˅V v5fzK8 +FeCJ 6 B|wnqk~Cѹ;~S'scAYvoB] l+ ֑*&`@D>#ZG3Lޡ y-_edq!2m[\E mbke9}y; @n|~qIS ߒgA:X"r:V'$ "tdj5)ň 6LʼnLE/s^lLK`N;TCH[9%\gI#l‡Lh[P>kj&4UfLcS涞/kEp0ܖbɍ(zffK>\1"p S{$}yEtNA#{y튺),@)/qH8|^q5tyw^׃$+\uο"wL9VA8i}&PdV es(0ՈHGB6e}"pU7E1R}\vMz\E(Ĭmr{r Ί %WRb$,q$!{΍WQ#q/v5##bʿpVtZ;z?a{K#yjLg+t_&p#~Vv|i]wɔ'e#1v:3?5Wlʞ9 @J͈zyZ3 p cjܱlu6 ]ȱunMTX:[!hVg^,}RH%x55DvfM *ix3씣q*k+ 0xtV*d:T_+>fw%c5oAׂ"Cmiؚz>UsQ~?^Q3>ѩY!^,y]iԩwiIa"+:CuW\3A98]PMgO%]Z/fł *8`> endobj 36 0 obj << /Length 881 /Filter /FlateDecode >> stream x]n8߃"$1` e b~0i/@#ݏJ1M#2Va8]_px苧4,U]OguY.Voax>rQn]ǏK:؏ygע\.?O5_ܿJ+N׏\5_Tv8Џ_.6e-6]].hUL{z>؏Lv c 5Vp ^A!B]Vk{FF!)dBVhŽFw -#BG8y'qx<qH x<q8> endobj 38 0 obj << /Type /Encoding /Differences [ 0 /twosuperior /threesuperior ] >> endobj 39 0 obj << /Length 234 /Filter /FlateDecode >> stream x]j 0%&Bi$Yknsf*Τ9"[@hQn\HMY+z3_ Rtxl." {1緒z%Jrux[b!sBr endstream endobj 40 0 obj << /Type /Font /Subtype /Type1 /BaseFont /CharterBT-Roman /Encoding 38 0 R /ToUnicode 39 0 R /FirstChar 0 /LastChar 1 /Widths [ 370 370 ] /FontDescriptor 35 0 R >> endobj 41 0 obj << /F1 27 0 R /F2 32 0 R /F3 37 0 R /F4 40 0 R /F5 22 0 R >> endobj 42 0 obj << /Im5 5 0 R >> endobj 43 0 obj << /Font 41 0 R /XObject 42 0 R /ProcSet [ /PDF /ImageC /ImageI ] >> endobj 12 0 obj << /Type /Pages /Resources 43 0 R /MediaBox [ 0 0 595 842 ] /Kids [ 13 0 R 14 0 R 15 0 R 16 0 R 17 0 R ] /Count 5 >> endobj 44 0 obj << /Type /Catalog /Pages 12 0 R >> endobj 45 0 obj << /Creator /Producer /CreationDate (D:20050710232258+02'00') >> endobj xref 0 46 0000000000 65535 f 0000000017 00000 n 0000063380 00000 n 0000063408 00000 n 0000089387 00000 n 0000089415 00000 n 0000109799 00000 n 0000143479 00000 n 0000143507 00000 n 0000198338 00000 n 0000198366 00000 n 0000212442 00000 n 0000304840 00000 n 0000212471 00000 n 0000212580 00000 n 0000212689 00000 n 0000212798 00000 n 0000212907 00000 n 0000213017 00000 n 0000222171 00000 n 0000222197 00000 n 0000222451 00000 n 0000222910 00000 n 0000223274 00000 n 0000239105 00000 n 0000239132 00000 n 0000239377 00000 n 0000239823 00000 n 0000240162 00000 n 0000265960 00000 n 0000265987 00000 n 0000266227 00000 n 0000266915 00000 n 0000267530 00000 n 0000301533 00000 n 0000301560 00000 n 0000301798 00000 n 0000302762 00000 n 0000303960 00000 n 0000304057 00000 n 0000304374 00000 n 0000304593 00000 n 0000304695 00000 n 0000304737 00000 n 0000305055 00000 n 0000305116 00000 n trailer << /Size 46 /Root 44 0 R /Info 45 0 R >> startxref 305323 %%EOF sailcut-1.5.0/doc/fr/model-sailcut-fr.sxw000066400000000000000000001316311477005247400202660ustar00rootroot00000000000000PKت219mimetypeapplication/vnd.sun.xml.writerPKت2Ok``-Pictures/100000000000018000000214F983AB6A.jpgJFIFPPC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( ( ( ( ( ( ( ( ()ڔ:6}\,,`*Xp=Esu4cn,]Nl!1yn85i/ѯ}A-kX8W)اl+_/u/ I&Hu:Ym䴹;6Ʊ6N9%PYzDuqi4ۋefxIrP7tu8"Oi^M̭ Rd.`p0H:f,֡-m~աio@X #QSw8%`wu-@Zô+4KCi*+H|-o魏 h ; wGӠo5[{73\"G&v89+f>mj:Vy&msAy`YḏJ#.|;gI=1y$qE88&7^oK--mnVU-#J6=p;i۵ƗZ_@QeP#8 W׼QktZ4vgghcxdo-P.E='u{A?w_$"jm{,G.b¶A3 WfA,cHpJաöwRE0srN0XsK t84L:1 Gg8߉@=xkZ#¤zU]ZD m<1@DleW95EhZ>dV6v<ϲ[[ghO_SZPEPEPEPEPEPEPEPEPEe#<-_Gih&1TǩO@k|ί|nSw~o޸#jE' Hw2 Yj~5o'uW>V7m3TVcvfml$NI'I'$' BaxvZw3}O(((((((((((WA\sa]KKf ( ( ( ( ( ( ( ( ( _Ms\h>Y-˼wkaJc2#+˲}S to?|ۜͫĮYhc;@ 5iZUevv(I9$I$@xtQujMsā S#x JvF1G$"({oo:v8״leXbh$1r2`qwLy>m}KkrP:@aEWk9<[h_i*pyuQEQEQEQEQEQEQEQEQEQE7@w?Կj+o+lPEPEPEPEPEPEPEPEP\-RK]9X"]c]uf>,gAQWQs08'z3v@a5n4VX(PNr((ym"h%BG"WR0A%0YxNMKn4; U[|lB<{tAcĺbf؜v=QEQEQEQEQEQEQEQEQEQEs u/-  ; _[5tQEQEQEQEQEQEQEQEW4e,C˴d$TNtc.y|?.tgndL 䑎:֧H|97F)gnHbF}fO$hR(((/B5xϠ^w'l\criTm6gFEKy2u*H#8>[_ۨapS0~mŠ((((((((((WA\sa]KKf ( ( ( ( ( ( ( (8yZ_ xxGa]/pa s8n⸿j|P^FP%.Vh1ǎ36:ssvQEQEQEWhu($WM^%I* 9gcxJ"B~OcQk"Q[\)$lr Lp2I;( ( ( ( ( ( ( ( ( (9º]s u/- (((((((+Ʊq/TIEZ, ϐŸyZ_ xxGa]/pa s8`z$>֛A唳Hb1#>гe'y5EQEQEQEV_4H|GKF ynxĂ6#}VG r+R<kÁ 'P*Cr=b4N Fy.+|DC1h{ kڦZƢg{I]g/" AlwwQ@#>_e|ǷF|;AalևMesۤl\nAҊB:q,Xͪ\C4"X%ye 'H,'8bxcƏ-okkCirG(;J+K@״+MxGӮ+,nf"`DJ`g/|5^%+Ub[zy~];ǚu_iPmWv+<2Wrąʰ%iYZ  7.Xr4LKz`4Q\[h?ӒK麫myb5x2@˓v R&k;[kA{ +S<,SP8p#Q\~㫭#OW'dsLzyCQྸh<+=h/y9=2Q\~?z'w}ag^wc82:zK]sWf: +C^Ƹh9V ti4m{\Q[۶p $H1YEp|B%u{WSYaEfWLl+ ^Š[kJk-nP~ \qe7Lg>#yzv5gPxF(r<PrEQEQEQEQEQEQEs u/-  ; _[5tQEQEQEQEQEQEVu𷃵]i0y̭)cR*;u:q~,vcBlKޘnU"ǔG8vvV_-?4 snJܢ(((((+{;6=CGtlrq层`FHϨ( mg'kuM #r0N# b7?g/ H&Au.qh$a(Wq(((((((((o+lW?WR٫(((((( j1GI6%,ʌ[(#| x__ x;U֙knҟ5!yr^ҴUX۪2摁np\נ@QEQEQEQEQEQEQEp>0>I%կ:WI&' ` ((((((((\^GZD̛܌a'r hɤ]y v kAWKîY?-éD핎!C16$`x4QEQEQEQEQEQEQEQE7@w?Կj+o+lPEPEPEPEPEPX~1uh۳E+2H^p\ר[ xK)ﯘ)x`ʑ:vtcvI /=GdY :;+y+xֺJ((((((((VPOK6͵W7Ό?MkRѧ^[A1 _iUÑԢjSjѮ.n[܋DtD!lsϮPEPEPEPEPEPEPEP?WR٫WA@Q@Q@Q@Q@Q@p߈'$fk"oW_' Pr'5|9KY)gnybFMǡfŽ$pj{z]/6H|.X}۞~tQEQETs  !y$($s x-h%@WR2#4%Q@^DL#c ȫQEQEQEe]T\ޛ]PZ=,Fsr(R ͜7pIuk[WrW#b8 Z_xy]73sc)8^[f>&gڗm]hdIBpr2 ( ( ( ( ( ( (9º]s u/- (((((tI BwYkklH&z¹]jڔ:6}\,,`*Xp=Er~߈'$fk"oW_' PrݤCuo-QRHPF Ab9y{Mѯ|Cu>}ŦM|+nUe '𐼐#ڴ?t9tnn~4HE$j,~c%L2# TLq\}m[<)$+#xт:`(5蚝_ .%yD:( @$ yi_ UM3ԵnGGM6Lf-͒F<9ux~}{OOQ"FAc'N3U|![qi$jq/(YnԱӬ㵵˅2@,XI,%IbI$I&8 ƳokH 73~ zV-KS\ ABD& )8bl"~x+AotYFy1NUNиYGGH5X{txONbDOpp60W^. dW[FiUTB"9l=xˋĞ0յ*=+gJMB/,% hm x<汩{s77:|iP!}vq"G2)w|=&eOcnmm)H("V  upėI}+>! ,kv="e[Y'c$ ;=J*T~-G,Hi enf;|PIk|#QO:xә<يE*H<#XEbݛxEӾgq,9R1+Cm}4y@.eNQںJim^jQkHgi]Xl nc%9&P??kZJiȋ~(9žN=xI}|S+ZVպZ>Y:\_QSľ)" Kms#P =8@;Ju-N{EKTwI ,5b9c Ux_QMM ps qFh杪Zjpo#[;4N̍]nFAc:c c&k,;3Bʲ.6€ ( ( ( ( Wm)}G\]D\&H"dTgg'د?+j>ycOrTܱ)r9bׅyok佽iMcj]pc9=OI?wC4Gsa]KKf9 >&9 >&9 >&9 >&9 "xğ84;˫DVL2ى7$8k/:O.'gNPKN=+0;6mCm F5R)0W`U$ ~qGdڋ)Ҽ.B͹8< w&Ѽc.Fh VPҹo5zopfF7nqct?MT}M7%V<:O vk+)ܤ#hTŸ;`&spqyioKyO50Hn9ia$^~Q@ct?MT}M7%U~kV74Bo&Ȩq&w/P@8<sct?MT}M7%WAEsct?MUwq }cNc9fdLT1'|;ěsg5OCD>|D葩KX/$Jѷ1,}M7%Q?wC4]M7%Q?wC4]M7%Q?wC4]M7%Q?wC4[  !y$($s&xj dn'ׯ!74Hn NS';zh}M7%Q?wC4XbMImuUs`1[a ja 5&<,sfP$Qkx&Wc;J}gYywx4r@c ~4âE,ZZmԴ!=պImk.glxCJnw&y<|&FAО2t Sy<34ݹ<=5b] ges 7#` sRCz5<]4<#Ckw,_in,hX [mhN5TvSMmijyC$I99vۺ?l=k:VܒDgD$-b F:;vB>ʈKb0>a嫌s9OXn%<Y\ P+83WZo?+msc͙wtqO,}}ukԭ-6\cx(?.=Ʊ2w2|[-k[۰鶐X`Y^(>ᧇVŦ.mfK1`pQ,l,8- ;!1.I' 8$ƬQ@Q@Q@[F JcSjrnEiM)$XH܀A{SBçmO !Y]t ( ( (? x~]I仜kgK#AԒy8(V4?># xjo x|{q֩yq%s*Hrv$WI@p~=oMH5[NTcOʷwvk5?hw쵴| cH<sѯ R&^ RhH B,H'h$qA6[0D#5 `*J(WA\sa]KKf ( ( (7ֈ-=/%VLq*$H{n@;OkpsZ?RČʛBͅH׀|6~&ohd'Nsm&<6G$!VfCiXʫ1//Ho4 !us%7AFenJҬt=.L-MD2I$I$#yZA>X?}6_"(QWkuT.?M zPo""HeG nF9b_siiweîͪ;E"MX }@Y>Ep~,5O ]hq^!\2azntv{bP.$2'9;P ( ( ( ( ( (8lXK 5teXĂˆ$Y:EPEPEPEPEP?WR٫WA@Q@Q@W4<[Xii;QA,p98Hv $.V)Ryp럼hT8iᝋ5+KnY5{!y0{ ((((((((((((((fڗkrdFIC22<yZ_ xB3Q0$9P(((((WA\sa]KKf ( ( }KCƿ&ZoxKy-cDu0$+# ?)Yw`~o@4<[Xii;QA,p98_ᝋ5+KnY5{!y0@+iBXjW#dso 6$l(TwU6Eq2U|w|ǎWӸqEc+v #Zy0ΦECY3zr + oh67O̸Lqޮpe;$m x'j[$}z[Q\zC1u^"y&k)|AHQ1i>Y D4ʥJ(.{JM/Pd %m%BJoN?g5[u['g.]3g ( ( ( ( ( ( ( +mU 7b >{VzK/]HIt%!K@Fr@s(-){4)V"VPC7QEQEQEQE7@w?Կj+o+lPEPEP!KӼ/'cȹXKeî~R:|sf>4dF֞ƻ2FpN< I @$ ( ( ( }ۛy` $Bc1(O Q@^5\izu݌K]N&+pJ2ǰM}>pqxY"`qJ(׏/#op^ƹQ|9)"x#sR V^ዙu@py 9'8<^\[ۦ1Y#Y|'s{((((((((({xoLUx ʓAkR=*`- pmU#XL秨Ҋ>%i[i.zaʹ.Sی yI,mݺB$e9vWkPӧD.HX2"(+p'c-.wh6kms;H gsiEp>wĉ5Na`9N: ~k)s/jq9+5]zavtw>kj6v|$[qGOQ\ޥjuKNV p HN2IǹOA<B|NFnxMtg᳂yX8tjztG[,t78u# =2;; H--c`FIŽI':߳xqXh-l˻l^ľ> Aeg3ϮQ0 $lqEptMii#?JR/[Zi)BFRr~cJ<8uiEqn+>8\~Vv lϕ 8MG'_ipkS:F:ÒW @!G{J(~Ѽ#IaIL̞kɗ r䞊?*آ((( ; _[5t7@w?Կj(n.%"BI#TP2I'5%pV-W1O\G%DQ OSW$dpsW]Ş;v]Qq/"U`>b=:qv.|G%*$6Wc'{ gSڭԺ4ɹdlv n {iEqzo[.GT.MՔV댁I*y4C?\|v uwD( ,j07`;J+r^Hx6 S5Ԯ 储H~5-4LG$gdd%#*>h9hg?oE']}3Nu;UcoeZhA~HDW(hal(eBY}sl:G4fԚeDy^p6j l?ȵ..ݯѝ]pA8dm?[\↙OuqʶD<֟Fdo1R  Tz-ͼS$D0g` b4߈g,0VЂ0('8Py jZo<\,Q i9c@QI<8Q@y񥯅!Xu `HFv7xğx^Q?>]=Ý\ܜ x;h~Dyڕܭ{N"k0de.Fp Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@W>iǑ*.E'r*QEQEq4W$K$&"c3wF;ArOhZ֯i:եeq`gIDHCP1PĒ-\nk{h{XNJ#E̻H8tiZPCij.L2~SnlPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPJFIFPPC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (PKت2 layout-cachepP ]FP .[FA NP 7F^P EPKت2 content.xml\KsGrWg rSKA/D"HJxpDMwLQ]niÞ|Q{//_/_¬J0S]]/3 wi"Δud`'TXgޗ/opw/>}$d#u76QG&+[~yr=ic×0%piOz{G-3w?=͊";lcmvww{/d|QM/ԻblPOKʷg?1oѝ;w^ ʚwξY;VS2+Y_t➁g5L GK8Wqٚ~㋓}6ݸ8MYoOU%ҹÞׇ0ֱZݏU{fDLW/̤'&OT'8)#K'3#>qC~zplLėU+ ?n&.\aL˴&Ek\w&A %{ԩrz+ٺOU{/)c^.7j.yBI, ^K?;$murje>`+C(zY,-9鰆BCCapKDf+&^"Sf7/Uz:QMKeWz׬^92iwk׮[yMe4ɖ{oJW9VΦ[c'2q 8]V7h{hG<2^W+OXF~&}xeoϾWngS5Y4Xwoߵ,NGPy܉x@0咲d-r*i|룑 s+ٿh@J^w>j~2*v,a%f+_s"_D(/̏+YnoϘ%e]>[baw7|b.Rl3 i?{_lw]*ls'd: ~B͡0ekj'v^mpWSrfʤZOJVT[K Ǿ8aϪx[,ԧdFk*tEkȪmjZI~*TB`u[)O~2<;$;Ԫ %ﱅ?GVpשoK0FUACvy",$ꌨxObKY˪~"C8k-Q /+"V"•vPoN وJ*^HDev7,Wj^u\f 1OH/ĵ`^{w^Y59쥠0w-4HGO0Ѻ7;]_& ~*s66Yl7nfr"Ҥ+v>yW;U-7`=jM>O!8p/Ƶn({>," TfzAí10G rbLO*(T=۝dr^h U"mЍ 3TߖQnʊjGpf2ĿI?`dCC!RF+VXS"Sw흅]ҁJVM"3 ܂OGB;G{c'] ZfP'`Bx> ^Ĵ˚LILL>OO 4??1qHBIepfr> <r"D9^I 2땆O[دLP0Y|qF&~ot&<{N@DQ ͭɴ̯HXB4@7oKS|@*@e2yt&Ǻ(@lL"ۻv^eN<{{/5dT@0g )0(vWzF90z\BБ|C$=xs'3s)I.Rf?EGXb̴+HAsU^bΝ}vw䋯+e E88*{nŵub]Aߩpkm[-- S5 pGF$)yQv`wS(Ӗ{J0%;Úԧǖu*JYg>F'p0owŽrQ7lKv3ZVjHD\eֳb\Wf #W~PXO&:'?B*L=!c`jPT-UQhQQ B%Hq~"q%\"gL:x9Ha>Obr;d9_dc5_v$\3Gq:dc !L%wgJP P'r2WByc01XY{w1z KMJ, ]08L].'&OUĘ(d7 .y#w\#&qm T.Ei6ӑ8I]#(wdVxovaFo\R}U|\WH}F4 :Áz t39i Kڲ `˙2\~P~ QO` II2̮^Y%-7Ixh\z6GŅ﷝jWĞ:%fW2Fc9fTgbJ JS\_|DiHBl7e|3tuxK~{Q=тR)Z@Z]ȭJǕ96 WmkB~Rj#ib0t>Vk3Yվ-zG rA03$8;QSyһWB 3ђ*@\4TsQZ-Nb: 8\Qb]E/$!V`&OO5ԫR]yP(MRJOEWYSgfvta;׼U0V=fTP#.G%vI"qu@ Q~ɾ*k>MӸh/ 9{ɚ=*I)_Q#AFZr(Ƞe8YwQǥ#݇S qCGr|o=jb(#>c `{J6}/Q9UԖ%^m͍cFE+l[s-x oŞ[+6T!s>MpګpH6 7!!c֭!UE  mw%ВϱMfωk1E(FV"0x8rPQPuP'@ 릲a~6bLrt-B*C L$cE s) j:V-&Wu]r@S:VgeQ99qU!DkUhWSة B_oHk0A) : ch(ܘ{M pՈeU*.O9l SuZ~o;T ;aq+zj uWlLjzGoiR)f,7je?ݪ-/࿯L-jhKj7vv+V" R~If)m٘nE$\b%`J: U ;L9BeEI`@ou*8"%ܨpf\UrŊX3h G nYk[ސP]VmV  [* aYn-P7})5w]uujimݺ=;)W@I^)hQsA6i/wխ -HbqoLS#%|q#7.mA8 L8yo)-/P-9әxnrQv EօhE5LUܬ"=o6[l v5sl}g*uɚ$.nH!s>Pf(|Yp/؆9V.J6P@c' Y2N>Q`4-V5rc?AwY$MgkGec!6%x+|h,kBD)ZLKɇZ%%>i+h 2dcQsF9n='bT09=!hj5ms(|XU/7Dȹ;b<@- m|C|}8RoB94z M LWa]t8\dfkLq,wqN IDD)Dy/۝7Ӈ$8հh67&%5ƂdvQ$oAڜq'=3N!Qv_+y` !DC'd?m}櫮M"JHT. ȪNA g͸_^yZ"TșTBF|Դ2/6I@o K_T鳽p NSKDBTJf;Vl{}WSAuZop{x~;7BZ3qu+P^OٯgE_R$ ql]N1o%IKVX&5a_U_:h FmQ;L~I3Ks{Kj ٝ޽nzru?^㽤'{I%}˽O%}h&"Pz+id?_uF. gGv&iAO[>G43k˧sG`lvp3с#8jsLSTp1*{Gw~a=d>'EMz69pXo`2'LсêngQw1:}7C  cY@)W5~g^ Sf>P2e|E S'7/ SUe;uY$XT2ۑLO}h q(m7t1 &B TueG Ȁ1j|hJpl"ao|=j}/=k$tA2w~Oy#Ӈ˒%Qhjf8 OpenOffice.org 1.1.4 (Linux)2004-02-21T17:18:042005-07-10T23:22:492004-02-29T19:53:36en-US20PT3H20M46SPKت2ObjBFFFD752/content.xml]O;H:x8d7;x3#D# ׽ý (yfZjem H")UH~-çi1Y&eH/Jfx2忽7]?ͯ'x>%u45ϫ[$ff8|M}~V _E](l<ݮ׋? !sopŮ:>65/m]y~piKj]i:}Zk:}H%ױ3/7:&c.6^ÌȌxQPϷq&۵JMQ Y%b=b&}6RLuwwy$"I7$fާMj1?J2Jd/xiqyvkvj>̧c`,8/ӵmb|L{+jV6|8AX_MM(IT^3f!/lu0if6NY]y =F"%+W\~ij} D.VsݍXτ9 {4[LO54I2[ƙM*\&Irpߺ}xuW|=:E/!uN3ܶsOȇ]žqew ?KMkfis'cۣ 2woGt2d֟&6yL8utqsUն|!-tx| Lg̗T27@S;Pr``NV=QMyJ1R;>n<$} Q.܈G?U1kmڤ$t<[JfXff^ _(/ߛe߮%T]onP[Vaƶ~JaC޸)](UtYh #x~.\me>W7EL0q8fhWh'O"v=lu7^> ϶O?oEuڨQHB?m7ǟqN z ݙ8bF~?}OI|GT9-c:xtW8uI #IO'[1 w NٳL7W 8Fԅ .ӂr\;i+>+mͮݒ7n0d= p$ Uq[T6q39np:õõsŀ2*1 YGvGB8J1 a/G?E? ΀ŽpϚ㞅ྟ%镳a-bbU00oQQY)ӊP-f N`=С1\~ z`T”5Ї !JJs$QRZ9o L1JS3&[J%{E`h$;Vmkϛ#"bpma"Wσ;2{CA]0P.LRYr8=Թ7+bú`(7v]9E(P6S\o]|/*AJqN"0q"~P/r )EBVsfw/ u;C#f-K0v <[hW,*L<npLLݞpqrR !31#qa+9ڹE{oVp]c1Vepn\䲌zb7g V+4{f*9~(/Uxy,880֫9/c"2bƘ˝yI.>l[fõocAԅ@I]E^">*<˓SQ~h<Caü*> Uֽyy%Bvxẏ)f$0F0 yy,sI-X/LCycA< DqF;{j<̳nF wϝ[)',C7|yV5e(A_vЇ<"YxK Fo;C(A*=" (ǔFΖrP3YpisIz">ԑ>z}h5IzDK Fj@ճ|a,= ǙДPj$ӆ8MZ^A҃Hj<:Dq>9">snOuw>KEDvPY{*=衻HOI)m<x>]#If9鏒v,=f)E^>PTxzӣ |{wO1{șzԳ{ٳcqBiy{fdgMw~T=kɈTQv9Uzk&.T=P GB6K?iq9W¸zN8Bp%5kN󇺷wadN1j WSQڇyd ,l>E.l?hi:?e$|k`+ȩF EA3M5`_LNŒ}gOhsl/ PK 9.F=PKت2ObjBFFFD752/styles.xmlXo6BSHvvmkb&haHKLT";>M$?'/Οz<'.Ɂg[,$4^3i_o-E$Eprܺ}xse;{azPǮ{yiK7mA(B_l |K{-D6w]^Xeym@+D I% QC6h K|*f9*d6]OQSBǭx-HWGj?C5Uqf0aX!kP_W5}<5.U~'xb:-UF *6A E`-3E)̯db[Ӏ$y6rj,͈ GYL7DcZi>^{@-6Yw滽WЯ,E}Zo] Q-MKKhغpqbL1'7$wyvψt, qtҨEu+'IbQ@.$E%(Ҟ"릚 (J z D볡եRKťXRVf ~ˣcYTO˜QyyDŽkD tMm9{ٝݐ=Xr<: ŐpU6sܟxGc#K hW~NW,)lWAmTKrĖpRsVdjQ7jOݳ R0zO`ɹwpL=EYuhH/QR^5e!i-~&.;8zܴ~X1t#k4_w8_k4fX&%$Ss"AF׭uL}+k`aĂ }r[:e&FqFǿ9ي48R95T'gWKDjs D9nٵ$=KƆ ǁ2L )t,=Q="*vp[=Yn^x٬ Բn PKVl]\PKت2ObjBFFFD752/settings.xml͗[8WAiAO{i@Dufs'BUJ*Uyai (y7,A<ۥ{sڟ͑aD Çi /1ȹexx\RQ hwC4Ti0(,&\ / {(ďry(TءTUU^,*;rZUvUZ]V e ~XW_\ =8HD"5k9?;!C="y,p֔w_5h۸a9V@(}[o'u=Uio ߪYjjN:c7o<NQUV'fNjDõ wc >ܕ;~sacll`dSSjUU8 " &U|̦m} [ cYG+1[ݙ804O~# E^4ȶU"c_`Btw^`5t_10eh8ŕȆQ#:-}Oӕ7?ʩPKɿPKت2ObjBFFFD753/content.xml]ks_~Li:v#@$jd.vhCCyB Yݽ{ܻ4*&etQr@Mş_4)nn(yfuy 'o?'`>N7MYQ._L/&g>d7xzuqsc^=o鲮ߧU}oߴɧhk`8LMy\wG[Mm}ww7MKݫˢ\۱| 77<>T}9Z5-3q&<0A5 `rus`;LG6쏲.|:\7uOiuu.Au|>PW؂pfS"mésJ t0:<_]x{0DD*̂uF NpxaEK쎪]u WiRM~.#\91ݤY r4<6oӪxXM;Lli@E'eAwiUY-i FxN720(p]T>C0&~imN߯M~.eܙ'8p[ɇ,C0G-L<u|c`{FQnq>,o裈>u\uX F4z8zY& ($}#aq$51u;#ZWtrk8h. 6U#Oz`U)MEIU0nl3)ˢ VaH֜w YJl^Ģ({cpUTHFɢL*蠾_'ugu}pn%{}?{l?:㐅m0$N>kA6GVS;uJ;16VOKCҒHR9KyR W :#} $E c=ֺ83Yt'3r\I> !Qԩ.x],x"uzsss>ϊ]ee)ҚR!JqGھRtIYF)OW>K(E4NiGy{}URwXo+P 뮫-t[1yw2t;j:ຈ.G泑69){ ꧪgTQcj_1Ƈ'#I K@+KDJux}C`,nmLYQa{B^j^1{%~}Ʊw$ُ0>{OeXK6;u1FA!} IF[3-酟ʎ|qS]@>?`lLcaKåaMn~ov)]6 .Ҽfu/:n;{@__wv}f݌vEո펼h^Ba cO"6]؏ݿ]`vy]p8nAb,wn1 q] s[ϋyg}Ο7zS&G>*]̇,nȩhKĉrXoE6jJ==Q ֐AR W fV\~rS _ޙdCfc~'_sL(y&x&DQ'v*$0K٩q}=G IWku,bPOE*?q$-(!N".`&]=1?tJ"HΕ`>y?ITdpvOD>癀y[G:/ L!='!-dL;SW m@E"1hT E!bic~(WY@u7́|ş)Q)Sꂧ"i̅SL6o 9Lk~(G[uoyĊp. OE*_O@"8O]`XwYn@uOьb!©HKW,T8~uv0İv0\*fW4- 3cVk6x*zy,U Hȝ{h@= L9l0?CJ”]~DbV29GB`"X)l; ^A. NΊ(8@$smq-mUgǛPKӋ7 `PKت2ObjBFFFD753/styles.xmlAo@۽`TT4ibI1Gd$]@}qW0&|幋,PCEsiaDYI2gB6K ,TEDsp9BFX˙D{vG)+_˛eYg|9Pד"\NNg`mE 8q;I>OHmk"gXsQƣC^mNbR7=q`3ZNODl$WC=o =K |7PKYLPKت2 settings.xmlX[SH~_u G WQ6ɴ$:IM&g=rZd:_tKހ7~)](qxuw_? 9p@E1!mXLjzA)j?O_jc( ґ6{JAYaAtK^oWJUS4M]_+ģqV7 CMW l]](o\^o?9Oas"_̓ʾgJ{@ٮU W<*qQV?|>h8ؙT*ka߂pnZ73nrY<,)u;l T ![@8CɄ<{ I> Ű&}F*_}FP$<$AKy(r9;׵QΜLg8yyU <:T1!?FE |Θ?Pts~X] - -.odH=7C˛to "H:_ʬq4FV/R(Pˆ$m)Av7#O-+"|^g~!L:%COyutZ\$spc# D"%Vz< Бf\ a ~9Τ1Wpe R(+j-nQK)QP'qn{o7qx=ߖ^u;A2j|wS%Ȇ6mǦ9ga 6G99 >d[G{&ɮGȏ7ՑYCZh|dM؁3v! E <+ɿr^Evrp48)6ԈGKYa]z/PK=zPKت2META-INF/manifest.xml[o0+Xh,٦ZPэ.l8'aPH}7x\&ee3H|B-aEr2/ScÕ 0n90`&,E5 )J`<>1,|?zS*tYDvOm;PN cO d&*ʊ/IE.iKIvʷ򭲴z$am)e,abX͛KA sp|[ΕwiG7CkgOϤhZIų"ْ)L+N@5X$ 5ͩ1oA5հj= \series bold p2 \series default : \layout Quotation \series bold p1 \series default = \series bold p1 \series default + CVector3d( \series bold p2 \series default - \series bold p1 \series default ).unit() * \series bold d; \series default \layout Section Distance d'un point une droite \layout Subsection Dmonstration \layout Standard Soit \begin_inset Formula $\mathcal{D}$ \end_inset la droite engendre par le vecteur directeur unitaire \begin_inset Formula $\mathbf{u}$ \end_inset et passant par le point \begin_inset Formula $B$ \end_inset et soit \begin_inset Formula $A$ \end_inset un autre point. Soit \begin_inset Formula $H$ \end_inset la projection orthogonale de \begin_inset Formula $A$ \end_inset sur \begin_inset Formula $\mathcal{D}$ \end_inset . On cherche connaitre la distance du point \begin_inset Formula $A$ \end_inset la droite \begin_inset Formula $\mathcal{D}$ \end_inset que l'on notera \begin_inset Formula $d(A,\mathcal{D})$ \end_inset . \layout Standard D'aprs le thorme de Pythagore \begin_inset Formula \[ \left\Vert \mathbf{AB}\right\Vert ^{2}=\left\Vert \mathbf{AH}\right\Vert ^{2}+\left\Vert \mathbf{HB}\right\Vert ^{2}\] \end_inset ce qu'on peut galement crire \begin_inset Formula \[ \left\Vert \mathbf{AH}\right\Vert ^{2}=\left\Vert \mathbf{AB}\right\Vert ^{2}-\left\Vert \mathbf{HB}\right\Vert ^{2}\] \end_inset \layout Standard \begin_inset Formula $\left\Vert \mathbf{AH}\right\Vert ^{2}$ \end_inset est le carr de la distance cherche soit \begin_inset Formula $d(A,\mathcal{D})^{2}$ \end_inset . De plus, \begin_inset Formula $\mathbf{HB}$ \end_inset reprsente la projection de \begin_inset Formula $\mathbf{AB}$ \end_inset sur le vecteur \begin_inset Formula $\mathbf{u}$ \end_inset de telle sorte que \begin_inset Formula \[ \left\Vert \mathbf{HB}\right\Vert ^{2}=(\mathbf{\mathbf{AB}}.\mathbf{u})^{2}\] \end_inset d'o \layout Standard \begin_inset Formula \[ d(A,\mathcal{D})=\sqrt{\left\Vert \mathbf{AB}\right\Vert ^{2}-(\mathbf{AB}.\mathbf{u})^{2}}\] \end_inset \layout Standard Si on dispose non pas d'un vecteur directeur unitaire mais d'un vecteur directeur \begin_inset Formula $\mathbf{x}$ \end_inset de norme arbitraire non nulle, on peut crire \layout Standard \begin_inset Formula \[ d(A,\mathcal{D})=\sqrt{\left\Vert \mathbf{AB}\right\Vert ^{2}-\left(\frac{\mathbf{AB}.\mathbf{x}}{\left\Vert x\right\Vert }\right)^{2}}\] \end_inset \layout Subsection Exemple de code utilisant GeoCpp \layout Quote \family typewriter CPoint3d A(1,9,0); \newline CPoint3d B(0,0,0); \newline CVector3d x(2,1,0); \newline CVector3d AB = CVector3d(B - A); \newline \newline // build unit vector \newline CVector3d u = x.unit(); \newline \newline // calculate distance \newline real d = sqrt( (AB * AB) - (AB * u) * (AB * u) ); \newline \newline // result is 7.602631 \layout Section Rotations \layout Subsection rotation de vecteurs \layout Standard Le vecteur \series bold d \series default selon l'axe X se dfini par : \layout Quotation CVector3d \series bold v \series default (d,0,0); \layout Paragraph \series medium Pour faire tourner le vecteur \series default v \series medium de l'angle AA autour de l'axe \series default z \series medium (l'axe numro "2") : \layout Quotation \series bold v \series medium = CMatrix::rot3d(2,AA) * \series bold v \series medium ; \layout Standard Le point \series bold p2 \series default qui est l'extrmit du vecteur \series bold v1 \series default dont l'origine est \series bold p2 \series default s'crit alors : \layout Quotation \series bold p2 \series default = \series bold p1 \series default + \series bold v1 \series default ; \layout Standard Si on n'a pas besoin de \series bold v \series default dans d'autres calculs, on fait tout en une ligne: \layout Quotation \series bold p2 \series default = \series bold p1 \series default + CMatrix::rot3d(2,AA) * CVector3d(d,0,0); \layout Subsection Matrice de rotation \layout Standard Pour dfinir la matrice en question connaissant l'angle de rotation ALPHA autour de Z (axe 2): \layout Quotation CMatrix m = CMatrix::rot3d(2,ALPHA); \layout Standard voir http://dev.jerryweb.org/doxygen/sailcut/classCMatrix.html#d2 \layout Subsection dplacement dans une direction perpendiculaire un vecteur \layout Standard Le point \series bold p2 \series default qui est le dplacement de l'extrmit \series bold p2 \series default du vecteur \series bold v1 \series default d'une valeur \series bold d \series default perpendiculaire (+PI/2) au vecteur \series bold v1 \series default . On parle d'une rotation dans le plan du vecteur, aprs avoir vrifi que \series bold v1 \series default n'est pas le vecteur nul: \layout Quotation \series bold p2 \series default = \series bold p2 \series default \series bold + CMatrix::rot3d(2,PI/2) * v1 *(d/v1.norm()); \layout Subsection Rotation d'un panneau \layout Standard Utiliser la fonction rotate pour tourner un panneau developp : \layout Quotation \series bold flatpanel = flatpanel.rotate( ton_point, ta_matrice) \layout Section Intersection de 2 droites \layout Standard On connat 2 droites dfinies par les points \series bold (L1,L2) \series default et \series bold (P1,P2) \series default et on cherche le point d'intersection de la droite \series bold (P1,P2) \series default avec la parallle \series bold (L1,L2) \series default situe la distance \series bold d1 \series default de \series bold (L1,L2) \series default : \layout Standard La solution ci-dessous est compltement gnrique, elle ne suppose pas que le point P1 est sur (L1,L2). On reprend le point \series bold p1b \series default calcul ci-dessus: \layout Quote CSubSpace pp(p1b, CVector3d(p2-p1).matrix(), GEOCPP_FROM_BASE); \layout Quote CSubSpace ll(l1, CVector3d(l2-l1).matrix(), GEOCPP_FROM_BASE); \layout Quote CSubSpace p = pp.intersect(ll); \layout Standard Voil.. il ne reste qu' vrifier que la dimension de "p" est bien 0 (un point) avec \layout Quote p.getdim(); \layout Standard et si c'est le cas, on extrait le point avec \layout Quote p.getp(); \layout Section Sites intressants \layout Itemize Dmonstration pratique du produit scalaire \newline \begin_inset LatexCommand \htmlurl{http://homeomath.imingo.net/scalaire.htm} \end_inset \the_end sailcut-1.5.0/doc/fr/sailcut-profile-fr.sxc000066400000000000000000000312031477005247400205740ustar00rootroot00000000000000PK$3Emimetypeapplication/vnd.sun.xml.calcPK$3 content.xml]8vP[)_Zk-=ֳ5L9Iy[mϯC$(yQM@"598?/fhz֥}a4Oκ?z/t0<EM8]tvvgY?_ o޿$߬87vIr}sq8MjϺt0pnF$߻ /rgk m\wb|4nw p7/m3h~|Tk7Mp[`ej[~JE^3#04Fe+ԃ2ۻ6Hdzݒ'MN⬻`ûRJ=:~~DdEwoNaDqւp;du3nqϗpa@~]؇mIrYv<8&6#.qXоMhV8NhT&8*OGdI wq[#}쐻\-^4[oI/{r ]ptiiIe}n77, {o`5YnS%t4^&WIa^gG(ED#26gb{#G _7a/Z-1B/"_5GwM:qb+Ħ!iYNm6Čh͏W`"v"`.ʦ"8nMDlelufL}"̎f6 ?WWWKP$fv$6)sNR -06m䐖jiV/L[ӲXAa&<6D(>|'ղ|_ ^"*_'/(11NW?HQ0Od_fvD28늻 F&Nc׶.`]1݇CȌ~7S3U+wc+nuyT1Yvw^tCm'*#&Y>7_LdG 2}}F}mÞvuG`{,?<=}9SZm=l{=Jnb!?_w;;b%O˛ƦK>Ŝ:zCl kC̑YJ'$&xᰱ#L7V@"׬C5;E7nv :@oh|#^8]3v687=ş$~k*?>9.c:lSQ;}I3ٓ'aM)d bQg<.$}#Zˈtnq,26ZoJaZrsjy{p&6 V#Y:%\0٬=aۦ1q]?0V٪\U!D2*1 =X:mS&6)?lI)N9;-R۷/LL)sBh)pj(lkFN@je꫁- [4kaz tj9, FQ6`2*a톃~ҾXKX}J*UυT^NaJ{ vLK%sJSr&GW NY 3R1+SX1\\hN"]ClΈe|˔ Q Pr{/V5[&-]I)&JJ[ [.ztHj Se@B0ūXzxM s@ J ԑuTVyqc%u1pމUvV3?n<IxpRf;a47V 4Ǵ>ħab;v|\bFc$X>yqcLcCy9YμB+2DqFs,jRv;a[E%hFA2 Xv[.v@K4A nAKR$ |IP"]E9pTAJsT+4cFMcT3=odzUDwp!ǿ񵑤J:'Ot/{ X`tuYO( 3_;tLhJ(5iCrG5vR;03 @& p٢#.g{Ţۏu`vw¬TwS)1V ͝`Kt965R)|hIL%~5O3]o`U X:_N6Hp-`5;1˗%;xܙOf4cQ!幃FW 1!~^H˙\nDw"_;g7]Qܝ)cG;ʗ%;xqݩ”Pib R;.RZl_p(k*78@ƻJ0Ms ,Q:8 YDx^_ݓwߟ~|s[-$G b_>z1G1թcOM\5Fqn0GF8sWRfG XAgؠw5%h(hEFXxz/Y^ףFөR~ky|$Qqw)7ޔ.+ćӈ #F" `W=A?ǓA Pr {n i)vɠb#R1?nVj'NΒ%SٚB7$aůc8oӘm2&^fal9r.Q*:Bl/;pV,Amfs$Bl=u5R1o:uJ bݞq#bbN™+D~iCK "D9-UZxbJ] 8V. vHD;y6L Ei8 !SeKAi_Uh)KD!K2o7[ʻ4w Ce^DDNǣ0Y}sH(Ӓ  ep Ij" lޣ VbiJ?TwͼmRkœgJ-iv:QCd"CHHNh*49pzkC; J[I 90x ؙeT_ojUjmTs mlwI%AcDb8P3tX+u90@u91χ)$7j'C]`Y/_冊; 'VsgA;^}Y胫ˣƶ@9PR=Jw7L=AYyӈH= O~YYk(hAW}Sbz\T%o݅;Ͽ_w?Yxq;\0M{mN%2I/ko5^nwٚ|!QƎ<0W&Ҙn"7f[c#L[2OvN&n;Eσm&9Jb8!lU_3x\yKr_CrWzSԖ#qhzeĜI3"UV3wţzV5z k-,Շ_= kzp9 ƃcx} xE^ &!,eĒ1ë~+ۓ2$ #6aFI< Pdd|h𓺨6Ga,Tpxk*EB`R,*MCwzŒn=&ec돲|Xb%k$qTuG0й'I&+U(Ń0WYk`U8toѸ 1>HElqX]+ʟɵ$ 1OZ<,ՖiX9$0 OOpN@s3?_~/L9!>:Cq}ۢodMm#c-imm7잶-z7/joWo}fyUg7nop픓۸:~#4bo,P_xjp_<:i]_R3M="iN)ay>.t;a*^~oe^<\N͎؆SWQ|70;<_]X{0OD%2.u'LN?qz[nAe]UMO0DUrhnE7yQ%_nڟv"#&@6crZEjo:)w_Wy\l- h*O`I FbO?hSW3U -Aqǀ׫4WV~f}+xCo(z6>CzonC&߸W$O㮧m7xBzwQ ޾㜜u}Z{_NjўI>fm{5rx&{VchNUtW7qQbc82 ƅOl Bj`e V.a;3d@1Y: *K uLE^UtYUUE⢼,e6A] CωcJڊ٨[-6uksB_gEԶri'`^'RVMaȇ\x_U9lvF1ƨ+cs4E% a X⪊W̔ː>Dy Y!+@j[M5uSeD)Pt}k&9L9mH[TvO D0c)bCUfEt!i⦸3-ǹew<~~f!Dt4cD R*ݯw~nn·&<3G}~zdQsTE>[c[v3oy[[Gd!x<1ܙμ-}#o4iJ!μ-'Yq]LcMjq}m/n|b>k"ٝ;>L.Ξͤd=aK3Zz7E||x^aވ K:WD 3e fV.&,X$8MM¸ͲϞ} g/QP}>ƵХ*1̸]V\VT-YjЌrݍgj5aC^3d?u=ƶ.6,6 )@ y̹|, qIbTVi "$D )/SK(F5E$wj DHƸbHK]>Ta+Fr=U 0/:wU' U?`nl5dEL8Yj)w,P^B"ư&u:Q08 ;U ш ”T$._jj4Đ\U(C"6%q7Q xAXVf"s0MA08]ci0+RʙT:?}RCv4@&K|e I!:/`;SȜGw*9h&A9Kd,bk{'Bh 3 b=ݩ Q(x^OhBPLa+ Gy:kJ8b9@ݙ Lư@=>S.4%^ lԔ$;y{!Ai((M-\͜Gw*py;CO#ф$ x4Wp!5`D9g*47!zpt^J#NʂJ(=0/ȉpptYYVAI0~`Gy*P1EI 7`4& 7$\v6K ,TEDsp9BFX˙D{vG)+_˛eYg|9Pד"\NNg`mE 8q;I>OHmk"gXsQƣC^mNbR7=q`3ZNODl$WC=o =K |7PKYLPK$3meta.xml OpenOffice.org 1.1.4 (Linux)2004-02-29T17:21:282005-09-04T22:31:342004-02-29T19:50:47en-US15PT6H27M40SPK$3 settings.xml[W8W0}K9W(44JR*I)8Zb)s>&N/׳K38\$u+#}SUa=[%xR'! !RԸ%@UoHn)jjvs5$jF)) R?ˤK- ?MOTUCe5i+ QFG˱Z.{CJvEM(kڋkg )>˕^Vlvqdc3,(N1d'"B/ۄTOvw!zUת'>q3tӲ`ysem4QMG@ǝ/iCSzZ@Z3ENz'O9oI|K~xN󡻔%a.Lߣl3@ξ)*|htiy|5r*;rkj A/7||̲^gۍ_ 8/(6`!FӲJ}Kr 1t p&^)ȇjNУQ,!#S8uImJ1D?a~1R%@p BwJ1ՠ UꑦT =X T=I.̚"dHoC!86|!C "nVUƼ7 &r3JnOoNwCE33/YG'ψ%hs8Z<@I#d ܯT1W<]L}pp$= tD븑pX=n \#GoPF;ݛ=p蝮_|4Tg[oOF'[~5dv凡lܝ'侱K"of ۵Q6w\>h܍}uh7ծ-=2n`xv*&ڵEWM_o[{9)7iꕥkU -Vbb2=Ӻud2 ?Zqz Nw\n3N;t\px>5E6e6r]H 08l~4_w+2hϠ9HC튪~>ȼ&c[Zpv]AAz2si~H Oх3'S $aی􃏂Bte6G j8S- 7j֯PK pNPK$3META-INF/manifest.xmlj0 { ODc (X-σ%e7H/GCaĞjK8 LM )x&]$}:'Ǔ6\@Td<׊² .҅xm<qڧ0 >IeG'p/'n+kGtU b97:c"!? PKLʒ!qPK$3EmimetypePK$3/"R? Bcontent.xmlPK$3M ! `styles.xmlPK$3(x ;aObject 6/content.xmlPK$3YL$Object 6/styles.xmlPK$3%meta.xmlPK$3 pN (*settings.xmlPK$3Lʒ!q,/META-INF/manifest.xmlPK0sailcut-1.5.0/doc/fr/sailplan.fig000066400000000000000000000074601477005247400166500ustar00rootroot00000000000000#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 5 1 0 2 1 7 50 -1 -1 0.000 0 0 1 1 4980.000 1860.000 5175 720 5625 900 5940 1215 0 0 2.00 60.00 120.00 0 0 2.00 60.00 120.00 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 1350 7920 8955 7920 8865 8280 1575 8280 1350 7920 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1350 7920 4590 3150 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 4140 7290 4140 8955 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 1350 7920 315 7920 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 1530 7695 675 7695 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 4140 7245 3285 7245 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 5 4140 7245 4923 2028 6840 630 8685 7110 4113 7248 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 3 1 1.00 60.00 120.00 3150 4005 4275 3555 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 3960 7920 4905 1575 4815 1575 3870 7920 3960 7920 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 3 1 1.00 60.00 120.00 5220 6255 4230 7155 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 4995 2070 5486 2479 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 8550 7020 7335 6300 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 3 1 1.00 60.00 120.00 7020 720 7875 1485 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 4590 3195 360 3195 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 1530 7695 4185 3780 3645 7605 1530 7695 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 3420 7245 3420 6705 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 1 2 0 0 2.00 60.00 120.00 3420 7920 3420 8190 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 3 1 1.00 60.00 120.00 4230 1710 4669 2140 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 3 1 2.00 60.00 120.00 3 1 2.00 60.00 120.00 1350 8775 4140 8775 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 1 1 2 3 1 2.00 60.00 120.00 3 1 2.00 60.00 120.00 4140 8775 4950 8775 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 1 2 3 1 2.00 60.00 120.00 3 1 2.00 60.00 120.00 1350 9135 4545 9135 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 4545 3195 4545 9135 2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 1350 7740 1350 9135 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 4905 2070 5130 720 5130 675 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 1 2 3 1 1.00 60.00 120.00 3 1 1.00 60.00 120.00 405 7920 405 3195 2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 4950 2025 4950 8910 3 2 0 2 4 7 50 -1 -1 0.000 0 0 1 2 3 1 2.00 60.00 120.00 720 7695 720 6840 0.000 0.000 3 2 0 2 4 7 50 -1 -1 0.000 0 0 1 2 3 1 2.00 60.00 120.00 720 7920 720 8280 0.000 0.000 4 0 1 50 -1 0 16 0.0000 4 195 915 6390 7110 Bordure\001 4 0 4 50 -1 0 14 0.0000 4 210 1605 540 5490 triangle avant = I\001 4 0 0 50 -1 0 16 0.0000 4 195 810 5310 6165 Amure\001 4 0 0 50 -1 0 16 0.0000 4 195 765 7110 6210 Ecoute\001 4 0 4 50 -1 0 18 0.0000 4 195 420 3195 5985 Foc\001 4 0 0 50 -1 0 18 0.0000 4 195 480 3600 1665 Mat\001 4 0 1 50 -1 0 16 0.0000 4 195 1065 4635 4680 Guindant\001 4 0 1 50 -1 0 14 0.0000 4 150 2550 1485 8685 Distance \351trave-amure GV\001 4 0 4 50 -1 0 14 0.0000 4 210 2145 1935 9045 Base triangle avant = J\001 4 0 1 50 -1 0 16 0.0000 4 195 630 6075 765 Gaffe\001 4 0 4 50 -1 0 14 0.0000 4 150 600 810 7020 du foc\001 4 0 0 50 -1 0 16 0.0000 4 195 555 2565 4005 Etais\001 4 0 4 50 -1 0 14 0.0000 4 150 1425 675 6705 Hauteur amure\001 4 0 1 50 -1 0 14 0.0000 4 150 1365 2340 6975 hauteur amure\001 4 0 1 50 -1 0 14 0.0000 4 165 1125 2340 7470 Grand voile\001 4 0 1 50 -1 0 18 0.0000 4 195 1350 5940 4275 Grand voile\001 4 0 1 50 -1 0 16 0.0000 4 195 675 7785 3375 Chute\001 4 0 4 50 -1 0 14 0.0000 4 150 1065 540 5265 Hauteur du\001 4 0 0 50 -1 0 16 0.0000 4 195 510 5625 2700 T\352te\001 4 0 0 50 -1 0 16 0.0000 4 195 345 7920 1755 Pic\001 4 0 1 50 -1 0 14 0.0000 4 210 2010 3285 585 Angle gaffe/guindant\001 4 0 0 50 -1 0 14 0.0000 4 225 2385 6255 7830 longueur du pont = LOA\001 4 0 1 50 -1 0 14 0.0000 4 195 1755 5040 8730 Quete du guindant\001 sailcut-1.5.0/doc/makedocs000077500000000000000000000005521477005247400154560ustar00rootroot00000000000000#!/bin/sh FIGURES="coordinates_system sailplan sail_seams sail_edges develop_panel_drawing head_gores_definition rigplan" SRC=`dirname $0` DST=$1 for lang in en es fr; do xsltproc -o $DST/$lang/index.html $SRC/sailcut-html.xsl $SRC/$lang/index.docbook for fig in $FIGURES; do fig2dev -L svg $SRC/$lang/$fig.fig $DST/$lang/$fig.svg done done sailcut-1.5.0/doc/sailcut-handbook.css000066400000000000000000000010131477005247400176740ustar00rootroot00000000000000body { background: white none; color: black; font-family: sans-serif; } .guimenu, .guimenuitem, .guisubmenu { font-weight: bold; border: 1px rgb(96,152,255); border-style: none none dotted none; } .guilabel { font-weight: bold; } .guibutton { font-weight: bold; background-color: rgb(232,232,232); color: inherit; padding-left: 0.2em; padding-right: 0.2em; border: 1px solid; } .programlisting { border: 1px solid rgb(64,128,144); background-color: rgb(240,248,255); padding: 10px; } sailcut-1.5.0/doc/sailcut-html.xsl000066400000000000000000000006531477005247400171020ustar00rootroot00000000000000 sailcut-1.5.0/icons/000077500000000000000000000000001477005247400143065ustar00rootroot00000000000000sailcut-1.5.0/icons/generate000077500000000000000000000021671477005247400160340ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- import os import subprocess def inkscape(input_svg, output_png, size): subprocess.check_call(['inkscape', '--batch-process', '--export-filename=' + output_png, '--export-width=%d' % size, '--export-height=%d' % size, input_svg]) def generate_ico(input_svg, output_path): pngs = [] for size in [256, 48, 32, 16]: output_png = output_path + ('.%d.png' % size) inkscape(input_svg, output_png, size) pngs.append(output_png) subprocess.check_call(['icotool', '-c', '-o', output_path] + pngs) subprocess.check_call(['rm', '-f'] + pngs) def generate_icns(input_svg, output_path): pngs = [] for size in [512, 256, 128, 32, 16]: output_png = output_path + ('.%d.png' % size) inkscape(input_svg, output_png, size) pngs.append(output_png) subprocess.check_call(['png2icns', output_path] + pngs) subprocess.check_call(['rm', '-f'] + pngs) generate_ico('sailcut.svg', 'sailcut.ico') generate_ico('sailcut-file.svg', 'sailcut-file.ico') generate_icns('sailcut.svg', 'sailcut.icns') sailcut-1.5.0/icons/panel.svg000066400000000000000000000013721477005247400161310ustar00rootroot00000000000000 sailcut-1.5.0/icons/panel.xpm000066400000000000000000000036231477005247400161370ustar00rootroot00000000000000/* XPM */ static const char *panel_xpm[] = { /* width height ncolors chars_per_pixel */ "32 32 44 1", /* colors */ " c #000000", ". c #00002B", "X c #0000C0", "o c #000042", "O c #0000AF", "+ c #000045", "@ c #0000DA", "# c #00009B", "$ c #00001D", "% c #00009E", "& c #000076", "* c #000037", "= c #000023", "- c #00004E", "; c #000079", ": c #0000CF", "> c #0000AD", ", c #00002F", "< c #00005D", "1 c #000088", "2 c #000049", "3 c #000035", "4 c #0000CD", "5 c #000010", "6 c #0000E7", "7 c #000013", "8 c #00003E", "9 c #0000FE", "0 c #000016", "q c #000041", "w c #000044", "e c #0000DC", "r c #FFFFFF", "t c #000089", "y c #00004A", "u c #00008C", "i c #000078", "p c #000025", "a c #000050", "s c #00003C", "d c #0000BD", "f c #0000E8", "g c #0000FF", "h c None", /* pixels */ "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "h$i111111111111111111ggggggggggggggggggXhhhhh", "hhhhhhhh#gggggggggggggggggg:+hhh", "hhhhhhhhhtgggggggggggggggggge2hh", "hhhhhhhhhh&9gggggggggggggggggfah", "hhhhhhhhhhh+yyyyyyyyyyyyyyyyyywh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh" }; sailcut-1.5.0/icons/panelgroup.svg000066400000000000000000000034141477005247400172050ustar00rootroot00000000000000 sailcut-1.5.0/icons/panelgroup.xpm000066400000000000000000000050541477005247400172140ustar00rootroot00000000000000/* XPM */ static const char *panelgroup_xpm[] = { /* width height ncolors chars_per_pixel */ "32 32 88 1", /* colors */ " c #000000", ". c #006687", "X c #00002B", "o c #003445", "O c #000017", "+ c #000042", "@ c #00006D", "# c #0000EE", "$ c #009CCF", "% c #002F3E", "& c #00161D", "* c #003141", "= c #000034", "- c #00005F", "; c #003A4E", ": c #003344", "> c #0003D6", ", c #001A23", "< c #00000C", "1 c #0000CC", "2 c #006789", "3 c #0000F7", "4 c #0082AD", "5 c #00698C", "6 c #00255E", "7 c #00AFE8", "8 c #005B78", "9 c #008FBD", "0 c #00006B", "q c #006688", "w c #009ACD", "e c #002D3C", "r c #001992", "t c #000046", "y c #0000DB", "u c #00AEE7", "i c #000032", "p c #002835", "a c #00005D", "s c #000088", "d c #00759B", "f c #00212B", "g c #003142", "h c #00009F", "j c #000035", "k c #00779E", "l c #00004C", "z c #000C10", "x c #00007A", "c c #005976", "v c #00003B", "b c #0000FB", "n c #00A6DC", "m c #000E13", "M c #0000E7", "N c #00007D", "B c #0000FE", "V c #005A9A", "C c #002937", "Z c #00002A", "A c #000055", "S c #001897", "D c #00002D", "F c #000A86", "G c #0000F0", "H c #00384A", "J c #00001C", "K c #FFFFFF", "L c #00C0FF", "P c #00004A", "I c #0090C0", "U c #0000F6", "Y c #003C50", "T c #00008C", "R c #00232F", "E c #000039", "W c #00A4DA", "Q c #00008F", "! c #000185", "~ c #003749", "^ c #0000E5", "/ c #000011", "( c #0084AF", ") c #00BFFE", "_ c #0000FC", "` c #000053", "' c #0000FF", "] c None", /* pixels */ "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]DPPPPPPPPPPPPPPPPPPP]]]]]]]]]]]", "]]h''''''''''''''''''1+]]]]]]]]]", "]]]T''''''''''''''''''yt]]]]]]]]", "]]]]xB'''''''''''''''''Ml]]]]]]]", "]]]]]0b'''''''''''''''''GA]]]]]]", "]]]]]]aU'''''''''''''''''3-]]]]]", "]]]]]]]`#'''''''''''''''''_@]]]]", "]]]]]]]]P^''''''''''''''''''N]]]", "]&8qqqqq.6>''''''''''''''''''Q]]", "]];uLLLLLLVrSSSSSSSSSSF!ssssss=]", "]]]~WLLLLLLLLLLLLLLLLLL5]]]]]]]]", "]]]]:wLLLLLLLLLLLLLLLLLLk]]]]]]]", "]]]]]]9LLLLLLLLLLLLLLLLLL(]]]]]]", "]]]]]]]4LLLLLLLLLLLLLLLLLLI]]]]]", "]]]]]]]]dLLLLLLLLLLLLLLLLLL$o]]]", "]]]]]]]]]2LLLLLLLLLLLLLLLLLLn~]]", "]]]]]]]]]]c)LLLLLLLLLLLLLLLLL7Y]", "]]]]]]]]]]]oHHHHHHHHHHHHHHHHHH:]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" }; sailcut-1.5.0/icons/point.svg000066400000000000000000000044251477005247400161650ustar00rootroot00000000000000 image/svg+xml sailcut-1.5.0/icons/point.xpm000066400000000000000000000034521477005247400161710ustar00rootroot00000000000000/* XPM */ static const char *point_xpm[] = { /* width height ncolors chars_per_pixel */ "32 32 37 1", /* colors */ " c #000000", ". c #00BAF7", "X c #001217", "o c #001017", "O c #000D10", "+ c #001F2A", "@ c #0085B1", "# c #00B9F6", "$ c #001116", "% c #002C3A", "& c #000C0F", "* c #002936", "= c #00090B", "- c #001F28", "; c #001D28", ": c #0085B2", "> c #00080A", ", c #002A38", "< c #001117", "1 c #00B2ED", "2 c #0087B5", "3 c #000A0D", "4 c #007297", "5 c #00749A", "6 c #00202A", "7 c #001016", "8 c #00090C", "9 c #00ACE5", "0 c #00141C", "q c #FFFFFF", "w c #000608", "e c #00C0FF", "r c #000F15", "t c #00506A", "y c #00749B", "u c #00070A", "i c None", /* pixels */ "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiii iiiiiiiiiiiiiii iiiiiiii", "iiiiiiii iiiiiiiiiiiii iiiiiiiii", "iiiiiiiii iiiiiiiiiii iiiiiiiiii", "iiiiiiiiii iiiiiiiii iiiiiiiiiii", "iiiiiiiiiii iii-,#:$ iiiiiiiiiiiii", "iiiiiiiiiiiii*#ee@7iiiiiiiiiiiii", "iiiiiiiiiiii%.eeee29eeeeeet8iiiiiiiiiii", "iiiiiiiiiiii61eeeeyXiiiiiiiiiiii", "iiiiiiiiiiiii;1ee4riiiiiiiiiiiii", "iiiiiiiiiiii i+15o iiiiiiiiiiiii", "iiiiiiiiiii iii0$ii iiiiiiiiiiii", "iiiiiiiiii iiiiiiiii iiiiiiiiiii", "iiiiiiiii iiiiiiiiiii iiiiiiiiii", "iiiiiiii iiiiiiiiiiiii iiiiiiiii", "iiiiiii iiiiiiiiiiiiiii iiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" }; sailcut-1.5.0/icons/sailcut-file.ico000066400000000000000000010554461477005247400174020ustar00rootroot00000000000000 ( F00 %n   F hV( 3<33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333331>33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333423333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333332333Q$X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-W-W-W-W-W-W-W-W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W+W+W+W+W+W+W+W+W+W+W+W+W+W+W+W+W+W+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V+V*V*V*V*V*V*V*V*V*V*V*V*V*V*; 3332333ɸW-3332333ɸW-3332333ɸW-3332333ɸX-3332333ɸX-3332333ɸX-3332333ɸX-3332333ɸX-3332333ɸX-3332333ɹX-3332333ɹX-3332333ɹX-3332333ɹX-3332333ɹX-3332333ɹX-3332333ɹX-3332333ɹX-3332333ɹX-3332333ɺX-3332333ɺX-333h6gEf#f2333ɺX-333ffffgffg|fZg9j2333ɺX-333fvfk w22pi fffffgfgffpeNf-j 2333ɺX-333ffkk~~jjUU}AAv--ngffffffggfsfKf#U2333ɺX-333hfj yyeePP|;;t%%i ffffffeeeVd)2333ʺX-333fPfs&&hhMM{77ogfffffffgMf2333ʺX-333ffUUkkNNx//lfffffffgJa2333ʺX-333f ggaaCCu$$hffffgete?j 2333ʺX-333h,gmmmKKt""gffffffUf2333ʻX-333grf|>>__~99lffffgeXb2333ʻX.333ffiippGGpfffff133ʻX.333jgj ppDDnffivӯX.333eLft((aaz..gff{#"khֻX.333ffUU}}JJpffwjgպX.333q fgUUqffwjgպX.333e+fn]]rffz"!wsX.333gmf}==UUnfiMKͫX.333efmm55gfwxtjA>X.333afj ffqfgGEؽ>>gf=;ӴX.333cfffl w((BB\\uuhhgsԶfDDKKgf>ibfUfkgffy''[[AAfc`KIplofoccWWgoÛX.333eIfgy++j ffffffge`g4f 2. xn ffmCC||66f~{fu|ufk OOpfURX.333gfiiccEEv%%hffffgfeygHd2333ʻչvs21gfg66xx{''g—jffoqn{$#fjSSú;;fz" ؽX.333b fj~~__>>sgffffefeSi"2333̽HGjfg55vvtk׻LJfQQqfjc_ơ.-fjTTuujk ĜX.333h@fx**nnJJx&&hfffgefe]h,U2333ͽšKIkfg66ïk uʦfWW||v&&fgGDּέ/.fjRRrgmiX.333ffddwwYY99l ffffeegM-333;ĜMKjfmVVf75tp{00fgDBҳơ*)fj ``ƻ|++fNKX.333f ghZZ|//hfffp {"ܿ*)ffy''wwbbfqnokfBBgf.-ŝƟ}&%forrHHf.,X.333d8fu##ttGGqffg0/pnбhepfk RR00gаgBBOOif~)'tftmmg{$"X.333ff^^wwBBmffk B@/.fhDD˽l v64jTTk fxxtm f|..~~gy X.333mgfww;;iff~'&xuѳGEgf11f\Yfyyjjofrvra^hgSS»gwY.333h1gt IImff{$#pmhejfx##==gϮg<_\gjoohMKfLLTTghdavrhk wjûY/333ejfKKDDgic`ո~('f~--˽t1/z"!p}//fpԸxfFFɴi~'&Y/333ff55fl pmnkgn66rfcfpf=;JHfw ŵuufgcY/333jfoy##frϯsfXXRRf̩fjjTTgm im 88g˨Y/333e`fEEpf=;;:f~,,mmfj55sf@>аqgttosY/333ffVVgk~wtgrdzf̪@?iUUgm ơ)(fOOf\YY/333jfnx""f87ɤkl ffngtpJHf??>>gӵY/333eVf>>__gl ™ֻrhfpmؽf``˿//f<:]Zf44i-,Y/333ff}}sf^[ygrrgRPl ~22WWfxƿlif}**mmfY/333kfl ==f,+0.foos54=;k hpԸ|xf{&&qvY/333gMf77rrgrӶ20fuu33trofl k ʧ~f11fY/333gfvvl j1/fNNg̩fqqĮphqmf;;ttY/333ffk ʹwf{x{#"hkkfgEE̽uhƞa^fMMfY/333gCf}//11febsk ͹fϯ}'&jggsjέPMfxxp{#"Y/333gfpp;;fYWؼkv¤f̪z#"foxx̺nl ֺ.-għrrfʨY/333] ghEEfYWf==ftqsfvǰk qophA?Y/333f>÷ttf_\jff̮fxsY/333mfh==f}k{%%//wrfiifNLfk qq??f™xl ty Y/333g4fx%%}))g™~zfttKKh@>gz))fqέz"!fx##tl έgBBoofֹY/333gfddvkֻ+*iiifkhfsf|%$ͫzwjgLLȯg?=YVfǩfokY/333fff{))HHiiϼl tֺgGGfҳfeeifMKHFfm [[fƞk22u{$#Y/333d)ffffffgr>>dd³g21SPfddfĿfaa¶EEfl ~zɥwf@@owfbfɫ|&&gY/333j f2gYgffgfffk ~//WWĴqqfheknfyvj<>hrýz"!i̴~))uffm Y/333ffzz]]sffvsqěy fs==h.-sjrl tkkffgƢY/333] fk ɾĭggufg;:Ùtf44f^[XUfçisÚf??ȥfgkgY/333gJfDDOOjfn hekihiqqgNLfhyb`ffa^@>Y/333gf~++fhVT¾..fz##ͶfOMͫff;9y m s64Y/333fgs§>>fgDB׻l ifPNf\\fffc`ͬfMMAAnY/333fif__λTThfHG~*)fHHfRPo55@@fĜRPfδUUfY/333fgIIfkqoUTfy!!fSQ:8orpj88ϰg32Y/333f-g}+*Ȯ--frŞ™k l ʮfTRb`fŦfHF_\fжosY/333wfzzrfTRչokťfUSfVVfǠj@@~((iҴY/333/mk̿KKfs̪uhfWUԶfzzn|$#SQgQQfY/3332%fDDnggeygfWUfTT||fάf||fSQZ033323xf;;fA@{##hǨfYWu~,,stvy Ըh,+Z033323.jqccf{#"sk ӼfZXDBjfnjfqpZ0333233f__hpոm qf\Znkfl 87Ϯf33g̩Z033323331.hįŦl l ҳ˨h}((f\Zfcc]]fkIIaaf{xZ03332333Ѯj}**Կol ҳfhhf^\54fQQfmj<:m fKIZ03332333vtfzzpl ؼ=;g̯f_]QOf55v~''olfi|%$Z03332333{##l Ծl rpufa^TQ>>fdbfMMgsǡjq|%%~(&fVVǢf?=Z03332333f^^~))jÿ\ZfҶfecfjm бͬjsPPih|$$kxZ03332333=f..aafRQf@@r}~'&Z03332333cafɬġFFhf,,~|gqҵLLjMKhNNjZ03332333k 00ssofsаqh99uHFk ]]fZ03332333ljfĤtft{#"g|%%,+CBoqn Z03332333n ~))vfwě-,fzzp?>==hst/.gf}{fŞf98Z13332333ؾfYYĝfrp}ffssiy Z13332333FEg..n ׼ffɤ~|foZ13332333gRRȤf~|kfԷn ͭZ13332333ONg{##q=[13332333ơfyyf^][13332333.-m f|z[13332333˪fooϯfÜ[1333233365jfֻ[13332333ѳfffppfwUsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOrOrOrOrOrNrNrNrNrNrNrNtP^^^^^^^^^^^^^^^C3332333>=iPPiS'3333333333333333333333333333333333333333333333332333پf]]//y!!xU33333333333333333333333333333333333333333333333332333DDgo@?sO33333333333333333333333333333333333333333333333322333gSSf_^sO333ܶǨƦģà࿙ྗ߼޻޺ݹܷ۶۴ڳڲڱٯ}خ{حx׬v֪s֩rէoԦlԥjԤhӢeҡcҠ`џ^ϚY͔R̒QˑNːLNJFA 333332333MMgf}|sO333ˮ۾ڻظ׶ճ԰ҭѫϨΥ̣ˠɝȚƘŕҏῊ὇༄ߺ߹޷|ݶzݴwܳt۱qڰoڮl٭iثfتdգ]Q333332333gJJήfĝsO333̰۽ٺظֵղӯҭЪϧ̢ͤʟɜǙƗĔÑᾉཆໄߺ޸~޷{ݵyܴvܲs۱pگnڮk٬h֦aR333332333WVff׽sO333ͱܿڼٹ׷ִԱӮѬЩΦͣˡʞțǙŖē⿋ᾈ༅ໃ߹޸}ݶzݵxܳu۲r۰oگm֨fS333322333h==oofsO333ͳ۾ڻظ׶ճ԰ҮѫϨΥ̣ˠɝȚƘŕҏῊ὇༄ߺ߹޷|ݶzݴwܳt۱qثkS333322333`_f׼OOisO333δ۽ٺظֵղӯҭЪϧ̢ͤʟɜǙƗĔÑᾉཆໄߺ޸~޷{ݵyܴv٭nS333322333j55..z""sO333϶ܿڼٹ׷ִԱӮѬЩΦͤˡʞțǙŖē⿋ᾈ༅ໃ߹޸}޶zڰsT333322333hhfѲoAAsP333и۾ڻع׶ճ԰ҮѫϨΥ̣ˠɝȚƘŕҏῊ὇༅ߺ߹۲wT333322333l --fa`sP333ѹ۽ٺظֵղӯҭЪϧ̢ͤʟɜǚƗĔÑᾉ὆ໄܵ|U 333322333sqf˩f}sP333һܿڼٹ׷ִԱӯѬЩΦͤˡʞțǙŖē⿋ᾈݷV!333322333n}&&έfƟsP333ӽ۾ڻع׶ճ԰ҮѫϨΥ̣ˠɝȚƘŕҐ޺V"333342333|zfşfپsP333Ծ۽ٺظֵղӯҭЪϧ̢ͤʟɜǚƗĔÑ້W$333342333qynnfsP333Կܿڼٹ׷ִԱӯѬЩΦͤˡʞțǙŖᾍW%333342333fzzNNjsP333۾ڻع׶ճ԰ҮѫϨΥ̣ˠɝȚ⿑W%33334233322f}}..{""sP333۽ٺظֵղӯҭЪϧ̢ͥʟ•X'33334233365fvvn BBsP333ܿڼٺ׷ִԱӯѬЩΦͤĚY(33334233376ffffa`sP333۾ڻع׶ճ԰ҮѫϨǞY)333342333?>ffsP333۽ٺظֵղӰҭɣZ*333342333=3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333335?3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333343??????(0` $2.DW,W,W,W,W,W,V,V,V,V,V+V+V+V+V+V+V+V+V+V+V+V+V+V+V*U*U*U*U*U*U*U*U*U*U*?2=ƎqW+2=ƎqW+2=ƏqW-pdj5q 2=ȏrW-y88nnddω\\OO@@s##P] 2=ȏrW-fQQzzhhKFmZW-t##,uu⧧ؿW-|88mѵؿcbW-JJ}ҷX-iSSqqּۤҶX.o'cfz--ZKKddsqഥίX.}22\iirrГeeSS88m$Uv_󼘕įչqnؿֻX.KK{vͯšԹѴX.v ppоžƴÞϲīؾX.|44Nֻàà˼X.LLּ ȦξX.q qqֽ šɩX.55DͮsrifвßǤɦX.q"2%nbɻcaƷȪԷչX.77£vsӬxoàֽÿŸҵƣşX.{//6ԶɨͲϽίɦY.NEԷȥ;ѺپƤşY/-D~œɦÿÞȣ¼Y/2=wdǢ›̪̫Y/2=ʓwﺑŠzyÜ˜xvY/2=ʓwĦѴ~|ƢǣY/2=ʔwͬѻֹĝY/2=ʔyǥƣ˧ɧȤ˩ҴY/2=ʔywv˩ĝήʩͫY02=ʔzÞϳƢήέ̪ɤY02=ʔzе׾έҵάͫбY02=ʕzơɥȣ̫ͬ˨Y02=˕{ѴŜȣ™Y02=˕{ɥʧɣY02=˕{ѳY02=˕{˨˪Z02=˕|ϯаZ12=˕|̪ززززززױױO$2=˖|ֹͬڷrH˖pɑgǍ_ňWÄOGV@ 2=˖|Ϯͭڷϝ|ܿԱ̢Ĕ༅ƊQC3 2=˖|ɦͭڷРٻѬɝʒaD3 2=̖}۷Ҥ׶ΜqE3 2=̖}۸ӦҤF3 2=̘}۸ժ֭I3 2=̘~۸֭ڶJ3 2=̘~ܹmHJ3 2.EZ1Z1Z1Z1Z1Z1Z1Z1Z1Z1Z1Z0Z0Z0Z0Z0Y0Y0Y0Y0Y/Y/Y/Y/Y/Y/O$I3 `?( @ [1hhhfeeeeeddddccۿcۿbۿbۿbۿbۿaۿaۿa۩U*zX`zY`|??mmffYYs~==SpzYa߀::,楥򜀀ǦtgӻbNNhɭļbffſũb`DDijj}}͵Ǽҹ϶cZZԣttbPȬƻӸ~|äc|;;'忿ĬɩƪǯƥťcZZlŪͯϾͻȭ¤ĤѶc}}ο̮͸ѵȰɩӼe::ƥƧǪ̰жԹeWWwhàͳʲиƫϲşչfaa_ʸ͵ɨͳѽвϮf~ͱ˫պμӸֽft[ԽгÛ˭̪չf~^ѷ˪Ϸ̩ͯg~^ͱȥҴֺ†g~`Ҷ¾׽Ǣ‡g`׾Ըʥؿ‡h`ֽԶӵа‡h`Ѳ‡ia׽‡iaĈia̾̽˼˼ʻyVa˼Ȑjըџo͖_}BKb˼ܷڼΦح|RUb˽޽ྛW)b̾¯κ[/bͿԩ_6_7ǏsƏsƏsƏsƏrƏrƎrƎrƎrƎqƎqƎqŎpōpōpōoōoۼzXY/(  ~\uٶٵشس׳׳ױװְ֯կÊj݅\\^bbFCCƐquٴoocͿ¼ٵµƿʹ˻ڶaaB׶ɴͿƶڸһͷк۹q99 ģ͹ܻܺnjszȦÿܻ˔xu¿ܼ˔xuݽ˖zuݾ˖zuڶ˖|uڳج{p>˖|uκća…fu³±߿߿޾װÇhsailcut-1.5.0/icons/sailcut-file.svg000066400000000000000000000126141477005247400174140ustar00rootroot00000000000000 sailcut-1.5.0/icons/sailcut.icns000066400000000000000000007121231477005247400166360ustar00rootroot00000000000000icnsSis321y]䧊fnw.Uń @ˆ͌ ͥ '}y⠌Gۜڜޖo͸Ēʶ$~g}ū^oȸ~s@NQ_gaWy]䧊fnw.Uń @ˆ͌ ͥ '}y⠌Gۜڜޖo͸Ēʶ$~g}ū^oȸ~s@NQ_gaWϭʊ׉몆܄ ܲ຃ vȵļHܻܾŬгmϔǿåUs8mkd; Wzsh! zڮ H櫙 ̩ꢴD *yI5ڋԛ놕>Adg܃sM¡s5il32ߎyYIՅLY_Q9nBm a~uCd >xM ,]iXkWZ+`̩+>吀l`ieBGfixvZOg^աvWe0w:d7۶czVr.QvkBɈFdk{MTbfR}^:sq{`.մefȼϳ_u啄mͨy;ݣT¸~C۵JO]8|zuz@kҲV)Y}p\55o֏K4iɑC2Sk}ψ9Zk+nȸrj9 XOIiH CvC+ '}zlF9nf\L.yYIՅLY_Q9nBm a~uCd >xM ,]iXkWZ+`̩+>吀l`ieBGfixvZOg^աvWe0w:d7۶czVr.QvkBɈFdk{MTbfR}^:sq{`.մefȼϳ_u啄mͨy;ݣT¸~C۵JO]8|zuz@kҲV)Y}p\55o֏K4iɑC2Sk}ψ9Zk+nȸrj9 XOIiH CvC+ '}zlF9nf\L.涚™˙Ҙ՘ǀ×煉 䲫棑 ռo |tʦ~ˀfĉ黱៥ɍߢϱάțӖ륈ھܡoڊɞ󘪀vw椉ͭˠ᭬ݞĄ٪Ոפ꜃Śz˜庀ͼݿȏڨÓ{ֱs{ɮpxϬmq u ~rh t`zx]l8mkr_#{/?K?{pYY|z=){)ph}&6Ym 퀸h/qӠh{ucaJoтdb ԮOnJdw>aBngxlTo>]w}2yNp[0dqN[GιrDCSAHn -GzWHN!Õ[kH it32PX[ ;c(3ƅC Ї SB܈j b  qXFQ & h1 ]O ǟ  @ 8W ؀7 N `ǁD  \ ΀  > jY q B/' v)D*J9\~U u|   c uo dr,A!}y x^Z# D, :ր)a -/ d*<9 1H*l *()> ) eI{ )nK`^(: NK HP( wK. K [}( UmM dGK Mz !N <OxEeuQR(ZQS M( aS  !  S/ h4 S^e ߗ&!/U `"V 6v P޷p"D 7͖U#2|  ՀU  7 ?w} :ӻf1 & WP mAyU>@  {O&  / ۢ   ) ,{` , DK ֠ / C|%ӽ@: o[4 ?l1Pu   '5=jt z͌"!h Z~ 3 ( Vu* z 3 u< K3  J ).D&%: 'm( ? T (3~a ( < om_ 'ܜ`F r& fWv+ i& Iٱ"lS(֡ wg%p 0ac $ Ց Ъ$# WԤ' ?  S $a"љ/ ?z  ] ʁ"9߫}ń ޹ aͨU"ߏ Đ ?#ʲo"S6# ! Ǣb "qݢ{  b#  nĮy> { o 7 .q? # .F =e(ӳ vN"  d{V ј xiB  Gؙ F  o :mJ& M׮  {˸0   %eֹ &ɋ % NԱ <Ʊ: ( *\Ӫ Qk ,  'T}ҝT2 %Fkr  "2_y>L% 2 ͦ  z2 \\ %\1)ʛ  n9 / Ȯ?  L/ wƸX  Ie . Kĵ` b' -§M $T + 7  # ) j_( 9q* %m) # R ! Y`,)}V$ }\2  tx]=  HoW9 }mYB)  [ ;c(3ƅC Ї SB܈j b  qXFQ & h1 ]O ǟ  @ 8W ؀7 N `ǁD  \ ΀  > jY q B/' v)D*J9\~U u|   c uo dr,A!}y x^Z# D, :ր)a -/ d*<9 1H*l *()> ) eI{ )nK`^(: NK HP( wK. K [}( UmM dGK Mz !N <OxEeuQR(ZQS M( aS  !  S/ h4 S^e ߗ&!/U `"V 6v P޷p"D 7͖U#2|  ՀU  7 ?w} :ӻf1 & WP mAyU>@  {O&  / ۢ   ) ,{` , DK ֠ / C|%ӽ@: o[4 ?l1Pu   '5=jt z͌"!h Z~ 3 ( Vu* z 3 u< K3  J ).D&%: 'm( ? T (3~a ( < om_ 'ܜ`F r& fWv+ i& Iٱ"lS(֡ wg%p 0ac $ Ց Ъ$# WԤ' ?  S $a"љ/ ?z  ] ʁ"9߫}ń ޹ aͨU"ߏ Đ ?#ʲo"S6# ! Ǣb "qݢ{  b#  nĮy> { o 7 .q? # .F =e(ӳ vN"  d{V ј xiB  Gؙ F  o :mJ& M׮  {˸0   %eֹ &ɋ % NԱ <Ʊ: ( *\Ӫ Qk ,  'T}ҝT2 %Fkr  "2_y>L% 2 ͦ  z2 \\ %\1)ʛ  n9 / Ȯ?  L/ wƸX  Ie . Kĵ` b' -§M $T + 7  # ) j_( 9q* %m) # R ! Y`,)}V$ }\2  tx]=  HoW9 }mYB)  eiieovhhqޝghoiorhqtqqetlqłwhgxfq΃ef~jqքsesp݅pimUpydkd`ogjljotosaoqorjqfqpigtsqČeg`dwnhfeqfq iefgjhkf} pfqogUorgp yhmogfpojgoghlnf opromp godftpq n nfUptso hobnst݁wg`ormguptӂqdmrnholrɃodbmpeao΂nfpĄof nohjnÃvdmo fnՌpimhpʄej}h o~qfiqehfUg dpɑnrghpgfrbfgboǗoqfU `mogfljhoqigkrem jjo igpdypigqjkmoergn+Ueqqkfgg{k/Uhqlxffsfoqd-bgsnqgsrna/iosmfjhgxomotcielppq1iqbggnqgfom3joeefepnovh4ppqhfroexmh|~ffofro`hmm?mmqhdpomfomgg@ppcUpeon]UoqdhfBfumkeln`nugvpjCUlp]oghnmokgpDkobncflinehoFippdexegbnmqrzhHnoghngemrrpgIing]nejfbppmJbmodUpgrnepKn}p``pfmkqpMh{nijoeqmnfhqzhOfmupffngeyeopgmƃng1kogepdqqht{rf3jpgonfpsmm̚oqe7knfpmbjfflɣvnkc9gntgjoifpegddoӶqpkelV<R4;f JY{YKqgM>.wv  & Xf1+6Pd?{#44Rs P~fn "X s|h!M e*NwlYTQ@#q.cy';%$:k >*u?Q?LA:LFAnB9JD B#7liDJ  ER M{Gq'!DV\ L%H&%k* IP JSKnQP L L(M5G*4_Mb!;KO 5iPck<pM*'-5))z&J, [ kH l۞Y#;rxX>w߰l54G~>|‹V)M5-34Jo&Er.7xDq]sK(VRF5vpeS,x $~4KC9f?j4uUs ') >x "*T $ t# R4e9G63|01 z \M1? G>mU-F0)-!1.EWmkO6_()?cww#D/ 8HmkL }^*?c#ҍLZ6NЖ[+`!.&}鿂M1|$eC!ď\1$`<P`g3 5qM%3fBj .W7>z-/=|BBCD6m ,7Vj}z +UE=n ߃-PoA=8k!sʀ=0r2 yB߶~P%\˦yL"Ѭ\;ic08[ jP ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cOQ2d#Creator: JasPer Version 1.900.1R \@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP ߂@O8h;kܯb Zq 6p Yj\k㣯vNˑ%Fw\~ x߂@O8h;kܯb Zq 6p Yj\k㣯vNˑ%Fw\~ x߂8O8|LTP2oD`K0&òcNn/aƺ[x:]A(הRm*\;+iDЬ+7P1oMH+ I~IH7g52&4Sl~'䒄';޿ߝe~u`ϤRS)W):)˩CXKQ] U:xx[T2 ;+1%y 0[454ODZ)Y+Xhȍ\ɣh bTݲSEWaj̘-c?[?ipW`|~OK^ew8!܊ilE iѶ]Yw.d_xFA \D=m[ tw+ƾ22uzrܛW c72%W'ßsHPX̣OaspVFrfM@1!,^ pBe텫K>76o=K ԝ]}J1CC>v`-PtO1VFjH7=`3ʧTfhcbvE-7pKGE~tZ$:R.$Jߝe~u`ϤRS)W):)˩CXKQ] U:xx[T2 ;+1%y 0[454ODZ)Y+Xhȍ\ɣh bTݲSEWaj̘-c?[?ipW`|~OK^ew8!܊ilE iѶ]Yw.d_xFA \D=m[ tw+ƾ22uzrܛW c72%W'ßsHPX̣OaspVFrfM@1!,^ pBe텫K>76o=K ԝ]}J1CC>v`-PtO1VFjH7=`3ʧTfhcbvE-7pKGE~tZ$:R.$Jߝ_~ub%}j!#x*6 v1(Ψu,TZXo~N"3$B8OGi,e̳|%)ntOXчE= gtv*ATc5+MLQ4@*uuDZ/ 26e,[*:z8þjijUuoϙxv,ڣ,`lE"Z[4p0/hctY9'I@תo,y3rSFbE~q~uofʇjT.X[ \rsgKN,Vyi+]T|_xtk٧`i"v[qT 2bEJ"^板 Dwpg!F Fȏ C?`zLTrb"cUt)`nN\Q?v s+{h|FClj/ M¾Hzo&>TP9$O$@^Fnπ11Di)6) ٔ9=]\P 59*r?֑cz Ib$ٞG>~&s]q+BB&T $'9D&]o?L~12#Q |QrUBJJyS: &q57;^Un̿ߞOàY4[e(g i3"ƈծ8`7e2h=U΍uν=#'L_EOQsM~_|^~x箔T7jW`ۙ+t$z'Χږ=),l\SF" 7!L1ZZ5:?H(6F q&gր3&d8k[5ӔҜ^P+B3HA1kԝB<ǫ0-|o` -'x$َER3ąr:nkCH i`'ޮUaEy˵lIdH>!LߧY䘦HjF9.9_4εtI(kĵ`*6I}G1^JPN B R A"R7Pf A -,p95+`{|mu_Ez)U'Qۛ1j.?ehOM ~s \<)|Iޫ'Xo הxM HfGđӔMV<٪|ed%9ʿDvg2ݚL8 ITfϧT+騂{VAMA{gaJ3 n+HWh4N *`gUiG;>38w Gʱ1=lW! I%6?N\-IIROMqV87J;BbG\F;_[=hN<ݠ*~p1X|sWZgi>BӛHW4vry0aM* &MҒ;7u1ą\3k.:˅mB"VYumSn*/YШV#JeqҴRww9dq~R8` V-rvkjVFz1 s#.߬kd&DN\ֶgJwt^,]r{:h%sBhp2ޚ[Vum4 +Mȧej9G{ ln:Sэ;7UI]@,k (ʺ^NhQKN/F?#RC{sJxJbp.f8jw<Ԯ@o~"ga$wZ`p TLciہ ~QA"Q絋xIl.9 o- { kDVa_ z:쁡d-&w;5z_VG#Y4VWr(cɣjAs8=.7~"A8Qkz |8|OVG$,1 k;6`RLf.0Li l\- 7o7r=˔kSb`莾|Fv4 ǞԱVW ׽gư日R5yVarY fK fE>Fzp7>ߞOàY4[e(g i3"ƈծ8`7e2h=U΍uν=#'L_EOQsM~_|^~x箔T7jW`ۙ+t$z'Χږ=),l\SF" 7!L1ZZ5:?H(6F q&gր3&d8k[5ӔҜ^P+B3HA1kԝB<ǫ0-|o` -'x$َER3ąr:nkCH i`'ޮUaEy˵lIdH>!LߧY䘦HjF9.9_4εtI(kĵ`*6I}G1^JPN B R A"R7Pf A -,p95+`{|mu_Ez)U'Qۛ1j.?ehOM ~s \<)|Iޫ'Xo הxM HfGđӔMV<٪|ed%9ʿDvg2ݚL8 ITfϧT+騂{VAMA{gaJ3 n+HWh4N *`gUiG;>38w Gʱ1=lW! I%6?N\-IIROMqV87J;BbG\F;_[=hN<ݠ*~p1X|sWZgi>BӛHW4vry0aM* &MҒ;7u1ą\3k.:˅mB"VYumSn*/YШV#JeqҴRww9dq~R8` V-rvkjVFz1 s#.߬kd&DN\ֶgJwt^,]r{:h%sBhp2ޚ[Vum4 +Mȧej9G{ ln:Sэ;7UI]@,k (ʺ^NhQKN/F?#RC{sJxJbp.f8jw<Ԯ@o~"ga$wZ`p TLciہ ~QA"Q絋xIl.9 o- { kDVa_ z:쁡d-&w;5z_VG#Y4VWr(cɣjAs8=.7~"A8Qkz |8|OVG$,1 k;6`RLf.0Li l\- 7o7r=˔kSb`莾|Fv4 ǞԱVW ׽gư日R5yVarY fK fE>Fzp7>x0wm4T ʪriUJCճ36g[TA*+4 CMl678J+ &ƹ7E;#ЇxaQЏ.ɆXm)ľ\d[ ^2 'h0.hKRRC)RUk+RZQqTO]XѰ./R,* ,,js&sY E^-Af?k/"7 N_OR~)Q-~]^*j. 6`rz[3\Fpp*.k織pylU)>@#\fei^4od&)n z+["hPf-%'\> /_rc\"xӒ|szedqlK;Yj s`W xw>…ftv~pgZ@ejsc&ڝ?D/k0ڥ0k:wl0(u\]PJ?pR,m)nPҡǽkRJk%<\v;ybh\. ֪muG2cy)H,,BFSٚ_jYyg9JN[3r".E^4@8-!pۤ$ 8YThҷN L+-?<3j#~2DzELAr7W rs//3d'ufwE*:>RCPVLjBju건-/ޕ uZD BgD1GThN>ۺ*\[GߟAWЌJ6Cj#{9TeB]-.lMbp~HgW|ϕ-m9r5L#<x(PB5`WEĔ*%notX~ ʮ"(N 4BӤMKn imvJPܲMzaS%b_-w9oT Y!\٭ -^ ΰ1\/o iR-bʀ4D-&*Z %+Tsz^_L0NgOhzQ Rx`:/MM̥7Rb?7"fiFŇN0W(Q_3:VԈ`h`x/L' - / mgC~1 e?#;ʴzh@+3TGۓXvJ IOOI`_Ib[R| {b*|((BX j{07wۀztڥiS.ؤ t-32froƝ5/n}mzs xI4X/A .[/ Oc;:fV);QSbP:9=UX"<[&YdE _LphFtHq w t_?2+}D{[d#`6D43沣B@QDqLYG15(rODM5H!+^+h3WzwV*72: )|\H;BO \>V4M'8&8J [yjAM,SX5jWXp7dtzpLߣ-ߎԯ g-B9Pwp![Vtj߾}D`'jfZlG$<Iйb>*5d/CWx7_97*mH@dꮴm(SYAM,Ju|d%^ ؗZR[o41aH@RarXc`i>bUU3]Dȹ2^[s<3maaK4{mjkmmjT&Y/-4H}G|LaD br婹{UlsaeKD[=xr^WV nZmR~m(Ġ7RGO:aQMsjtDž^Ƈ:xEߨֈ7 IϫώpRT/P=A* /5Ƭ늻jV]p-8pC9M 3-l 䢸|t뇵AQ_tɾ0!ЛB*#rWVx 5 :iŵa]!yZ.νO.^4# C%8>fYo&wtO*7f }rJkE֓tnJA%]ߑJ>HsMpц ;u8y.ҌwG=DHі?}.]~eAEh)$͡MU Vh/}G@@Ly/ѭ ;]Kun@36ߟ=Fc2% aO/~#Zw6s=CU=LXu|/0c7bzaڅڐƢ)R._̦! Q lF~3gY drh;xkPn]jf>cv~)w9$OZ% nRX"/O圻q5WGf&e0IOZU޼H4BJuI]@QPaδ*a,)33Wdϭ-BDy+啲"Eܽ=Z Q)2xT>gBL8#1'QckLi{ acYl/m[3ktPQIݎ?M-y R@࢖bTʃ6|ug'SsYެ` P0G,}HZHjf`əvrњwX(wciX=Ѣε0  ZR:A؀!{HRbe"9^ 1TNK*T1c?tzL?m7puSK^*bx ,J`SwT3'Hg#˚X8H_̝V5j8tĢ4AsdkJAe v }qQ4I[%~8yhn%$P"4Ri;"8hW]b5/}!ƌ k&l2>יÕSQOjQ}u %,Wu`w+~Eۇ S}8|v!t\ 4%j)!y}QЏO?߹ =ɬ8-2XB=;k+k44 qXu%^VfEM??pK/\Jxg $ &*D.$qchQe=-DV.ilk^*('JS%Z'>Z͆>s"T\j8ΏU ٪e|kQ.ڞ6b~-6ʬl  :awQbË*&?MgQHiaHhqm}5r}@7!C,3傼e@aXZp)p"^rLN$iܗˠ rו\uYլEb8 m1S={o2l8nݜ.;L.5DHv| Z O:4XUf|t>Б/QKAS8hN 'X0AyHΥfಐ!͟-բ]n9 O{oیz ṙ !ԗc$@_v2_, x71r[0!Q*%Rɢ rn7E1TT\mPJu!Cz,jlu "nיjƸ^l.F/ ZWҲ./_Zoj }Jr{SߋiuT}ZTYA2=#j6@X7GUS|р۾!qrsoXH.o MtܓcHďQ eO8kTn6l_W,䎹›43L{/Cpz::QY6`/ ZGGEJ=ضhE;m3LgJ S7J^D8Ptuщd08`Ӟ7uC,B_d(]l7P+Ҥ."Xzw'0I)\BWptg{p;'v"wG#>k#mnql٤}qa y%8U{/n/o 0"L:]BltST[=W G mR F)kz"BVu wc$ dwPq[^udK۹RO2 :_4aˌ^hfљXlŋ(6 T-N^?}cs YvHbnݶH79縄G:FiϨ nb$}@p F_@)DHC\sgІ&|έgʔ8h02v6l|UphR"h՚g]9m0'͡X Q7be2 h>w*nү A+V'G,vrCtaX#*o%$˽Y&lb;T@^y:Δd_Cav@+袃zѬ0mkw^C} q\|6A9"; ĵg_2}{>k7,%R#pó*Kf'n.sHwc(vpwNE+6! /偖fD5@4ƟqSr0 ۧJjE>qԲ/yA>J#Կʽ߲˜)@AV0;zZ+} {J6̯g3; gMYV pr ,yޭ s<&pH,׈ h(C?OpA#)Rc֏)C,[CYnf')޳u+^;M.OTc0̴dPr-.:h|?-}S# g9U)x_$%0hvnG} /;I թk2,h/0g:,LAC;@'.O?Zl;0ٶVEbjp'*P>,o,9|w6 fIO7PNyq|Yև/+̉Vޜސb֩klBDbMV Bӈ^dЃ}cߟ=Fc2% aO/~#Zw6s=CU=LXu|/0c7bzaڅڐƢ)R._̦! Q lF~3gY drh;xkPn]jf>cv~)w9$OZ% nRX"/O圻q5WGf&e0IOZU޼H4BJuI]@QPaδ*a,)33Wdϭ-BDy+啲"Eܽ=Z Q)2xT>gBL8#1'QckLi{ acYl/m[3ktPQIݎ?M-y R@࢖bTʃ6|ug'SsYެ` P0G,}HZHjf`əvrњwX(wciX=Ѣε0  ZR:A؀!{HRbe"9^ 1TNK*T1c?tzL?m7puSK^*bx ,J`SwT3'Hg#˚X8H_̝V5j8tĢ4AsdkJAe v }qQ4I[%~8yhn%$P"4Ri;"8hW]b5/}!ƌ k&l2>יÕSQOjQ}u %,Wu`w+~Eۇ S}8|v!t\ 4%j)!y}QЏO?߹ =ɬ8-2XB=;k+k44 qXu%^VfEM??pK/\Jxg $ &*D.$qchQe=-DV.ilk^*('JS%Z'>Z͆>s"T\j8ΏU ٪e|kQ.ڞ6b~-6ʬl  :awQbË*&?MgQHiaHhqm}5r}@7!C,3傼e@aXZp)p"^rLN$iܗˠ rו\uYլEb8 m1S={o2l8nݜ.;L.5DHv| Z O:4XUf|t>Б/QKAS8hN 'X0AyHΥfಐ!͟-բ]n9 O{oیz ṙ !ԗc$@_v2_, x71r[0!Q*%Rɢ rn7E1TT\mPJu!Cz,jlu "nיjƸ^l.F/ ZWҲ./_Zoj }Jr{SߋiuT}ZTYA2=#j6@X7GUS|р۾!qrsoXH.o MtܓcHďQ eO8kTn6l_W,䎹›43L{/Cpz::QY6`/ ZGGEJ=ضhE;m3LgJ S7J^D8Ptuщd08`Ӟ7uC,B_d(]l7P+Ҥ."Xzw'0I)\BWptg{p;'v"wG#>k#mnql٤}qa y%8U{/n/o 0"L:]BltST[=W G mR F)kz"BVu wc$ dwPq[^udK۹RO2 :_4aˌ^hfљXlŋ(6 T-N^?}cs YvHbnݶH79縄G:FiϨ nb$}@p F_@)DHC\sgІ&|έgʔ8h02v6l|UphR"h՚g]9m0'͡X Q7be2 h>w*nү A+V'G,vrCtaX#*o%$˽Y&lb;T@^y:Δd_Cav@+袃zѬ0mkw^C} q\|6A9"; ĵg_2}{>k7,%R#pó*Kf'n.sHwc(vpwNE+6! /偖fD5@4ƟqSr0 ۧJjE>qԲ/yA>J#Կʽ߲˜)@AV0;zZ+} {J6̯g3; gMYV pr ,yޭ s<&pH,׈ h(C?OpA#)Rc֏)C,[CYnf')޳u+^;M.OTc0̴dPr-.:h|?-}S# g9U)x_$%0hvnG} /;I թk2,h/0g:,LAC;@'.O?Zl;0ٶVEbjp'*P>,o,9|w6 fIO7PNyq|Yև/+̉Vޜސb֩klBDbMV Bӈ^dЃ}cԢ>S}&"ہRz+8%**ph}N{Q!Iۃsr7f4[)2/2d>L}d\?bl䝀d#,XwhqV?Q0iCJNʃE9~@ =_ sHnZ8Bl)8݄_c ДeSMmKŒo+;1E[H=ѻts{."rs am݆P 铯.r2 Vw^$AP߽70 '߬4^i_C1(d@FIuMBPimfgoCƺ+:GZt&UD= 2u*Z|Hbl~[L:8 q>}JUw/UP^(N`S8?MD&w<%[3@Bl`iTN'9i3҉ N1f9k!b)1y.=#xJk.fK2L{TX;>欠+lEC]-*w!iT apUc)Sxxba6uEDqWY8r/ |EaMD0A0آ}>8'cw+LK2k!޹C9ީ/+bA:7J CnENqCaa} 'Ò& _oANv3VwLLt}0r+4ݏ$+{&bd|ȲV 5E W&$a1Xf$n$\U }H:$IWL}ExmښzĺDmWnFKY.3 9&gg#hJ3!rpP5r`C_c1)=RVM0K,#6 XIڞFŸq̾)J/^K瓜Eua0T¤'Osș͠rّͪɽc<_@x->&.įg۴a5%4~? inC5.䕓Y8&E0 3 Wv^ʇ*hR-:.ϖ]PZ!GLCS29Ly:eK+`#ڂ&x;ѱ7o _^*pI$\=h/Hs1nll'C@g|Rz* )F?|>h^*]KbdI6IJֿt\k @>\ɿ RA{$o,03.Z{G)ٰ_ r=0M5L;ekaQ Qߙ掃CڈOL}#(3 Ah-.3M~&&L9X@jvWJYc?k7l/{zhE$ aE^<YFA[ yy^oH& ؾ)}C4 ZVLT<1,ҭStb4q\6G{mتt XkʩN87.\md Ew!]sUvr|@!w,QaB}oTW#sYL`N`BOCf^m,a)&Yb3fM X|R@# D?Ͻm-9Udv}F&G'|Hj iK ;Ѿ7>Pp4)ccɩjyTEN ߟPm@>w!yAvVS,p76R=0U <DkY1P,yCsbS>jM6HTáJ[)x}aa>0é2׿oa8NdauC!@wU\uh\|| ^Y<xr.ԅ բcŎEQ:LB\_؈v>&⾥Wj9i=h<3ޝ!dGrE޼qJ=Y\E T:t S ]EtoP_9_kyW6fׇ2x.}Qa 8;[D@B*ѭJoK:RGGd5\GEь!1isφ%1x Om7>L;9_u냸ا']bHr=a?$nPi6jEŢN8d鉰 h1AJf6 *Dtd Ʋa"%N?}Ш%; r\񔹽W~m h vŠg JH`qDZ։!m}Y%߈E*4~{<UM|dE"H*]r@Rn \l%lV#cqģ C$ãijHw[u$ W+i{jrW&[]"MK lE+^eW`2RzN,ߟ]B X؁uw leEatϘioaV5V >0B,NW:uk<#XL,ŴI6/i3V.x!>9x `wUvd.ոb\%ߩyuH1?sHe2Lf.:eԔWˢص IǞc;̪Ns5hh˥';T8T;_.RqW2'm3 o0z&".O_%I4wt!dOqeP\;a5"!H1{f)|% p{ƽl SH}_ UXEш'ŝHj#ѕ]VUIb3L;0!:GEJ>58 +YLYu2`5&)v5-4fii,"j,3ჍW6f2cPc쉒(UىC(g4{JFŢ,jC?ŶpYWFK'xtEzmK)H!d*y:K 3_B%W2W!l-|GWjk%TX%Xv^} qPIJ.1#<)~5_I9B:#^E7鶯ЦHso9Sx9}\*+S۔_Wܠ\XbkaEZ$s|*zR@lJJFr9C|@X6)ڬL뭦{L#Xr۫ w*;r+#Ǐ'*y Kፇz(]#YZVLRcI6X=&~VǃI߂mW#6~܊-gy<4GkOn*i%Ef;S!ڋ5h%f0565AY? G1h@bp[й O//?crxe{2Sm(`rxFte~y)RDZFB?i - V \ūF @&MGL'pJkx/W7{Kܼun*-eʌ<2 Es¢3;ڃTU1?K ߧi+fFάo  o؁cXgqg['H4+ȁᦶ͕{ٳVMsY)%wr,gjrAV#®bϰIs HGa(Mmn`H>CYo!KU *[WL N؈W"Ye!T,~6zɇm}ud-]SUx4`Qq^g82 gfexL8ieâr0KL_DM˗3NƫGME]r FӨ),֓-ByUڰbIDbq^GSLLj0QoYnRR"Uϵa_NHU܌>"G(F%Y"X eq%$*/h{پdᇇT19|c{NpH?9c-TYTqJu~c ~?K$*yY(YMTls X6tASG6hν"(oy9ҿVO&Dnm_"Wr*JI nXd@P+.pBf:Lc]PyeqK!/)MhU>{$ԚoGFW> -JUՐ%v7(j^ۅ䷵k-B}.ܾiR˝/_Ot7&xY*h[; Yo*| (bO_/?+^ jN_>[tI`V`BҪqF yH]M.;6Pl$yZ~zH85Yl4I oj Vf|\ jgy@fNWTFs5Z 71;w߶5qQrfޕc3`O 5E@ʥ"` \0§ϩٻ)=g.#De,ScjoCs 61D p@xUrR'qb^!OoM\N=r4]Q/X}dbK ܊0)(ſ<(htGj.ju@Kk+!`iJ jVa k0"Spb_&,%o*Aɥ9l Bɵʄ$s 6hDĪ1ߨ& l <?U(#J:ʈ\ ̽84o6 bmj\Oɦ'=@͎ĪT<G=]?45ցw]'WtRm׿PkJLКo-ێmC?˔drwS"Bb{ٓgaHB> V4N1SF1jS2쬦q@D ygj9Je56Oݳn/EقDLdڍі!C:$Тq% jN#2#=jr<Akj:-fG.5&T~]]`dęΐdq>w!r9H-GX4O6yu@{s BGx|r3o׶mtW fCAvy>m>-x_w\6 jK˫2XїrO0{s5[IGL7Dn}H9Lsb6SP[ZI0uR^= %GM/~70I6 J)?%;r \u&NgD.nBجJkoZKU^YqDl,;4n*TUVjbE"wd禘 &e5zjewZXi#B%jS~;Ɍp%#uВwQT"șuse1b~G( ;>"FW3Q6H8Dĩ=495]3?|h ^nuH'7I\0Kg#z̄v4𖦬]my=-YJۧ2MU#⃺W!L ,j)(ϔE˗nj=Z¤S"G@{U(%Rfcyr)Qy!xpN=4giM[ 5uvbɾk2`f6`4BP(=uV^ӳ62k<&-+3c',l*PV8%f2k5d&.LB>mc\T rߚ?1bdծAByxZ* ca&4xon;{O+@R)Hp7:rut>mtxx)dD[㡖`D؝m|Tm\vRCjQC 8oOa~y8Ugpg*QVrʺ\D(si A^W'pni^negjPp&Sjҍ/R}3:aHտ0,2X|Vn^1g\dҮ1/ꑨS 'QSIFQ<+Cjq$mEeǷAg- HR xT+M8Pr[f-o,քsDd}[n?|ps$`<xMRkx|əIYuSe2"srCĤԽ[t5#gyzI ,w˩+r=0BHga(ϵW- ])WSFqNvn_zut+uHO0LsL]~mRE!-ͼ^2B5^m%꣙[CY\ %MmGXqw 'VG)Cn~]Ԗ-8u5Yym,oOJ_Ua$T9Rv'c?cr!e>8Vfp* 9ؽWM0oMTh棦dK!: .F?tfFPDTzuۮHu(_bZ 0G]}*aT6:AlPw9럣ZcW37]nֱwH#̪_jW:I,T`2ZN8- }WR|gqa vơaJ)7YgpǀbpT?땨c,>Sf?@`쀑,H܂5/[F".YVFszcjr|NSu5h9 r/meM4e}vc߾K!LS4@Jm-PsW\tN:RXV-a>tV\.ǸY@4Z!ajw׬)6܀+H3Jߚ܏c0$TLK.́|mJx:6h9U@g_ k1OrujZA u(EI/0-2#\1ԡPMR)8썅Ǫu"E3&vlXA}4-ŨP o {[p"D2I3K:}uuڞ`4Qz& + u/kDn5?X(90rUJWƏV MRryq]EF$!u4XJ=@J6/t6 w4YTadͣƼqx=HYN>[y:ʐx/b3r::婿$wZPcU_DU(W/P0kΧޣVҨ:em}6bM#T [y[xZbѾ԰ 4S/MYw5HJIVg: 0Aְ<+Rvwh<(9/u> FႶeEGD [Cb v-)Qeփ-L>GN>W{qpFr V{V= pڵs䄣LҤ%lH8F0SHrf&!,)~N6> ܱ9D ͛<(nzfct|:3WѶ]5 q`:>߷\\c_#FAUk\:m}d>H!랶6piXH \ 6xqX>$:^ɋMo;coJV8^?9ޚD{o:Zytl]JE0R.^Ag`86'`Ayl9/ζ"u:%]sT:; ‑IO{lM_^B6hKI9А LSYAǦb2̪/mr8l PdXE aC,k>;lm*T'&5L0w{xeO,ȑNްO99p]Z3Ș˓B\q$NUxiwemQ֧dr8E- B[T)&3}ș7xM`u|sC/ں!W9ѣ. 9ux=._#r{{zfxj6VR[yO$ٓ6yvoG$}%Z1Uk6eBʡqKmFjKJu+U .{$lMIkED4 z|I,'AbJmOe Su2``F؛&(FG,{5x!_".ͣ_Z,b#ū`~Lߦң bF]f&gE5GlV^.\ߩF#SMdT+زBN[uy\'>#8 b>\nB44$8%mZL(<P?(I%9v*ýo=iL(r&=]*2r[nš$XV"٨whyBH̊mƹ`$NzO`Ԝ(b֔Vv粯\UV777KE5TȮNDz:;_8d"I1* .eF zB-Zg9em^  igle/mŮ 4g<4^sBsgw.,NQ}D\e#]\~7=yh>NEN (yԟԣ#uFc7#a5 @b./{kMEU2i"04{BC|8e M|In Ө]'$PJ wCYkNט=ƙ;qj(`oO`8F`8ŀ6ZrYφpAa6bs4Rm U]adnc)x1I`*rߥp rr.jS4e9Hq@aqʒi찥 aiΨ[IIȺ;0gc{?Ċ6&swZ2J<~n5rLF߭=r3KWO=a@UͲ!)=I uiѰ9-$|hוU>#bX3zɧ916J}xloD]^}DzcBhpr e\+] [C?N~omz!Lcr,бK/JG":/^D  yc݀Gg,.6z.\-uu_ Yle)1)58RJۗ9&y b$2YO 8l6 6P8m£f^C9Sa+J]"^k9dsM~'G0Q>eG]1/n@28;hw=^¹ '.uƩIhH@"V #좣d%ֳQY= {NK 4۲)*v oMyzq'Pʴz̳C,&09$q2UmL,\T]1K¡;ԥ@/O_@2n@&֙GDu֟3?UKK{9\א[n{0yM-}w$Xkڲs*a' ڕ N!k~Yj/,?ˁ^TJ ODLylxoy;rvAؗ{&lRv:xL̲ۻZ%q?#@5GIu0=c%j*apa;ApEFlR$-5y8T"!i\#ֈ۴nHOBynO·J洗II@]tnE5PLԛtJvΎNo}aA뚃v%Upϧ"U0S:=@ 5dNE/yXIvH #)DzZ5v Gtt[4pPi"(,n H.k׵d8BgP W\xF/q7w3&U}Y"?RG+Ǔ2H]jYm|1lK|Z)".^PF]XM]nY؛\e}zb!.F8Ht}jDI>~4`($ U!Of67Hrq"3֯_CPZ.ٗq0>$uv#F?QMsСcVĔ]gvMUTS!ng`Do^2te5[c6͙JPv徦Oa`@NPl X틪 ǩqbC `(5H)u۸0!LNȍϹr|+MΈD7u#yVu݇+ilԥHUm,1˵sl&ea\= dA_ʀzZQB2ZjA?G J.-42VJ1YcU!dP+ag8&ZOf#( x2_!oƉL]NNs w^fشMd4o8q&3kp`KβHޖ &znlKŊ_]2 DҤsib}b%G5@ <&G~ nPV̅u ,oa1~I|ORa6I0z,.=&uKLnc%> H>.d~)7k֎-W^e@F ak}8 z#~C?mz"WA` j>Bɵʄ$s 6hDĪ1ߨ& l <?U(#J:ʈ\ ̽84o6 bmj\Oɦ'=@͎ĪT<G=]?45ցw]'WtRm׿PkJLКo-ێmC?˔drwS"Bb{ٓgaHB> V4N1SF1jS2쬦q@D ygj9Je56Oݳn/EقDLdڍі!C:$Тq% jN#2#=jr<Akj:-fG.5&T~]]`dęΐdq>w!r9H-GX4O6yu@{s BGx|r3o׶mtW fCAvy>m>-x_w\6 jK˫2XїrO0{s5[IGL7Dn}H9Lsb6SP[ZI0uR^= %GM/~70I6 J)?%;r \u&NgD.nBجJkoZKU^YqDl,;4n*TUVjbE"wd禘 &e5zjewZXi#B%jS~;Ɍp%#uВwQT"șuse1b~G( ;>"FW3Q6H8Dĩ=495]3?|h ^nuH'7I\0Kg#z̄v4𖦬]my=-YJۧ2MU#⃺W!L ,j)(ϔE˗nj=Z¤S"G@{U(%Rfcyr)Qy!xpN=4giM[ 5uvbɾk2`f6`4BP(=uV^ӳ62k<&-+3c',l*PV8%f2k5d&.LB>mc\T rߚ?1bdծAByxZ* ca&4xon;{O+@R)Hp7:rut>mtxx)dD[㡖`D؝m|Tm\vRCjQC 8oOa~y8Ugpg*QVrʺ\D(si A^W'pni^negjPp&Sjҍ/R}3:aHտ0,2X|Vn^1g\dҮ1/ꑨS 'QSIFQ<+Cjq$mEeǷAg- HR xT+M8Pr[f-o,քsDd}[n?|ps$`<xMRkx|əIYuSe2"srCĤԽ[t5#gyzI ,w˩+r=0BHga(ϵW- ])WSFqNvn_zut+uHO0LsL]~mRE!-ͼ^2B5^m%꣙[CY\ %MmGXqw 'VG)Cn~]Ԗ-8u5Yym,oOJ_Ua$T9Rv'c?cr!e>8Vfp* 9ؽWM0oMTh棦dK!: .F?tfFPDTzuۮHu(_bZ 0G]}*aT6:AlPw9럣ZcW37]nֱwH#̪_jW:I,T`2ZN8- }WR|gqa vơaJ)7YgpǀbpT?땨c,>Sf?@`쀑,H܂5/[F".YVFszcjr|NSu5h9 r/meM4e}vc߾K!LS4@Jm-PsW\tN:RXV-a>tV\.ǸY@4Z!ajw׬)6܀+H3Jߚ܏c0$TLK.́|mJx:6h9U@g_ k1OrujZA u(EI/0-2#\1ԡPMR)8썅Ǫu"E3&vlXA}4-ŨP o {[p"D2I3K:}uuڞ`4Qz& + u/kDn5?X(90rUJWƏV MRryq]EF$!u4XJ=@J6/t6 w4YTadͣƼqx=HYN>[y:ʐx/b3r::婿$wZPcU_DU(W/P0kΧޣVҨ:em}6bM#T [y[xZbѾ԰ 4S/MYw5HJIVg: 0Aְ<+Rvwh<(9/u> FႶeEGD [Cb v-)Qeփ-L>GN>W{qpFr V{V= pڵs䄣LҤ%lH8F0SHrf&!,)~N6> ܱ9D ͛<(nzfct|:3WѶ]5 q`:>߷\\c_#FAUk\:m}d>H!랶6piXH \ 6xqX>$:^ɋMo;coJV8^?9ޚD{o:Zytl]JE0R.^Ag`86'`Ayl9/ζ"u:%]sT:; ‑IO{lM_^B6hKI9А LSYAǦb2̪/mr8l PdXE aC,k>;lm*T'&5L0w{xeO,ȑNްO99p]Z3Ș˓B\q$NUxiwemQ֧dr8E- B[T)&3}ș7xM`u|sC/ں!W9ѣ. 9ux=._#r{{zfxj6VR[yO$ٓ6yvoG$}%Z1Uk6eBʡqKmFjKJu+U .{$lMIkED4 z|I,'AbJmOe Su2``F؛&(FG,{5x!_".ͣ_Z,b#ū`~Lߦң bF]f&gE5GlV^.\ߩF#SMdT+زBN[uy\'>#8 b>\nB44$8%mZL(<P?(I%9v*ýo=iL(r&=]*2r[nš$XV"٨whyBH̊mƹ`$NzO`Ԝ(b֔Vv粯\UV777KE5TȮNDz:;_8d"I1* .eF zB-Zg9em^  igle/mŮ 4g<4^sBsgw.,NQ}D\e#]\~7=yh>NEN (yԟԣ#uFc7#a5 @b./{kMEU2i"04{BC|8e M|In Ө]'$PJ wCYkNט=ƙ;qj(`oO`8F`8ŀ6ZrYφpAa6bs4Rm U]adnc)x1I`*rߥp rr.jS4e9Hq@aqʒi찥 aiΨ[IIȺ;0gc{?Ċ6&swZ2J<~n5rLF߭=r3KWO=a@UͲ!)=I uiѰ9-$|hוU>#bX3zɧ916J}xloD]^}DzcBhpr e\+] [C?N~omz!Lcr,бK/JG":/^D  yc݀Gg,.6z.\-uu_ Yle)1)58RJۗ9&y b$2YO 8l6 6P8m£f^C9Sa+J]"^k9dsM~'G0Q>eG]1/n@28;hw=^¹ '.uƩIhH@"V #좣d%ֳQY= {NK 4۲)*v oMyzq'Pʴz̳C,&09$q2UmL,\T]1K¡;ԥ@/O_@2n@&֙GDu֟3?UKK{9\א[n{0yM-}w$Xkڲs*a' ڕ N!k~Yj/,?ˁ^TJ ODLylxoy;rvAؗ{&lRv:xL̲ۻZ%q?#@5GIu0=c%j*apa;ApEFlR$-5y8T"!i\#ֈ۴nHOBynO·J洗II@]tnE5PLԛtJvΎNo}aA뚃v%Upϧ"U0S:=@ 5dNE/yXIvH #)DzZ5v Gtt[4pPi"(,n H.k׵d8BgP W\xF/q7w3&U}Y"?RG+Ǔ2H]jYm|1lK|Z)".^PF]XM]nY؛\e}zb!.F8Ht}jDI>~4`($ U!Of67Hrq"3֯_CPZ.ٗq0>$uv#F?QMsСcVĔ]gvMUTS!ng`Do^2te5[c6͙JPv徦Oa`@NPl X틪 ǩqbC `(5H)u۸0!LNȍϹr|+MΈD7u#yVu݇+ilԥHUm,1˵sl&ea\= dA_ʀzZQB2ZjA?G J.-42VJ1YcU!dP+ag8&ZOf#( x2_!oƉL]NNs w^fشMd4o8q&3kp`KβHޖ &znlKŊ_]2 DҤsib}b%G5@ <&G~ nPV̅u ,oa1~I|ORa6I0z,.=&uKLnc%> H>.d~)7k֎-W^e@F _Z{W~QkAWԯgo"ͷl߳ޛ@.7^fG o[<$i՛tcm".G .쩕[Ɲ!ϾF >CV-Ay" fu##60l?s8W]~BT%o9V'˼St S;)(d88 PV R.iK[ /1e_Yh~Üچ-RH}^;}dS?$؟jX Ay͜a Ӻw>.44컥I04=ve>'75}3(z°+}"',L…mZ_Jj ~]Vcg/8ݕ1\"RvĖ"8}?c+y e~"+ xg'ùz$OL%T&4"n i$ * 3YW z6r;nTʥ[XfJe:CzиV.~FHiU%f;!*ZCnJ5Gf,׽n槻P CxpZcN|æ߸S&=tXm9Kpќ.aY*Yqb"cv,&FE:wdiY{H6t*LkmyF3Q‚k($h S]Q[:esxC 9O%DkΏZ&-At7Ӛ;e󨸶"&B(_ 콙_7z覠;xw:!kmY52Bj@2'b{r6,=UUO3%U ) Oev~U_0v Owy(= J*J 8{הʎt;P}x/RjF/-CQ>|s 1哳Y j="ruzHBfVꍹe冢@3KcP$o‚׵8,#iH&ҺN|uAUAxRFY,A6}>'0)5cm\9$d;@bo2ӀDM/ `,k餩… AޠN!"f0G$*3WZ&Ok96mS\(vQ`>B"^PXwd"sGtfՕtV/yEeeD_J]68Y| O0N{< gbKHo a:!#\[Cs9?wphve q>c ,99֩kKK!~Nߚ`Zd1c 3?uPu V< S wl̸sFH.Œesxt0QYE] uYmJ^2NjXR@ͯV$}4m]TC ͘n-? -rA.k%],>g?;+{4KehE?R1 )}{~8ػ0IZNpT^|sty$)ǚ\2LJ2TϮYnq<0 jS'|I2oϵx/Zy 9ˆ 0 WO'/cDz~ȓLFu [Xƺ!uWӥ_c\7L, +Jr\օNu$@D,3NZzq]uc0fC$L̟GK7 ~7^%=\ 2Hx 7??ޙoJ9n16jgU9%J~Y)ǟc*,`3ڗDK*NE9ȝz)Ȇ27bo#f-ÚD9+<|Gjъ ^987Cl3p#*63ψ>%@KN6[8"1Rv_sl5Gco\v ]fz u]d5pR9WUFO\b\t^4BڊI&مA[bvHhRcNbrV3Fn~o8Bd;vH[Ndqwց!|V=o8'DauE %"^O>\1,-Bm)C>K΀u4?Nm7@(>or~Uq:&~40eՆۀu;3ph=a&Ye".fV𖛏Y7Өjte@i9`p=bI lfeZVZ*Z /1wYGKrU,{*Fix̨Iqi_ 'i4vDʌ~[L}I}3 Ti.4H]3穑"[Z 6K[ueQ?mVV_#3P69pYX I pLCoVefVM!0|"8 9HοhwޠbQ ΥEjep{3:h`z߇n@Ӈeц8khu%^'( 7 'Z iקXDI!'K 5ȍ[RP5+j$_(=c.!wͺ/R+Ӟ8@8xTPZSv %zky!mu|R$[ckC01m~ˠw:e?:dG3&&k>'={;Cc0@?/6W/9Gˉe7ZCu Z6 io(O;$A {\Hb _ QMQcL ,^%_'ZwVeVܦj g 3ICzjYDn~qRh0XLJ~݊U畺¥\ȰV˗iնr`9M;I;\ATmzlcoyΊ`C^>?] r-; uFYRp̞؀Q1t "?->[ڝ_И=u_Wxc^qj gMTN(!l ]dx~вGYuN)lFY 2l? @ fnKiQƱ211NS˿~QH@u:c@ճv"&r6m/ )hRǩndr)>\aI͕b>8E|1Z N?[*cv[$kc2|}t7PS5AJ><Kb x"~(eYqc6RAVʆLy˭|j[3 EZ*ZZ7YśR5CY }Z;b,(w ga߹&ɇ4G:i*G*Y΢EH+p@݄PuW5x*@ ǻv(t@j׍<^? ?}h5tMi^Ѡq^i*z*!m]I[kNAM}l3ie&B|]saG>grYP5uHQkB%uvZO..uBcǻ- Mu\:^_"L~a=m\qWк}kڬ 2ӰO*D"CYU7Nj_?] Lzg00` y_|7Ϯbw钚Sry}Huuq(_3M bԸ)eHDL|-.`y6+F"kH'SѯDU^svVGѵ1cA  Ru ؼ!&i1 3,s|.a8Jz@ #/UِVn %o5?)CF!$vWtm>{h;e''r6/L߄v:诙Ȥ`Nu[Ḱ^"U,4,S%:iz[ ~Bԍ~:(|/xV>W͏81>ClDl;P[,u3.9 .kݸ|n `kߠ?dmJ5^7qYJ$jca4XEn+ržRd2GGDzEز{Aa C\k'|%l=VQ`z/?k <6.;c<)P iZd lq1*P`8; wxczm(nPSFXrO M_ӔUmy5_gv{EQ`jg}2mC~ }Q@p#$[!t~LjG +7l:!G36|[-QGGf&e5\]8߷ap,EVA&W$ںm!-oEE$ '[sU_껠:%fN/öx pBO4dIЏ/1L_챭U.hCЄTA&fz/\v1@A;SbI26ڸoxe V9hZc"s8}r2FN_h͍t)$஗祘 ; ӡ~d6k)1YPixwę)Ex9$\xzvy#+pFQXN@O!ݡ3u.o@[#HǦH-NDeM@: 0-K7Nfzn>yuv8rs-Ow3yڙb--ضA] y6C(n^ 7$YPdI}Ed%UjyI&ͯ!qK :b8K H"# p=G״C wfMHi1 C{"yuojV2`Βe齋Ҩsoxu`Yj능0sCw\, @=+W kJ- _ e!gdw瑍ƬGS:I? X.Y[ŘY%qTrP8RzN ˴+g-Dz{TcU[ مÁ kgD 12&O^;1}xigSo<*0E| Yh]NE>h);WKmƇJ˗Eʘ hiyS;sXIӈ4VID5|@2m<{'{m]Jb9n ~-/=?ۊVb.@lgӺ\Jl^Žy?]FKVo/PeV^2kj>;hkoտ7Bdzulxr/~xKF6Ŧ=r_D&_fU]F(s꿌U狢<_cF ͜NW(5Ok\j/W޿ҎtmiuÐCLCwsؘ 9췧,cH/(/lk ?*gM8eޚฒC'4[1[sӼ|%sB9loE|s;FLK^9GQCrķkȪ=8WJ`{%(L)..aDMu6amw=$+_W+"c7k'D]r@i4+`ɯGe%}x1|kɓۥdCLXAЯij}pd$ G#TȒ  7hbFCR'8~tɫ& ÌTK݈ A8"JfWYTRN.djYA=V”g㖪7dAy%%1ٳQm23̽O15pvvnmGkx1h *Wr} qnnFNcSQ?E3nK]7R_n:v9lx;[ bqQJg(kif}[+Ź>#ϐML8VصF+0CD?[K:k4aR(Nd! wSi@O'$;-ByD "rf0V"DNnu%3 q.Wgo YZ;@/}8`Kv&˰-(̦fȗ؆8.wmOƋJPߖyVߓ_zD kL|I̹kX{f)6i4Mv+ܗGWyA4?Wqny&R߬q'RsYtIOaXhiph_2*Qs+ipTC6bePLЈsjKYFaG'F.U6} q&^_=p/Me2K*y#vݹ&"Ae 69Fm8i1!<ܶ˝1-uIZdh #i42u7%95$(0ʥ10kh قFox$?H&HQh ;PԜ<<;n!m\4KB ;BnrqabcCAA,ZЈ Ua%@N{Y6ylH4Z % *m%- J*:/$y@9G];80U~RUv]ed[`F ^ٿ`DhxL8vIYJrJCU/_2F'bl9+< ߎs3'u ɩ. 1?sO`"͙_]aNE.W&4Pܳbe5B?~O ڽB%kMh?L{yc?_K5}\1|p}G\v>?cIU1_ή&)35NOoSg'^UȌ5nz%{Kf#No+oM U\Y:PJqoЬ񛕁]z QPq,@hm!KR&Gv䔴5 +=ؽ7c~AADȒ1e%C!ո*\ֻDxɔDEU(h &)ZaUB*+S92%*' k pɵsd"l ΦKbL s&(E2Gsc ib$GŃ9,F3CXp W9_%VZ~êc- L?ڊAFcXk~)ϰ&ȏChջWvG%ϭզX`'(O0@6a䢩(2K?DCJz6&֔k ,W5RõaAHCtk3 7cuAVuj!*}l;QL.\ G#y*+_e"kIcNTAn,Y@3^|Ʈ%/.e? A 4&/ O6N&2WJg-]V& pȺ~]m / .I~iS>/DW"RJ0_83z9 ^sl﹋v_Ia 3@w$A~HbD<׊G~j h݄V~2u i)ҩIhwn[ ULXw|u}C'Ө)З#@$D7~R:1P'$pJXpp8v"#v{$E)řqEGI]WWawyzS54t*-_f-6gwXIZ_Ɇ>*i[T;>{6g/D;6Z(]̖؊fJZgQ{5ŧyP"K/W ^j~W`E0׏V[VxdX@;Ik1IEp ݈9Jrߚ$K;R+ N%!9Ndup ۖ3Yhc;./i(J"榯F$B0@hK曃Bq<a%jtdcdh7(mTĕu\Aܽi (d.΍4OaRղ6N_P:,nL/&o=q ,`(]C !~n7нy;I)${c=gguZds _zf(JΩY@g L[Hݬ,2^FD#T58P>rQRIyw=(EA\EoƹP*P ,Y}Q^̨z2zݙ&įڼ`e:Fݠ˶D}TX{\Q Ct /  !;70az!UY2b$)ښo"T u ÐγUe>7YkGgLlCRr(DKii0%:aa~5@.jPncܮ-qm *]Y-<4,FÈF{qz30Y_dQ !wiID<@/"Y:cee@Ecj!$<tS>4[G'˪~EvLf?˭[NKN*9G+.XKArX¯o#2-^ˆwL„<;V i@WB-org'̀cQV^!G6A2wuR͍)ekCt.h6xZATi 67?wH>>;Mj<~.hJGfj cʬ [ ^_|+8-mNtvLNkE^fl w9츶;5Atf:-yckJMU$q 4yI h<8tJqTUVݟ X=;Nz=k)1uNdA6@â! //*RVk}60AAܾUIsoSJpY B U/g7\4q2ރ/]*64".]=p9V$ak( :/=ہq9Aӧ":Qj meF m96א2nI>w +^*\BEvw'pD䯔k X5&3_Qf WfZlmua4vJ^.pl>ag黗]ep2X'!W6r嗭>*tƑsOĿ:71 b7ϴ^ZrLkV]d?ҷ 8Tp <{Yjɬ$I..T#\&lG6e 8h-)m| D3ZFW/R^e! BfSMSvs-Z7)S)ުJWȹplj~R xm.'Y+Ñ'a3`K /I_;\U^XP&@<8F@29cUD'.?]\VeN^۲t~3c/=2C@-M1ٞu.wQZM)ُ̓}SJ&gw׸ 7XUG,Y1Ѭ`|UOb _~w\xXphzFЕFG TVq=s'v(y?W*ݯJG6<9@NATP@>>UZv,w sEih0UZN1j>>9,])k$o!3{\0pfk33W+Ÿ:X W>KIZ'.U~]bD2P@%tL>ʨ]V쩼$W a>XM.ϩStU :sA`;rlB`'{  ^`$  B'B 6a/sVtUe@jQRPY:_JN74]7}yҝ @|@k*J_F2Wo%U>.s jsy~&01k%{-EӅޒkypVtAۊ1f#0FEߛɫS Q?ȼQw}V9b%iˍյ_c>|)l@L^Ѳ]RMhdZ3BfDޖʤ{aiF~bWWDZui+ʘGb|lSibK ,hzxKLȿB&/j-{,x~0Qs# φHOԞxWnkˍsa#5 :*'àE+eҜy\0]<N&k)Uq2?OG5[fu/Otm~͵` ]@?23xnn'}+ī1XAc,iOT1Tel**4Sp铕ГyޜS`]5s\i;Sw/mkEIg2%ESkOLc ~.şeQ!)B)>:$ɦގ_x6!UUUqf[trFs{(}E*gӏ* 9L!nugT!zͯʬ$ic09p jP ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cOQ2d#Creator: JasPer Version 1.900.1R \@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP /߅PQ(,= kVT-|f{LWuHMDe;~J =r+ o[t:1.\A%>%窰lxV `VcDE#,x|C |,gʖ$DipO91Tաޅ/I!y -p>/2fͶUc@p eܟe; 3|#߅PQ(,= kVT-|f{LWuHMDe;~J =r+ o[t:1.\A%>%窰lxV `VcDE#,x|C |,gʖ$DipO91Tաޅ/I!y -p>/2fͶUc@p eܟe; 3|#߅PQ嵙{ЋﵞCn7R$l-[ޤF |N-:LSy`PЖ@C>CӞ93kL SX: UXY; -v `T{X"%1l(zqzH`K;cHoʚ LB?y]uA4n!pE{`\Y*M%FNH)s4>f?-QxI SjN70Sb;DSjQoeoxbq֙EWZ$-KDb]SjC<7q'JGk8f9czF '2?-QxI SjN70Sb;DSjQoeoxbq֙EWZ$-KDb]SjC<7q'JGk8f9czF '2X.啒+E"Q HA6N)4@GW!!K ü:b̃$YPǠL:bfOL&JĠJ(~+Dy~ S0 bq'\\NW5"[_t8یN-|;)j=% Ù\*{jS)W My|cJ/vcC쇘bEe BHpC\NZ)ęZk5V}_Vkz$P,+"W.~xTM@&r24m -:Q򅻧yEğӭ0jd*v)Jj)w'2]1*A8V 8Ł"Q yO! ߝg~u쐜:}q8FF12e(n*Rq؋,p 2 ?/'Ҽ0\4^ɖa5* 5a=K\'f0YB€⣕\cGEIbԞIi >bŤO.ICfMXy%oxm5'JVedխl74g@OI>)k6qr kyON3r+kܳd , ȮA,0nL_2:oZ\=IѮB눺 V;JhͼĀ1T'/ ˠBXi9@:-D/ I$;tnkPϗao4"T^߄ MĆ7z*X7 c7 \*XѤb8 >V2jvMWp5jMæ]h]GYV{%9PF$RBy\r{ĕNFa% 8f%K`:5˯(22o`)jE7p=/}#gE㶴`ON3?ͩN>D @%,_4u#z) ݠ-J[E?櫅$}OaLzƗ\ẕ"{Yo,t?1t&̪-dʳOl̃A5iyQ(r-4k[||daeo:eC <떘ߑQ&DnL~=*,6#̎mS !}"LC Pur>CD`½Ul4MFixhobIb@"gܥIzԚ|ZiHԶ]ly._ǬT>1YelB<2/!HtK&G}>ۊVOV%U0(dḐ'c8VBn^MI/_p8{S}=ě~W.H[WGh,-B8ȊM8!~r͹].Ŝ} 1 .WMMTGC^ ʥB-fϦ1˙s5Zwep+YߞOà:[I\f_8G~; zm:r%ش[Gmaf)GCs%B3O.P^vY 38a7P:^3lԒ_j#JC,QFˊ=.͂Zi#DxUc4j /%џ <蟐F |Q5(d O*Ei(5'.Ꮾ\ô-hoY.}W\Ɩd)EUp&)//xA, YHiQe[nmk\sO*PuXPF$RBy\r{ĕNFa% 8f%K`:5˯(22o`)jE7p=/}#gE㶴`ON3?ͩN>D @%,_4u#z) ݠ-J[E?櫅$}OaLzƗ\ẕ"{Yo,t?1t&̪-dʳOl̃A5iyQ(r-4k[||daeo:eC <떘ߑQ&DnL~=*,6#̎mS !}"LC Pur>CD`½Ul4MFixhobIb@"gܥIzԚ|ZiHԶ]ly._ǬT>1YelB<2/!HtK&G}>ۊVOV%U0(dḐ'c8VBn^MI/_p8{S}=ě~W.H[WGh,-B8ȊM8!~r͹].Ŝ} 1 .WMMTGC^ ʥB-fϦ1˙s5Zwep+Yz'άoe0c`"= xR夸@3C.Dud 9 ?@z >IjDVATIlvY ܇"ψD^_>h(t}.A{T&=5f'!_ۙT6x~H%F`LuY d~ MsS<z0LSY {kUnr"|]G|8 Z)q[ 綵{Aij]J[9rrn;HYM'Ѱ^CB>O7 <떭K 7duğ֕ms<,1RD8s{pc C]FL”}Tqp `+U8XfmLޕv緇 =bm[m*)=+K}T UnQ;%ⰬXgϢHO K:}f*h |OR_cte}ZqV!\WsTGQym$3\s&\tׯidEO┓L5ABjpV)w7NjDzɋ덬 Z{ _r/cy^1{~*V$ܨgEmK<VKC&fT^ $ܢ9-/ U5I]]ga:o!Mşn_Fأ3%G#A%SR$x2(|ȍUupmJ3 HTolN>7Uo+%\6\1 }ښ~K7>|p&N1t]˷t;bZp.ĮΥN )hXH}"X r>cf9I񘼢?IЁ =:󏬸b0uTm؛,I`EPFmB;o8,'Q^8'e 23$MW]=6tCr߳J;˦ 駚\\et(]F+y#6O9]Z`cBI<9DX}8 ܘ R[ۙ:9(>W7abߟB+hʲ 4M*) !2[)-_:}j0ôD<6By% X62^ mЍiݽ\EƋqi 1pWuP߬tc~URCV?g(HQV;lUb$Ap{/Ʃ B: ߋ)$$Mg5p:q j1U&gdhfUcX0v* G#:Dud_NY[-(KQ۝d|Qo\:OQ+x)m>GHA8Pbl`b > ̂O<iV!u.fy ;#6ƥ:f\;K`Aa"6! [_q(=;ףrpX$}6(#t괘N?mo7Cď$ah<R/mQIxbkYj {ac*K1e1W$7Uk yޫ5 x8YT: pQ֌U@GYgo%H 薗zۤ^i lg v5ftrVs{kEQ;R^.}Շu}s-#Fp 56Q"+.>㓓> F^Ⱥ1n0n^CՑ^P+ZsAYfxAQЍcv8=rUj+[KJR nH3i_{O_5&6V8 v!ɘz 1oqFDŽH+.v((U8#-69SٿoXТUO"w4J;E_YUĦ<0E 馤?bAk v8dQFX{v֔Te͢\ =2$UjiZy!EhJLujSig*դ'l簤iHHڻgBS?dTMb?'9nMRj 5|lTSJ؀ *(:ZEeFHʨMh75]7oKqOoS.(T~+MT>5TTXef'QwpoyoDKaEy*/'=ʠH(vHg IٌDqmݜk?HB}.6Ӟ_-f_.w[A$tʙ}97 ٫HPfX;D?4m2Nn:1@NIY- j(ϑ$=rI]}KE]#kU?Б.N@*pyH+^r"c.Fb_W/}; <1%"*&ptԋ9WߟL=U#%݂]kp%x{9ri u7 AƢy7K?W/p5&r $eL ;&Icv}#[!'=Ka/n;CYgMzl㜘j[ڰ&Cʌ1;sجՏq2樶Q!1?TX缂*Ylޫ"C4P\|(uYQ; >Uyx(oBo@T"OHeO+TT30{guA[ Ν8lqPtZ,o)p\Ϩ*R7:d-rC5A=Ѵˏ  h#he pCD}G)n=2~"51N,`< 2j0,1qy' M({v +iFV-05ݠ1 b,Kש0]]xm{=P Nf&*Y+< |[=%Ne4 w`,RB>(tc)``d},mPD|&+P ǡ}c u</9na)Ga s\ޯ_N寺\Dfϸ:gt|' 4=oqtOYڻ@[9y5zKnVЦS(Dok`@[)WVbHRp6Z@'@.#/VA+ܝ#X):TdCmeDrQ`(ւoȾTp两ldd9K7I9JL#c GG̍ 6Oi+^Ta\R'Z K wϖpkQmt8/Q.S+HKY4##/^.i#pCmeӕb)3A.H&Yz^oUHBWѾAU*×$6*52В8j /3=NQ1Nrlﱷ})wvEqVHت^kFRWU 1 \Zkyϣ՞2u*[W$>nBj7 j\$?~f<>-`Jt /I w/) VVnE rLꥌL(q9MX;O6#~^*»OKk!3>6lꒁdЪoӏ-|Ǖ$4{("H!q51'襑yȁz4nCHMBVP=ΣT z*=KEdُM$TxhH=_5ye,p_[zky*z˶G[} $A|[(l||.@P=W`"m1 iRTϨJ+lq8 fiC@ΈW $q̋w SHj)ycen-IYf(OA ښ!)Z bC*H~an"^SOUBS޼Ju 18-S \S& ABJn50aX:m U&U8̊ohAmw+vON-!/UBQZT24`I D]$% Ei҂W"$ _C৸ܔ 0 ] =DirD0A8Ծ8Qe9`ƴc? CuɲAJKْi+%kn1v,w%_[U \<:? 1w3f}ZM *iΘVa"/ ldv1jVIS\ W({*7 h %JTj. E㷲-/=d` x$SRK+7vKbtXiʏ\$3Qͪ*RPug Gmg'^rE* mѹ]E㓞[`8P,cWŞ^d:5uXlH"FQ#ABS,ݾUy mK7ٽhj*p+'0J^{imm_cYGԳh#k]dBZĴITԽIPk~ 8劊\^Q:Erb AX5{Z>zg ]RW({M ١>jG"I \:<{h̊1r(lX u aBXTp΍Ú̮e';QFx,X)68;2 tC5?1t'TvwwPle Ú`Qg(u*Nx=d!ꃇ3yՋPv- a p(Z#3kO=_Q q~dgzgV|f>cxPtx!s׍n=X jBma tiq )EMCy}?& *fTz7U/l4v%ѹ3ƱLHǺ7 -mT$P@ \DPx/ɖ4j`^s3fw<Ò*Tw{FdN!Odʢij&/ϋ_懿m\̲m#Y+?b/(934v7|uEZ0y1*荷p/˹Vz%b y>Ls- #Edܕ ~a;4>{V^Õ]Gsr.tې%K4dXm@գ?:nTOz$b!6,DHno$U…DEfM~maTRhP4^NF Ո+KNytq\ .hHxwi'HaJ2lsi~z3JIKW~sJۭUc᪑|qeFΛaD]iߒReK.Igے7u"˅8R,[uNn驌xB\ i=ټ{G+ܥm#Bh岬09Ma1!Cl̉1iB.uBߟL=U#%݂]kp%x{9ri u7 AƢy7K?W/p5&r $eL ;&Icv}#[!'=Ka/n;CYgMzl㜘j[ڰ&Cʌ1;sجՏq2樶Q!1?TX缂*Ylޫ"C4P\|(uYQ; >Uyx(oBo@T"OHeO+TT30{guA[ Ν8lqPtZ,o)p\Ϩ*R7:d-rC5A=Ѵˏ  h#he pCD}G)n=2~"51N,`< 2j0,1qy' M({v +iFV-05ݠ1 b,Kש0]]xm{=P Nf&*Y+< |[=%Ne4 w`,RB>(tc)``d},mPD|&+P ǡ}c u</9na)Ga s\ޯ_N寺\Dfϸ:gt|' 4=oqtOYڻ@[9y5zKnVЦS(Dok`@[)WVbHRp6Z@'@.#/VA+ܝ#X):TdCmeDrQ`(ւoȾTp两ldd9K7I9JL#c GG̍ 6Oi+^Ta\R'Z K wϖpkQmt8/Q.S+HKY4##/^.i#pCmeӕb)3A.H&Yz^oUHBWѾAU*×$6*52В8j /3=NQ1Nrlﱷ})wvEqVHت^kFRWU 1 \Zkyϣ՞2u*[W$>nBj7 j\$?~f<>-`Jt /I w/) VVnE rLꥌL(q9MX;O6#~^*»OKk!3>6lꒁdЪoӏ-|Ǖ$4{("H!q51'襑yȁz4nCHMBVP=ΣT z*=KEdُM$TxhH=_5ye,p_[zky*z˶G[} $A|[(l||.@P=W`"m1 iRTϨJ+lq8 fiC@ΈW $q̋w SHj)ycen-IYf(OA ښ!)Z bC*H~an"^SOUBS޼Ju 18-S \S& ABJn50aX:m U&U8̊ohAmw+vON-!/UBQZT24`I D]$% Ei҂W"$ _C৸ܔ 0 ] =DirD0A8Ծ8Qe9`ƴc? CuɲAJKْi+%kn1v,w%_[U \<:? 1w3f}ZM *iΘVa"/ ldv1jVIS\ W({*7 h %JTj. E㷲-/=d` x$SRK+7vKbtXiʏ\$3Qͪ*RPug Gmg'^rE* mѹ]E㓞[`8P,cWŞ^d:5uXlH"FQ#ABS,ݾUy mK7ٽhj*p+'0J^{imm_cYGԳh#k]dBZĴITԽIPk~ 8劊\^Q:Erb AX5{Z>zg ]RW({M ١>jG"I \:<{h̊1r(lX u aBXTp΍Ú̮e';QFx,X)68;2 tC5?1t'TvwwPle Ú`Qg(u*Nx=d!ꃇ3yՋPv- a p(Z#3kO=_Q q~dgzgV|f>cxPtx!s׍n=X jBma tiq )EMCy}?& *fTz7U/l4v%ѹ3ƱLHǺ7 -mT$P@ \DPx/ɖ4j`^s3fw<Ò*Tw{FdN!Odʢij&/ϋ_懿m\̲m#Y+?b/(934v7|uEZ0y1*荷p/˹Vz%b y>Ls- #Edܕ ~a;4>{V^Õ]Gsr.tې%K4dXm@գ?:nTOz$b!6,DHno$U…DEfM~maTRhP4^NF Ո+KNytq\ .hHxwi'HaJ2lsi~z3JIKW~sJۭUc᪑|qeFΛaD]iߒReK.Igے7u"˅8R,[uNn驌xB\ i=ټ{G+ܥm#Bh岬09Ma1!Cl̉1iB.uB~>SH=Y (Uu|Kʷސ&!6~բX!% ҶSYQC}N"G ],o쏀);o` / ?G)"_(O/8YUH?n:2FX"H*hX@\W-I]UVof&*j,D$(GjmmTCٲ[=!UFnv^FgF01u 63Ӄ ;.q e'kz}JnU*'g1EfSXj;j'@=G_\ L&+V [Ny3`_42o4G6T?޶L3$OMDZmhC^-:k53nZ> 8,QDiӅ-4.oTn~LTv02M|@!{-`c[ _`^)-ŭ48ꕠ/!X;[;r{)`+)Yb}TpX.s8垨4Q( [K)d}2*A+>c[/pBmM2)t$jGlF(3M6tɂQe6^m4]8QBMNf,1 5~w5EԥǓ,0^jxzNlN^v6`YMk.lɔo{(Y8o)Q9Q+s{`D)@t|A&Y1NB4NDYZu`."A'T*X&H1.;GR~ցĮ3y;Xe,7q.^]gN*Vr4Gg<eDlmI:1'2CN>͟|?Ɔ5d왇a5[CJ7 sQ)"Ajnǩ<\+Yɚ;*.oˮG*3 ,_6%}䤛}R)$]coAr[Ԓ sWdo)_[͙ mҍ|+.Y1Luey׍|EtXߗ[BRbìUۈcLoCk/hmFю޳RubN#Y5UAC%GBP'n<?ޓu=RLv64.S>j^=Ԛ"FQ]Ʈ@w{-_m`cO\+MerޯJP^?^Iְ싞0ndu Ƕ&ZZF:EQ!CMCXp\]k0RA!hS6͆sR͜*gg|{Kʥzt!t/uL]`\G&PҦT1,Y줊ϿLTm\P}xc/ءS'z:!bSF!.'_0i Q1hiwh -` JIa7X֙!AyZs?6tp"U) AoS7sMT8 '#eIjy :xUP4YōTZPCb2iRΒ/H`)ſVD1\.vvI#vVOޕѴS½Ne5It 3ȁ"Ph9U$x L;$BWN{jŭOmT+mҨW9A.(Q} tx5)j|K6+vT( Y$凇I ;-@=H,bp*)/k/ 0[݂KXnxGv>L/)F=e1m99FN{= Jus"^,340J~Zxn$mp:-pw~aQd F^^dYMO$Cv42dž!ӡ#Ǭ"y2 7Cy~$ _%$bS^EcTyr(rR* o>/Nx1+?K.Pg"/Oi?7 5?eOWTlfB 1!H6ȫܕyCzN9#l\pQ)*=B4n&_\@D?Vߑu|ҟ2#NrcjS8{ܶp5 @qF|nYϤIhAvouW^g.0Y_ 8S<P:ZS2@2@, ҅\dw%J:v).ûU^wl*4ae+uBC'j~؎A{HmxvK18` eCgS㦎x0 vdFNR2*a:< ^VDzQ7;C2%5 >L;Ual[I.ar3Af-,lҸ!f"|, vg2 x~k mfE-eG}tȉU,.Dm&vϢzj $y$y]ܨiJaZ$lk0!\Grnbװcݗj(ڶB/]WQ~b *Q79nė SgvDz=1OI2~H=#(] ڃ0~푒B>O۰4S.E^3g=h\{S)CxgH~4I[>xg+b iY=aԳ'D\gJ^bv7@:34A.ʐ=S>t.Œ\AO+³FnlO47/Tj# ,?|U[':=|[&<31M^N@W+2BkVwcDa`U|3Lg%P*Kʋ:dP:RE;X>aI>}#S 2|!!uH=;XW+,5X5E @Cneo6qVŸK6o9xyGܢѺXr8ρ^2 f:q.Gg݁A<&O\ iNP9Bj\X)j#ER?<:qn\B{?UH˧N]&"`$NŬ'ғiSJ :m1,owMdM=\'rDT(AWC[ZZAșiN>Qvߦ <ўP}z=G9A R=kC#F#l,* Shӹ2;`|K%]XxrnDrvIPiݲ6XgZVv{s+%qkDPzn;vo#T?FZQ.aijOtLmrPQc ?xBɻ=MIyЀ-l4K,mZ+]2S=E52)1mLVLNk,Z*rPhjG2;*^bqÎn%2Vt J_=O0T<ҊSO"޶4BN)+p1P~i ,GHVjhC!7X@6zK:+;Jz+8?ȗ{H#ա`\lZ ρ9?\vtqNdvl6'8Ht8q!NUɞcQ :L4̗J4Cpu#=\"ߙ8ÿ0 +IJrU\0Odqm+_\-G, Zwxhq`)Cs<ץĞAes֊_-O)NcYMt:Z.AV`_Ujbc7\=31q@NJ@hk~COg0ЫX@E_3M*^=}(F3K\9yo:F D9ʻ/DD.K9Hqx@ȠI PVYyGp &2J:ƝܾKVJ;qq!cazbm*GphIA m [5ID OeEI.=ZO׳""&juA'}KeSN$F1@b:o]D.rs75k %jom .gԘi&4ؕGimIsUbQqDK}mcցsWRfIѕh:dG^"p=^] iBn%˂qm k iKSԱ{i/Ţ3T[ 4$OR̽K!?U(*isԃqbalD~τ|竿Z:+Hjc} E%Gyvp2`k bXhygo`gy^>GfW}:Ҭ < ?|+8L4ikSr`mH(elBdXIՈfQa6Ӓ9#FkVX(퍖eE`Dz#_3DcjqJ@fBWP;OAXHOMio\~816%]C1xl ~i.ޕ& f)I`,RS~QאiT 6Z$)MeUoL 靈-+5t6H)UqiRiDg6[bs:fUsksPY!׼۫B;`~dSϐ#c{8ъQ@3K{͓Tq@|/B@?%DD6 4HDtQ#"1]x{`N}h}Sюzz);C39RI":++u3WzQYQ .־go,G@PH >k3jۄ{;]NiI_E.^X肛c}( |sMhTXg6SAYSPU^!s˗JI55̣(HXL{я|tB8?T:,IL c8m6,90c*xcd@2 iؘdXL듽3sAo FQ΢ҧJoJ_bE vDaG.Y ԫ9,Rtr0.{Ym^UF=J'ܑ<_. 0)( Ýzql2厄ϑ#ALA --BYʧaˑ:ž^ѨH!B\֓u ldl!E)i(x mC(!! @\l(XeǀFQ3<0d'D-Ϛ̽ =7*f"Gژ'`8@ g2|ӭ=؊iOn٭Yfؐ-gNFG~Ga[ bxB#pfd@(.`(3) ~ YZҡ nO߷_I W|txAKZѐ4Zk J}& .`fY/Ϗ4m@1]r5VՔ^N3[e"uI\{kY,1Iљ+HH{ Q@yOHAv?G19ᴞìH'ϨYL!,8zv-t1lѼ4ͬD?Zțp,}aeac_F!؃j-&(WEv],'BJll?{߬HEfh曀?*8{(LϜ^&ij?XZ~Ã!^l|;UYG{*>ECFӊڂn=0ݪ\ i6+zH6+#Gx?Q آ,Z3}؅]7t2 Qkbv&6j7elZi_F`t=D8\1S{G{\B$38je4(!dE/;a sW^ J\@Xv~h.-ҏ1a%a,INlRdBvIw0ƙĞ)rB]QR(h4#OȐ&fZ da9lg|1nȓ읓>nRYrLr8"=h@ ZA~v); *C1GU^ ݟ%}rTiJ/ĴJېHrxvd 2M>/ !e,罎+9#`'!@ڻfwlux+iLjk+9OۭHw]4zbe u=I[ OJ7]=p-+SnJ"Rt;m'!Ԕc$gGl!Ug=&q,N򂸫r'xa]"#U:v*t5 ӮnsR!]&dn, =.3A-o52DLV=,YyeUFZe`c:rFחg@#/2Չ |bVg~Ht3{JŐ!^Z\fߏK@ovk694RSp!,rb}92Okqƀ9׈\X; cKrǽVm0<6xPmQџץ+=1i'w;}E:0^?@wzUFJ.җ$:ӻ$5bU2‰C!mɱ8ߔX#GGJLޣ)Y{u+.iKoa6~DG6m.%b~%l Zrxle BUO; i@&GɠҔk ~$%c¡ˆ}åʕ)SkYi KZt_9CGQg`Q=QqCy6Si()a `X'rJȞ^KA#% 2g\@.fk> >KwxZ䫩9^jK{(,XaUlˏsK8fYq a.-Vo1b6$+!n-p'k( UށbUӫi&(;HM9.'1V౸Zk [\JP&c3r <,HƲxb0;ih73p4gJi<喨zlU+e)f@\HA"h)5Nvϧ&f .y8p'!Y5?lRL#^Gn_dXl!“IJCZub#`+8(n}&i49j:,hP%%=WeX ={j^_{p[l;2!c7ʂndP,e Kq߯3r7$XJ0| >ZR }{ЀK`tJޛH(kG'zҷϼ{{ 2C5{9' 9Hr&=6)wrKgyJ@lp%[_ňkv +7OL\a#>he }VEuWM A6Z,t;<;~V9# Nh61zy+Bo)D$0Y Lj(~XRuW'rtZp.k+^ba]/ht8,AݪNme ơnOq(ʒX(,vPM XɢuJ28 }RvaE~v\M̯*=8 |uhٕ@Ua:Vn/>`m6%'AK[wGV?I|L6TDq_^uF[Gz?oڪݳ(7N]2.7i/nodI8:ĉsB^H =oU-ll!n{_Ѩyjh-QΉ&%dwx-d( c_po7+m(W|+O 5ulIqM|(5]E2ѱ[lnM|N)뿮/slEh+* IU ?!DV M~qQ&vٍFC ɍ[v cb<51`X[+?+br'MN?:Cɗ/]H뷮 z?;Z!ҙQG "Zwm aJKT/dnqS0| ^wk*Ό;,u[xʥ_O3ӷYYS'`LS!' Z1ڦ.ULM^9aEj Qv=M}|{od* O֋cFo|Mmbi(`nRj鬅 pݞ`4v2CH\>޼}]GcptxslUCp,҈*bòN@0^&gDoRϩ1Ab{`omZY$X}֝14]?ȑjM"yP$C_F0 c[5.~t DҰ18(rpD=<>M-^~?=?;MFKwI*@Jێx8LG xɛTeitvM@#yS$256#PfY'NM4+&Huw]Ɠ1sw|C6ahY\"EF=e߀kN'f2X\#\@3+$P _DFOt,ޮ({ϕLE̎Z9b rfpeBm!((ce٩̑O\I궫K^N[ZGLOȈ\JE=~%fa>6[ io!KI0PO:mKLApuu(TjZH|ecOC9ZbsOXbyB2wI&k®x'(.ۉ_0D5"#ט&21!~G2m]4q Xw%6}~q 0w9I_h=xlϲi38pZ^K_n&!Wo"YSBD'[&CO,go[N69mfy+}RwV _J5:x"%!tt@(t*StqhfկK S\> |} dW .ҵDhV73,mxh֕ *lR-OUvUAdiY%y4YhСO{ ζ"1<3,~;N)+9P W+{_KO:P 'uTX8@!,O&',ru~9aaIT3O%@Fy@$.l5RNk2)< O֥pKR!hóMt/گzm^Y QwZQ&+"6w)E@ ?{s7JLAMG5[cE2/S 7JӍP?"U#ɏk+=3$*8a{c0yOϯW:HuYY>0[)QG#FX*+S^d]An3‚GkMl#gb-fϾ!U9ˋ3cΡ:Iyۤ=ϤA̽ofyLJ] ~!c .SQ)`_pqr_ES ]Fk"ʝM].2uJ!˾FxY[X> lI)@*CŸsЊ|G*HP`S8i?aWY[D hDC4Q뗡JQ{V^C=}~G.m@|o_h0jnM]RC\\+O'X,Ic3 G ׶*9 ),v SľGP%tbuڌtq $˻doKxbiO-h~=wKbYi:0`@GL J'f~M|85g>R}XT7a8t8!HuBHHJU6vY`G"GO.X:Jw l`׀!V ̑a@m|$;SԂ]|'YSЃ :x .f>h{cVzY 4u%r !9 ]6E j3z]Yh-:~Nxlh1pւQ~Ax]QO1](Wmc{s鷾ZsͯŠvz:Hm0-i䢵.$)NE'h-V@ؤ6qco3J rT6fc3"!ƅKXjJ]n,r}N,I;gRq&Vtcvh%xu*sY,~L-E%}f*OtI"'2x+V7k'>=t2/Cոgl3"#t5{$p>}HG:Ў4)%T`qC޸ED&`fNRT2w[͇p@`Md-`n&E{):h2pdͱӔ^=\>1li& /Nyj(D@N1ȮѼRD ų,uA{%6AWz1Ѯ4=@mc NzL;$a}{J6z2ʗSMT\Z3Vԟ,8l'}|]CGj>.*: )pKLkkF j f1uS̽R"e$L٦ϔMvQoIGѣlI!>M_9H5ʙ20Ko l;KQO >ߓ^FX#ڐؚZmYәͰk8 }G:LF|^Q~l,)>uK 4+yy(Tuϥpus64wq>u2e8bWV~]ZWP0-~YadB/Y4m @!"'TlCݢKImKƇT|_QQgu~wL\x8;=} :l7/ %[MnuL_OhH}_=kwsP!S]rW0.$Y.'-br;**^Azr8v#7G$RF#wA >Mxy?%ǛpJ(?RZU 1^ %H}md4Wucb޲6e&\5z灡`FTvdu{#iԮM|F&XՁ]b8rh@epS-t/: H'@`o=s @ZMVtkf.a;2t3㦉u{Ui*8Wp}:(ẼQS*:BO zbϊ[dj1χcr Iݣz`clbu>e>o;)D#"&ZPFHq{- =]P x8*RCI5NN7[((a k<^SJ^;UըBoT{2sJNZ,l3"I iK?,mR;i$FBblx)Բ܍dcXrm-)w!,$Phk\-sG z* @ @> 7L~8[i3) ys) t|3_I!i\44U6_n[w'W";HM֩HbGX*so7WdNgZOr ]z4|EzЩ0I tܣXb 9Nc%g<~KW#6 ‹0$ WG|jeqgFITXQ]Vyotg0tcGX_h-Uh9ӼX_a䇵ogIz!QKlFXoMAyFx_}-jð0xֵ=у(X;uf?_XDDt$ιj ͞ l% F塽㋂=GVt\1\2Pq{G1]h~/[(͡"WS[򙅢ԮL[QR_at`B$T>I{0f*/+ȟ{6@(?W$[s>%rG/'dJ侺 qdTSrS |џץ+=1i'w;}E:0^?@wzUFJ.җ$:ӻ$5bU2‰C!mɱ8ߔX#GGJLޣ)Y{u+.iKoa6~DG6m.%b~%l Zrxle BUO; i@&GɠҔk ~$%c¡ˆ}åʕ)SkYi KZt_9CGQg`Q=QqCy6Si()a `X'rJȞ^KA#% 2g\@.fk> >KwxZ䫩9^jK{(,XaUlˏsK8fYq a.-Vo1b6$+!n-p'k( UށbUӫi&(;HM9.'1V౸Zk [\JP&c3r <,HƲxb0;ih73p4gJi<喨zlU+e)f@\HA"h)5Nvϧ&f .y8p'!Y5?lRL#^Gn_dXl!“IJCZub#`+8(n}&i49j:,hP%%=WeX ={j^_{p[l;2!c7ʂndP,e Kq߯3r7$XJ0| >ZR }{ЀK`tJޛH(kG'zҷϼ{{ 2C5{9' 9Hr&=6)wrKgyJ@lp%[_ňkv +7OL\a#>he }VEuWM A6Z,t;<;~V9# Nh61zy+Bo)D$0Y Lj(~XRuW'rtZp.k+^ba]/ht8,AݪNme ơnOq(ʒX(,vPM XɢuJ28 }RvaE~v\M̯*=8 |uhٕ@Ua:Vn/>`m6%'AK[wGV?I|L6TDq_^uF[Gz?oڪݳ(7N]2.7i/nodI8:ĉsB^H =oU-ll!n{_Ѩyjh-QΉ&%dwx-d( c_po7+m(W|+O 5ulIqM|(5]E2ѱ[lnM|N)뿮/slEh+* IU ?!DV M~qQ&vٍFC ɍ[v cb<51`X[+?+br'MN?:Cɗ/]H뷮 z?;Z!ҙQG "Zwm aJKT/dnqS0| ^wk*Ό;,u[xʥ_O3ӷYYS'`LS!' Z1ڦ.ULM^9aEj Qv=M}|{od* O֋cFo|Mmbi(`nRj鬅 pݞ`4v2CH\>޼}]GcptxslUCp,҈*bòN@0^&gDoRϩ1Ab{`omZY$X}֝14]?ȑjM"yP$C_F0 c[5.~t DҰ18(rpD=<>M-^~?=?;MFKwI*@Jێx8LG xɛTeitvM@#yS$256#PfY'NM4+&Huw]Ɠ1sw|C6ahY\"EF=e߀kN'f2X\#\@3+$P _DFOt,ޮ({ϕLE̎Z9b rfpeBm!((ce٩̑O\I궫K^N[ZGLOȈ\JE=~%fa>6[ io!KI0PO:mKLApuu(TjZH|ecOC9ZbsOXbyB2wI&k®x'(.ۉ_0D5"#ט&21!~G2m]4q Xw%6}~q 0w9I_h=xlϲi38pZ^K_n&!Wo"YSBD'[&CO,go[N69mfy+}RwV _J5:x"%!tt@(t*StqhfկK S\> |} dW .ҵDhV73,mxh֕ *lR-OUvUAdiY%y4YhСO{ ζ"1<3,~;N)+9P W+{_KO:P 'uTX8@!,O&',ru~9aaIT3O%@Fy@$.l5RNk2)< O֥pKR!hóMt/گzm^Y QwZQ&+"6w)E@ ?{s7JLAMG5[cE2/S 7JӍP?"U#ɏk+=3$*8a{c0yOϯW:HuYY>0[)QG#FX*+S^d]An3‚GkMl#gb-fϾ!U9ˋ3cΡ:Iyۤ=ϤA̽ofyLJ] ~!c .SQ)`_pqr_ES ]Fk"ʝM].2uJ!˾FxY[X> lI)@*CŸsЊ|G*HP`S8i?aWY[D hDC4Q뗡JQ{V^C=}~G.m@|o_h0jnM]RC\\+O'X,Ic3 G ׶*9 ),v SľGP%tbuڌtq $˻doKxbiO-h~=wKbYi:0`@GL J'f~M|85g>R}XT7a8t8!HuBHHJU6vY`G"GO.X:Jw l`׀!V ̑a@m|$;SԂ]|'YSЃ :x .f>h{cVzY 4u%r !9 ]6E j3z]Yh-:~Nxlh1pւQ~Ax]QO1](Wmc{s鷾ZsͯŠvz:Hm0-i䢵.$)NE'h-V@ؤ6qco3J rT6fc3"!ƅKXjJ]n,r}N,I;gRq&Vtcvh%xu*sY,~L-E%}f*OtI"'2x+V7k'>=t2/Cոgl3"#t5{$p>}HG:Ў4)%T`qC޸ED&`fNRT2w[͇p@`Md-`n&E{):h2pdͱӔ^=\>1li& /Nyj(D@N1ȮѼRD ų,uA{%6AWz1Ѯ4=@mc NzL;$a}{J6z2ʗSMT\Z3Vԟ,8l'}|]CGj>.*: )pKLkkF j f1uS̽R"e$L٦ϔMvQoIGѣlI!>M_9H5ʙ20Ko l;KQO >ߓ^FX#ڐؚZmYәͰk8 }G:LF|^Q~l,)>uK 4+yy(Tuϥpus64wq>u2e8bWV~]ZWP0-~YadB/Y4m @!"'TlCݢKImKƇT|_QQgu~wL\x8;=} :l7/ %[MnuL_OhH}_=kwsP!S]rW0.$Y.'-br;**^Azr8v#7G$RF#wA >Mxy?%ǛpJ(?RZU 1^ %H}md4Wucb޲6e&\5z灡`FTvdu{#iԮM|F&XՁ]b8rh@epS-t/: H'@`o=s @ZMVtkf.a;2t3㦉u{Ui*8Wp}:(ẼQS*:BO zbϊ[dj1χcr Iݣz`clbu>e>o;)D#"&ZPFHq{- =]P x8*RCI5NN7[((a k<^SJ^;UըBoT{2sJNZ,l3"I iK?,mR;i$FBblx)Բ܍dcXrm-)w!,$Phk\-sG z* @ @> 7L~8[i3) ys) t|3_I!i\44U6_n[w'W";HM֩HbGX*so7WdNgZOr ]z4|EzЩ0I tܣXb 9Nc%g<~KW#6 ‹0$ WG|jeqgFITXQ]Vyotg0tcGX_h-Uh9ӼX_a䇵ogIz!QKlFXoMAyFx_}-jð0xֵ=у(X;uf?_XDDt$ιj ͞ l% F塽㋂=GVt\1\2Pq{G1]h~/[(͡"WS[򙅢ԮL[QR_at`B$T>I{0f*/+ȟ{6@(?W$[s>%rG/'dJ侺 qdTSrS |k}fu}o\ok?Я%}9c`#ޢg )}6sws<b/)X_vmLKEMո 3HmଫĪY8~jd'y ~e6YA^lO[ܭ] `XJ+m(zIEK0l(t1' 2H3!6IYЀ1FƯ_( *h=Hq֕(EDˮ;؅Э5L )6.I[\ljt\aLj5Qg&cdTRZ@(b{(#Qmq[B7׬0eP=nץi5'/hOi Tp5隥yhBc3s[6SԑV%RQs^Kel~ )ypg*5N[Q$_@fE1eC 61E)fJG!26d5֫_}3\eIϋ4f5ZGfyrt \e[eMqݕO^t>jt*=j*xC+#s }F2D[RrJ"#4`eok|-m>^ݐ#1Ek֠,̏.עLG/XP;bbV@ݏ7,}kD- S HTUXg1DѶ;fF`7^LOT a/,6φdb,ؽH-F>Aq}7a$(Ļ\K*_.>,;:.8U6'.a;dq{CPzWr媌]`(z_v/)\kmIb (창Y5b[qsVFWb=MuKS6iv-멪!CJ1Pr\4+WiPǥ=Qpakv!DSLbx}vmm> /9M"˙6Y7uDNb'Br DsL]5!38r'[ Z_x7c+GԆ0FV~$z'ZadR4JH" }}_:4D,AQ䦦 h1ie,ޭ걏z?uuA,%|z@8 MxOSedjfaʯ xu#[FT7.UaFݾy?}0x( Ru|91b}:d[DtuSK y84ֆqnH5jogod[c 8wBKq$y+Pk뇬.#ؒko 8 GѮkȂ8Kqٯ3"C%tTMQE֛E-xR:B HNl+B{{)S\LJ&ݟ˪ n009a6 ![~`L#;łNXIX0߬Jm潹i|lhpπd$/AjB3~o11zLx$!Jh00jHXk:\c2 ׶JꖙM uLc74ŀܣꘖԚ/:|+Y҄"yCÓsw\/4ʐoWϋ G$8P8JzW$p*u#=KPz9n i0S" F;- -Zs lcRvƖ|Oٍ{m8 ( EiC `oX3 ?*oa^LUkdQ.P_YF8ƯW@S]Ӝ(FKUj(eӹoi8ȷB8Zzope?Uaٿ`ԯ;&i4{]ߐF?TmZ//*T>$I(zY'֦My5%qJc+ O9ӅXP:0F©@n5tKVzȶe1a>r#$?Sޟ#LFFaHTBˣÜEE`ocg JO1N]зR &[4LfkO(9Ե,:5y\nNZ.#\5vi_˄$g&/$q8ŋ !C7>OÉѣKgIg^[DIʙFnh#ꬢ:v# HL޳*Z4:0N⎒Iɑ@`\:d Qwj:n_s,\2 46_Obrz)*9*rF{&vAŢr<3[N~i>}~g5vkadbȗ_kXn6*VR]Si;uIʜ@IySC+o&`|qhT$~'JSJrDpuɈ9_վh3F72Dm jgbVӧx1 7FcI,Nb7߾EO@K cڇM]x<-裈mq_'П@StqרK /+'olNyl@jEVGZWHG~]>ٺqnl~.+;W:K&d3 m->Cu8IO-U#V=UhZ[Rt54:K5VTSwuFg (Lq" y޲0P#~[?SgoL-1Cq4"߂m;5lꛡ; jLc|QM??ʶRr[m"L[#&xe˞Ʌ$~ˑԺH"H'Zzж +7*&7VKi/0)@#[HDL ptUQQa8E⤉rك?pOg糳=h}~,}0P{u $ 2jOz >ib+:PIE:4ғX]/RcS?dzQ.:sS=N2*ℽi&/5uciWgH综(#bYQD?vawtz#'nfȠv)2Qvf]`]1HnPʣZ7<_Z=vEo҉);w\* =I{a@@[JXʿra[[/l4{?y4r5;+p#R~PqĒ'L""Wu7f:#-9+bd]3 AQ"C|]BT+EF5Lo?%<{`m)$P4'70S@M$ ];8P]($?nlQY>KqKrh?I8_V6[P(͞rOƣ- m Xn>6%~YG}GxwXY<`Ou]> l'K%J2# xtlc w/"\y@mJ I9=|X.j}ucV L{t#zK9g3jt-Pn!Qc[0jR}4XRFLN%4 J:x\x!֏'2蝑+JƣV8/N-H?R+AjG`q+rU_b8fo,R!;A_[ҏcx^4.-!_7W eQg-e\@h õo#B8NtF~ GD>n!%HF1uD3ߺL7nTj.XA ! OCj& D۾%eޚ.Ӱ?,+wfw z> [/_1򧈱v1WstR0#'ɫ]IguځK1Px?ʚWcN٪.3v$LEB91E2LD5(V(] U{zYߦblfmORh/|s 4ijIJBO$ K˭I^ogcm,. :Z?wd$ȏbJjo1esގW7/馿7*K MBW#dS]W=t]sSlVQea1n;%?.ߪmzV:`kuIB8+vvw9n,ZFRH\ fA{Q'>g6=LሻKdg1pYҒ3M5+倫~X3鹅)tp=ņq}m>=lQ5J-H+sUgkSRf\K'I} Rm`.磕"-d^(F{{]fWx3L62ox:םA$*"b:+4] k]%5{%">|[yCJܝ3,*t~(MlC_S; b&_C13;) )T2Q󾡃^IUgۥIK D=9*+ 9782CvS YV#$%,5-dŞrH܅^y%7yo]f0$Rt}]\>o7]kIpW?#^7sL\/&$e`:j6BYi"\})Z],?Vj\դ`>;ZƏ$b?^/rʩ54Iw돭kxɗ +C -;xlm$g*qwm9 ڣ8ĀѭI> 5j' 32Xʉ4! bessuQHxpLbzJ`{5:B,(,:VG]߯B#RKjW:ylm<0X9ԇ4}bp5^ gMH܃lc{V7#8tl>dZ>ɚW?5H,A#rs&># CXqGc@WHʳ2y4CL6`}Z5U>0jCdc)5F7zݷoe 3t,tr"Rǎx̠FI5H*RGkE6gVQٓ{{TjCpȗ?-optҾZ$ # agNB 3[ü ׸t/sdrTL]ڰǦ$ʕVT( VOQpϼ~ v\#blf-Az6}Ɠ9-PU2YP +P.a!>zq!+u(zYbICʕD`(VJX0ry^g ұ_eBywOG[h!uiez'4tZ&,pebymeZR5bzbk_S@=CDg<5݃/6 7w'gRu:ȻZ$t[MA>gSD lJfߓǽ􁆚 x6;w+ RVHrMP8g^: ;Ʒyľ]gCUU*>V91K&ÄЉCe+F"s(UfLNFƎiat-L/k=";-Y\p `Th^ʍA%r/%&1f]- Og)P$Gӱ%lk0 ՗Xj9MB3& c 9;W/D=NwwJ(?͝f~lҾ|1Ԓ0. {Xҟhx-huMm[``e[L5(4&0xE".Y,d%T3/%I31̋,}ȚFQK P؃/T@eu_߻8n&qY\񝓨ӸйU/Ӏ)jo_諓ZyHgR5s덥=}|T0x"<^<,vgQD}n 7a;$6#anٺӇ5_9kjJzzůtp$g$FH%-s4jo&C_|M}Bun](|O}7ܴn T}珂}Q V';C_|Ƃ`>8$Pz~Ļρ OFEKf"AvP"O&87vBm銑vc6! ~/|aW n‘4f24O=|B7l/'dsե#vY1hÑiL"w^xɠ?§TH"|[tgi\ Y;y7 I?{RibDtuEwY.3\{R3 t=s>A6F/ 9" hfژGaNs3*c'agLbPvq)B0Ƒ,=ˉ鮿Z*~nF&;.X-$`Ցc'хWҙV왠FJlSޥm"+ ]$[:nzz[1[>!(Tn_Xnzr0FSk(Z,g("Am݋ȤΏ{(Uf({'d MC-i5P0+Qn~k>K@QXON|cCLm6PO'oԕi-R;jRl >ru M:A>b+.1ء nՐl [qfDâ5Q?6" *fݙޤc0g܍6[dT xTwp$?S̮yG{Ma+()BCp"lT yn Kf!73mnͱ Q318LVY˅;3f$QHxVUd>'OPWǫ 9&߇/rL:A $+O2+qHɞSD0ݐ5E-l!\b@)6mU#݀/xD[B PN Bݘ>A/Q963s:HBYtFN~'w*洯[+qaaO'߸;砲lR~"QT**qF=C@ /{EmwdW嶕[ Zt2]c3Y:u%ݕI! b P`'lzfvyW,HϘz~i4v_++vz!%}Nn|IŠj{ihn}0'GoPo*1kG艫ܿj&uHaƁ0@Z"Ws (^笎 M@m&y 7XDr4EgI4+$7^*:(]uwKShKcq1LAoy6=eԷ $oVyC#WZTJMH]-3i2Uq :+GE&t+ʋSq _y&M^ pS~8$ mKx6Ebo6+L6QI*dWY wOQh5='m=aQ5ȑDwzRSLcsȈɪe{U+"h?# 4RQl`ȤG?0rhFXY~rVC7N(ޖ1Ņ KmtZUz)Mǎi#Zy\:\@fl 6'6L`/{݄>Zː1kT/gPc"r$Un*] ._- wm9zdhz ~?a]EzUo=e ȟVF\LI|ΠzÆ[~jt+I=%KP-;4=%"Dtк,Bd39~`b]u~Z4:}$k7çOؗ8~nKg7@(+ɗ0!nH(Nv-V4:X 1G; 4ݺ:!OKT5NC<Խ3P Јp{ۤ^t#ͦ+=XXMBe=QAydamy}l9" 7nbs <1AC߆vQI` ,u WMVk'yl'.(1 d[#(vP*+&ȩQ`- ߕrM~oQRF}9s$}MUkė^gi/_:)F> QVP,CΖs{댉DG4? aJq~5ylmMH2L"mД*r RWnu ߻rG*46>oasS뎗+jfi+ Ui8~6 /{qG%\5F~w]?(q#_G |g Qs'R9MGܵ*DDb0{PF!l{~(*\" 9͛u=RKKӠ763Ɍ}H_MDVؿa'b?v{W #/5fi:Oz^JbؕPmwg~2LfV!ڄ bg"KY1s+!g },\ #w_QM܉Ggedx<%DžJ Ѭܦ+4!WRHpd ӱ.g{NɃ7V't2=ЩVADeo`-^{*ۍFWGsIPΩk*lJ76ˆ=d18m3i J1EQT²5ovmHV9,*``wdoG% \ڢA&{L0^d^z[m`D;c2<Sg*7xТ(#V |( ΙʨvEZ C+\!!+kM@ݭ!NmKvo K4suLի_<: :LlgIH}bT 4{ /:SY֓+_0 X1J6N뿄ma+T9U ʖ)1H.z+L'~5-#pu l}ә)^v/=\ iE9jK#x_e?c6unCKO IRG&XR.䯚荖OG & Ooⷋdow'8~= W z[Ƒ"25G,$&3ޒ ]y&ΧC,X>_ y% y̓zEH9)ܮ /m%ho7 uj+KmgOu)./ۙ.+KeN~>v- 6 o/P 7RCW|Z1!AZm ĴͶ a(Z؁ሮbU9/{*Xׁi4jB^F510sFӟkdJlU ׭9v۵Rucnwѧ㿰J#qɮΗ9Â.'F(ِyٳ ?hـpdZB{ǰ]Нk5;VZeAyn4xFؔSU`u5q 1X O )v7i LG0l3Uk.cPվnr7 Gⶻ9+,_F4:SG'W5fE#M'7gU(̾allFsZGԢ-J\K̙d=\1} K8-bշQ(B:9 \o=<eLltxRz-VWvP43S3OW~;BeKpeH&'4>`1b 7##TPKo u c׆ O̊h$.Br?m!WjˎE$9 IMH 36>&NYDA_gƓ`+NvOb}j0xv]EwkԤʉsngo W2L8=ݻ(µX+1b@_]2䵂=ܱ^:gGHR@f޴Mȝh|mHh4dz n V ]ˈ~[|P1mJY]"vk8h^H-:K,)x=(`e17a'%)?U`yg,S!$X!g3P!疺 ,V)HƎaQ%xubLyC-AaIsk|F2=F♥.P%QfH85ˣ1^@{oJ}U(HGd/)2*.: }z+ ,.|`r8n6&^"^'#bO-n%vzTYB8(%dBYbt<1`I $a4u.r6=+6$}$H@}yj @Lf)Zj% [jrGں>Ͻz@cͬd.|wa (]:F.lHjYA CUxDKkAT'6^3錡B8eKȒmլپ![RRt]IlEm6l2lB T> a\@Km9,X.LcH۸7p~áiB?I{#^vxRHqhgSE3*`gj#yAk59ެΑl֕?i}r;-)!UGVt.m*(<n(ۉ|㾅¸ߝ(2,R SK;p9YUu h rc#r##&|n]2<ݫ%fC͍ ͱq&*[rikZۼ S$r,Vr\[2Ao5<[sen]%l)6aoݕqJ17 ?$p[;$)'"|!eۇM\%JY6Qqdxl.?\ }#s7)ʪgNïʀ< >"m? =R위3Tsم@(gakJsч hxB#}e]cvYMbGS*E<)S) V@.rIlKNǭȣcT5+wS଴C%!9^7c'$ܝJn3;N%V_i6k8д9P5S.{W 0{#W]jY AZij%A! F{ Ӻ?+6JP Ez-bV]@ZZ+8{B'sK)wV dRݧqy4rej#]sA ^Af96Vθ4ZIL/ѬZ=mfYۄ9v,v%?gb\k4B4eLDѸ3JED&Ot2V8(oFtz!Tg?&WaoėŲN牠JFؕ0:sC ]RA~2.B(UvbŹ3jIl./yD}SD 1IYh\mw`@_m*ۈ`f i`yT+7XZT̆=J!ƚL1Gi v:=B?va$ Qw kQMfbRGK?ur \]šƫB 1 lqE̼&DHA][Z"$g$aL8)O>͘z$ ףϒm/몎aLbiY Yo&ؿzttTӡADB9)̟.%jtpكx>25=c!N6K}q"eo+#p  s pR(-kI1ϼ/7q8 HA{KƢ8n(h ZYS2&?3dz_ vP v{EwJҵ r?AL OJKgD.6Di>", QJGՌgRI uP:zhO(aY+xDyxR%A@u:4Ѯ yy@lDŽWCL=.Qgfts Ox#\}|vޔpK'_6<-fcS!5Q<,Pf; )Ssh> Lk/zj IOFD,ywL 2&@Zgrz`q;`û'Kjx}q..|MiKr 6$F;=DRkmUhLdc6B8ktu: C ]_i8{l <" ^2u:aj)բ+9jhn9V [8`W;4ht韏>LR>ߩB*lzo #XC}#r"".N-h:}f^j;3y#8ɨ,⹕UmˆT{:-fPɷ~AV¶ݯ&BfVT\*)A'>CD 4YzT;l|͕F;^#Z1Az\O/?V(J k'%[YsOi`3e8Yg6c7l>Z(P{xSlD4'r^ޚ<0Mvs@ Zα%gw⥮ݏT,r\Q+}m7WFG4c#qz30)gq+ R4xL53XMns־?Er5V] g-YiI3m1]?$k1M]@Y6i\JU/XRz0qHʼnB@tMP&U밧O3 [J=LgBܐŀw2YW|]u"^p<W}95ˎ`x,\P c@` o-~G X..g$+|B(ag(,c=* u kzb\\)Gu:4WE>tpXBDRIR67*9oKP/ ^sR8J % KG&R˥ض_^&/S#Z24.XiU=t_Efq\ÕpBqV->+`Y8\GGA停U _u6euCmPlw ڎѸ9#%'CkH&ӳx[I.B 52(l44L:ۄaۥ9h2#ZG$c/$ς9EgU,hSJ+B \P&sjɈD)-o.ۜDs*A:C󂌟7l-puhI353/mL-Nչ{:3F`t,|6T3&jB#(nYSlv9eNd(%g7OiHdT oZgQ!g%H?]!u'eOvح;(ó#\dhn@a=\@J=Kv'+R2$N9Om' +ϤѱF*ç#+/->m߂sgwKC[m*/)KcԿU sn6_l\M~帔Y8gСz: ?!Vj("jwݴHLbS l켪ȫo(yd,5LsaP^Eؚ{hƑz@{sk_ 5#c[}Ot1c]v*Srw˺m0T&ph2?`Zu! wEœ`ԔL5h5J Uԙ3<*:*>SI 5vސK4*8i|MIűONuԥfE~~Hi6&r,%3*|eA p̊ECk$l?$D\`q4ԥ# Xmeht(7aSs*Tm g0U!wT%qDʚ&#ProDsqI^3)+Q (~^כkm_n?u|BUm>{96K}Un޸7v?n~ނ?mkۮmz7۲w?mL*xCnʍ#!B58V|#ݘa_ u ~F'ofb7u'coZ܅O3 }IIȧ_@(G?trA4#ڇDn.[ ?,?ر}([uVoQ@W`EP {g6Dgcv}%پfR/OaM#L -]ww)pG\r uũ+Ut(ykHEjvhD ,'1UD*.tqAbbj5-CpD3{8%cKIDwTޜqJ}jGE03c-[Ue:beouuﱷ@U3(nja+eH5`]*"$.O3b>ޝ\)8E5h]MDKpHދd~§| %D}N<6͠VԄ"-x/ 嶈(_jd޾O`,w,Og^pĕeM )U^~x?]ĂԑΦ9"K$Dz dW bJp˃^qHBֶ)`&Oa cUZe\OFn5c2Eᝮt<r[z]yڭ#i>@UZl̋t虧w_R'@+_)!l~7j9FbT2nEugY\]fq <[b6y35"RlmzmNY`de#aZy5 ;AN`wm4Ʈv[Dʻ-Ӗ8>Tu>+FWTQKWc,ixft`'siX܏o8Nlw-!, I1캍piSyQkUSrfw`U(=?mVraTSWk;[!z"ΏǐñB1Mp#P&˪3%ػ{8,tGnJ!( 66.^EZ& 22ڝ43rɏ4.ʂ e!@Ja#\.;Q\/mߐ}P[zkL?<|C[,AX!!yNS7AVX{QV䇳Y`ʾ6LI>ynBVQ{^Hn^05o!h# 1. u k8oo,N`BfWj~4Cy75(~PƮ茸?]l)JOqB`(VHrms̒fwv`7^>ϩZ)΂&,VMcl! vH97kTةmyv)ݒp&GzkT/ˈeJoMU]Ұ)1..6V 9Gq{|kU)/aQq))WChbeW~i^r܃c+S_Mukr_ZfUOl\^N k6Fa"k=tBA7ǶuyL%~ 62iU`{W@PIZsk`u?B2S+DU=~nkX5@pfċ0S_ߐw/D.y+@u' K&x^4*3u&}.aC E*ś1v u+ֲTƐ{Fp_gT%F`Fh +ԩ=@&egqXAMe)RwgI8E\ iWed`+X1taL`nZgB*l'>OV` @3r{D= EE\˷]hĩKǻ u( h}S˯l̅cIuZԟD'UŞLzeq;m_ߏv'yPN._-Gs&K:&RPW/SEZďt x n(iύBp|@Yqf.|9YByOk@WtNld7W3~.8jH]w .Ol(85D˒N= 2·ɟu69GRtWW=,,m&k&C5{IisҔ$& ]N1&NtK]ɕyxכ}Ř"mNZf_גyխn["J2x2WmL5T)Br[˙IPK 7muP:@4~GD43gsI;b|ǽ~~a%SVY凾\' !to#Oo ʒlseޔ4YG,nx$do)P;1uhv;fdw eRvng\^$5KP1bRbSJ܏HgO@KPH86x5i4VF_w_6|rM,;$*y5Lc)QdGGIZo߇[ +%_u1 bs4Z~ P+{tQoא`D%ky Nm%:In)dzƳi,s tKF|;˚yWӂ[aC:yVQr#}Y4bR}nNP#݊ pshUNuP$~ul!؜`I{7|%l2YI\3 R@:y6ʰ3ח W#B}qN o՘by =-|&YW6n 6N8Z.XBEYmg cH4U1.wMsr rW0#)9|\N D>L-[/I!jEd&/aDt״kF;*['1㣺*#g\m~U9^v tJ$un~@%X4[ʰ]l oķUuZxS :'tel"BtVjW?qb'Eⶅ;y_9Ih:HqkP;T'mq_Mçɉ6glhJ⍻kJhE5af/Ut#^ʎ=;ܛG@x" AS,&lImm)s;?E>K hݐsKB<~ l| .  w}xOCVX*sLMI2~a3x۫\=DOfӑV_ 멎F,^BxYb%Xzrmy|SpIW^аHzG{hվ#9q?e O,&`]AxLH2aibWO(V0L<Ջ &GNB868@<)rhl2*3H8h{%$`ATH bɁѾC&N`ήs~ ԓe=}ju}sݍszgv,k'FMլ/6pu=@>B"mSYXS?ܞGҴZyT ##A<ޅ~sBקTW/x{vezwy:@w59\<7VTڶ:=o`g . x!V=(,;{;(vNPUxQ{Dk, ].;_n@3cDVۿc[Q/3e悸Ns Y.@5-Ʈxy8Im%6Ŵ+`%xٵF1L$TDeSm占ku;<&, Τ2[y5QLNx;88A{χdlȑ5>AUr 6CeE6BxF=c>DW_!YmPtDQВX*23;Zo7i̺qD5%xm 5vCghWƼ@խl} vL~-$bJ~31J7 H8۷ rjH܅+r؜ELP8=\ b5\9A T]qՇ,?j*hSowR7zPT̀O)&Fq%{{ɬ9 :,ږvd<~= ߑwP=ןoi,^ їUqF- \6w6w⁚@UԲ4zW@ׂĴ><f":r畑Ӻ1^Flw O>01ZVzG| 9,ˣLqv5N/ݹXZ!{] #)իYYN/⽫Fqe}pt݆-RkTsWbg8X"Op 9't "mt`pdaw:/<8pP@ҋteQjAPua#ڸ{q޻RyqV˸ ]|Ȥ%3 ,DƒC,xM Ԗ9Bf9#6Mx8Tsx}"QӖc8NPp*tB0@7=3|ꍍ)Z0`LDw: G!kz(Pkp t7_ū l!{j-ߖa,sSN-&X5#siceQpZB?ɤFCw-8}]41?%W@_XO]L}5sd)2$3k+esU2,J (0i}M=١߼bX(4gǵ2X\R <*.ONpQ`Wo a?2 ҮؠRt[g;C]8^PuFi!qzSP` ׬#,{= N_`M-#}lp\iȖ,K'$2# ߦ@37"$trX?ҨY4>&xl91rpԴenόyf&eoZ#^NUXVjc7IF FДsUWVe k'YCq(bfpƦ`f%d>EKDXz̋2A15zBJ] Ukq-V}9GU8N")9@y)c,k?ѳtŸ^ JExIM555_C,-/7.h" lrw-8.n_ӚN|'@HtǽK"` 6B_.#4"oT?)[_' ╸0Fc>T\ ~ϣ߄r؇cnfFC(v㼟KUT¬p:O=aK.vWKq#jo=q# ْT N9-aaf0q A;Hҁ MfN,Řߌ$8 |<%wdi?:uO:{1. *{p[V5>J̚Ȳ6{T,_Z~} pK%|V iPq^pZ!w'(ޯN|qtVD6ޝvU4,̘B5&i‡ ,j^J2r%TG%! Y&>Y^#+8SUSg\D,eɁ{9"rp@c_e}j]m[[?4_#،^2O0Єy2 %˓d!2>5D+3FA abڊJjk"cCXNj=f5S |i Zm \QJPXֵY0~n0кzim4 wbؽ$;%XT C>Tr\b%xLFiH51~Ш v*w$,uj_zPY"験ڡ! ն( _Z8[ZB{9Vz GÒ|h{U8\,jcńt ǐeќwgo)HU*sRL};_iW;Ύ0-^))CaNjm#Qb9h<>6BWW9悽EѶ̓a ִj8W$h:C&Pz_C/*c;v= 7izS3gvrͨvi?ER~ aW%38PI^Cv;"CȤE.-81ydGčGK"u ȣ=Mx.DP1yZx~ǜ+cQ:3 :lUK'>}|'], ~`/KLv*8n0TpkI2h< +SyyaBËx$$? ' S' xA#]4ڊ`։''JMUo>۴dy6嬤vGi!7G9-UAn=A7gҿ+4(uy] ޷8Q3XaajPf|&9w0k PN#YgvN<< XkNO?t`׃< {L4}StT: Wf B |< #t|xP4 3mxc`*q'p N=8H3 BTߣsQx*tiCj0OӠ9N'O/r; oz,S+-f8:ڢ:cV/2$Ƹ?>e#Ca0ـ| _ j'Vu@/=n( =gs7tgkqo .7W[~xK-9%Z4ۥǤ-~JdODtb՟[ڌ nMpE|ffFM1ehZ(خGz*ǂT/ ֭kJ)Oڱ>l$B{R,hk1\PĿ 4ν$L\M'Q3v#kljM8zO):g\nw+.4&[\&{w toxm` i1ize1N(|2[FE'#( #TCs" D2.,oODPd/͟ycImX"M2]v+ } \Ñ~wL셚{K]JT⮽f!pSg?1vM5u'&-cD6: 7SSu x:5 ω 1Y-a ;ܹ ]Q i"ge$wn<<A b`Iҵm@w ʤ h! {׳hLB ]"s.am +9 $2`O}o ! {7LoRD~OdYdZfN'CipOiXF-z.o=aZ58>B6q ApFx? uE_ ? )|\jc# b^#%+I2]R!!%p~.Ω,όYw},'x1AcJܫ0]k.@e{IId0B| `ba\;k6s DhqUF^"=ʫ`FXPܠHÛe3*PrV )/o'iէ'%QvЫH]^#KQ1ZzᵾQPaozfAձ`7I-e2Tus:ۡ ᙡ-(m$r3xvB݊;zz6>uR^ډ4_Xz ޫ%5!?l{Yiۂq^\D;[:zPIDFoݫkc;<.8z.9ZlZV[dj/w= 570^;"\-~PG>`pC84Zbҵ_E`d~Ѕ `ů8`4Z-d c,k}c\ڱD~^aDٛ#T؇X.[\zK@xU0XbH8`l~x 8SQho-)Ϯn[=3\mC? oZYNzFI@ʘS݈]Z\S{qZE?$IP)5`iiآXVaP~ 9Z+/lyQzIMPf-)$eV*)It)>+HrE QO\ T w2e&ڎ6)Ö{Uw _n R9dxfWxos7QC<[G%SV2Div0-p0(vEuCF/ɡ/Ђ0DɭV\D(fa +g֡ʕ0:G̬ Ig-zj˦ g_|&u&WS?z9Ȣ_s >|ց:^<~D"L;Rgp}62 bWiv{̷ۘ?s"A|\ՙF3b0k{ ǒgYx~/Hq]iȤ|I%/WR(N|2^#+ &' BiId 3bۘSc&!!3y_?Wi5_(>:_;I("j̉iBtM|p-\,L3E~]a'QJ=Q_poA^!|Om,)gU]V\psa h -:sqK}U wY #_ ot Лu'a>?QjYmUhtgw^5u="+t*nQ)-@ Btc+'j>nWA[*L$ZHe} $ ]syJaUw|,ty$󣫇!&tFT dNK*rӼ6cke":"<>.U, 8ؐS4б2p\ B\slq kB?q @S[|~^כkm_n?u|BUm>{96K}Un޸7v?n~ނ?mkۮmz7۲w?mL*xCnʍ#!B58V|#ݘa_ u ~F'ofb7u'coZ܅O3 }IIȧ_@(G?trA4#ڇDn.[ ?,?ر}([uVoQ@W`EP {g6Dgcv}%پfR/OaM#L -]ww)pG\r uũ+Ut(ykHEjvhD ,'1UD*.tqAbbj5-CpD3{8%cKIDwTޜqJ}jGE03c-[Ue:beouuﱷ@U3(nja+eH5`]*"$.O3b>ޝ\)8E5h]MDKpHދd~§| %D}N<6͠VԄ"-x/ 嶈(_jd޾O`,w,Og^pĕeM )U^~x?]ĂԑΦ9"K$Dz dW bJp˃^qHBֶ)`&Oa cUZe\OFn5c2Eᝮt<r[z]yڭ#i>@UZl̋t虧w_R'@+_)!l~7j9FbT2nEugY\]fq <[b6y35"RlmzmNY`de#aZy5 ;AN`wm4Ʈv[Dʻ-Ӗ8>Tu>+FWTQKWc,ixft`'siX܏o8Nlw-!, I1캍piSyQkUSrfw`U(=?mVraTSWk;[!z"ΏǐñB1Mp#P&˪3%ػ{8,tGnJ!( 66.^EZ& 22ڝ43rɏ4.ʂ e!@Ja#\.;Q\/mߐ}P[zkL?<|C[,AX!!yNS7AVX{QV䇳Y`ʾ6LI>ynBVQ{^Hn^05o!h# 1. u k8oo,N`BfWj~4Cy75(~PƮ茸?]l)JOqB`(VHrms̒fwv`7^>ϩZ)΂&,VMcl! vH97kTةmyv)ݒp&GzkT/ˈeJoMU]Ұ)1..6V 9Gq{|kU)/aQq))WChbeW~i^r܃c+S_Mukr_ZfUOl\^N k6Fa"k=tBA7ǶuyL%~ 62iU`{W@PIZsk`u?B2S+DU=~nkX5@pfċ0S_ߐw/D.y+@u' K&x^4*3u&}.aC E*ś1v u+ֲTƐ{Fp_gT%F`Fh +ԩ=@&egqXAMe)RwgI8E\ iWed`+X1taL`nZgB*l'>OV` @3r{D= EE\˷]hĩKǻ u( h}S˯l̅cIuZԟD'UŞLzeq;m_ߏv'yPN._-Gs&K:&RPW/SEZďt x n(iύBp|@Yqf.|9YByOk@WtNld7W3~.8jH]w .Ol(85D˒N= 2·ɟu69GRtWW=,,m&k&C5{IisҔ$& ]N1&NtK]ɕyxכ}Ř"mNZf_גyխn["J2x2WmL5T)Br[˙IPK 7muP:@4~GD43gsI;b|ǽ~~a%SVY凾\' !to#Oo ʒlseޔ4YG,nx$do)P;1uhv;fdw eRvng\^$5KP1bRbSJ܏HgO@KPH86x5i4VF_w_6|rM,;$*y5Lc)QdGGIZo߇[ +%_u1 bs4Z~ P+{tQoא`D%ky Nm%:In)dzƳi,s tKF|;˚yWӂ[aC:yVQr#}Y4bR}nNP#݊ pshUNuP$~ul!؜`I{7|%l2YI\3 R@:y6ʰ3ח W#B}qN o՘by =-|&YW6n 6N8Z.XBEYmg cH4U1.wMsr rW0#)9|\N D>L-[/I!jEd&/aDt״kF;*['1㣺*#g\m~U9^v tJ$un~@%X4[ʰ]l oķUuZxS :'tel"BtVjW?qb'Eⶅ;y_9Ih:HqkP;T'mq_Mçɉ6glhJ⍻kJhE5af/Ut#^ʎ=;ܛG@x" AS,&lImm)s;?E>K hݐsKB<~ l| .  w}xOCVX*sLMI2~a3x۫\=DOfӑV_ 멎F,^BxYb%Xzrmy|SpIW^аHzG{hվ#9q?e O,&`]AxLH2aibWO(V0L<Ջ &GNB868@<)rhl2*3H8h{%$`ATH bɁѾC&N`ήs~ ԓe=}ju}sݍszgv,k'FMլ/6pu=@>B"mSYXS?ܞGҴZyT ##A<ޅ~sBקTW/x{vezwy:@w59\<7VTڶ:=o`g . x!V=(,;{;(vNPUxQ{Dk, ].;_n@3cDVۿc[Q/3e悸Ns Y.@5-Ʈxy8Im%6Ŵ+`%xٵF1L$TDeSm占ku;<&, Τ2[y5QLNx;88A{χdlȑ5>AUr 6CeE6BxF=c>DW_!YmPtDQВX*23;Zo7i̺qD5%xm 5vCghWƼ@խl} vL~-$bJ~31J7 H8۷ rjH܅+r؜ELP8=\ b5\9A T]qՇ,?j*hSowR7zPT̀O)&Fq%{{ɬ9 :,ږvd<~= ߑwP=ןoi,^ їUqF- \6w6w⁚@UԲ4zW@ׂĴ><f":r畑Ӻ1^Flw O>01ZVzG| 9,ˣLqv5N/ݹXZ!{] #)իYYN/⽫Fqe}pt݆-RkTsWbg8X"Op 9't "mt`pdaw:/<8pP@ҋteQjAPua#ڸ{q޻RyqV˸ ]|Ȥ%3 ,DƒC,xM Ԗ9Bf9#6Mx8Tsx}"QӖc8NPp*tB0@7=3|ꍍ)Z0`LDw: G!kz(Pkp t7_ū l!{j-ߖa,sSN-&X5#siceQpZB?ɤFCw-8}]41?%W@_XO]L}5sd)2$3k+esU2,J (0i}M=١߼bX(4gǵ2X\R <*.ONpQ`Wo a?2 ҮؠRt[g;C]8^PuFi!qzSP` ׬#,{= N_`M-#}lp\iȖ,K'$2# ߦ@37"$trX?ҨY4>&xl91rpԴenόyf&eoZ#^NUXVjc7IF FДsUWVe k'YCq(bfpƦ`f%d>EKDXz̋2A15zBJ] Ukq-V}9GU8N")9@y)c,k?ѳtŸ^ JExIM555_C,-/7.h" lrw-8.n_ӚN|'@HtǽK"` 6B_.#4"oT?)[_' ╸0Fc>T\ ~ϣ߄r؇cnfFC(v㼟KUT¬p:O=aK.vWKq#jo=q# ْT N9-aaf0q A;Hҁ MfN,Řߌ$8 |<%wdi?:uO:{1. *{p[V5>J̚Ȳ6{T,_Z~} pK%|V iPq^pZ!w'(ޯN|qtVD6ޝvU4,̘B5&i‡ ,j^J2r%TG%! Y&>Y^#+8SUSg\D,eɁ{9"rp@c_e}j]m[[?4_#،^2O0Єy2 %˓d!2>5D+3FA abڊJjk"cCXNj=f5S |i Zm \QJPXֵY0~n0кzim4 wbؽ$;%XT C>Tr\b%xLFiH51~Ш v*w$,uj_zPY"験ڡ! ն( _Z8[ZB{9Vz GÒ|h{U8\,jcńt ǐeќwgo)HU*sRL};_iW;Ύ0-^))CaNjm#Qb9h<>6BWW9悽EѶ̓a ִj8W$h:C&Pz_C/*c;v= 7izS3gvrͨvi?ER~ aW%38PI^Cv;"CȤE.-81ydGčGK"u ȣ=Mx.DP1yZx~ǜ+cQ:3 :lUK'>}|'], ~`/KLv*8n0TpkI2h< +SyyaBËx$$? ' S' xA#]4ڊ`։''JMUo>۴dy6嬤vGi!7G9-UAn=A7gҿ+4(uy] ޷8Q3XaajPf|&9w0k PN#YgvN<< XkNO?t`׃< {L4}StT: Wf B |< #t|xP4 3mxc`*q'p N=8H3 BTߣsQx*tiCj0OӠ9N'O/r; oz,S+-f8:ڢ:cV/2$Ƹ?>e#Ca0ـ| _ j'Vu@/=n( =gs7tgkqo .7W[~xK-9%Z4ۥǤ-~JdODtb՟[ڌ nMpE|ffFM1ehZ(خGz*ǂT/ ֭kJ)Oڱ>l$B{R,hk1\PĿ 4ν$L\M'Q3v#kljM8zO):g\nw+.4&[\&{w toxm` i1ize1N(|2[FE'#( #TCs" D2.,oODPd/͟ycImX"M2]v+ } \Ñ~wL셚{K]JT⮽f!pSg?1vM5u'&-cD6: 7SSu x:5 ω 1Y-a ;ܹ ]Q i"ge$wn<<A b`Iҵm@w ʤ h! {׳hLB ]"s.am +9 $2`O}o ! {7LoRD~OdYdZfN'CipOiXF-z.o=aZ58>B6q ApFx? uE_ ? )|\jc# b^#%+I2]R!!%p~.Ω,όYw},'x1AcJܫ0]k.@e{IId0B| `ba\;k6s DhqUF^"=ʫ`FXPܠHÛe3*PrV )/o'iէ'%QvЫH]^#KQ1ZzᵾQPaozfAձ`7I-e2Tus:ۡ ᙡ-(m$r3xvB݊;zz6>uR^ډ4_Xz ޫ%5!?l{Yiۂq^\D;[:zPIDFoݫkc;<.8z.9ZlZV[dj/w= 570^;"\-~PG>`pC84Zbҵ_E`d~Ѕ `ů8`4Z-d c,k}c\ڱD~^aDٛ#T؇X.[\zK@xU0XbH8`l~x 8SQho-)Ϯn[=3\mC? oZYNzFI@ʘS݈]Z\S{qZE?$IP)5`iiآXVaP~ 9Z+/lyQzIMPf-)$eV*)It)>+HrE QO\ T w2e&ڎ6)Ö{Uw _n R9dxfWxos7QC<[G%SV2Div0-p0(vEuCF/ɡ/Ђ0DɭV\D(fa +g֡ʕ0:G̬ Ig-zj˦ g_|&u&WS?z9Ȣ_s >|ց:^<~D"L;Rgp}62 bWiv{̷ۘ?s"A|\ՙF3b0k{ ǒgYx~/Hq]iȤ|I%/WR(N|2^#+ &' BiId 3bۘSc&!!3y_?Wi5_(>:_;I("j̉iBtM|p-\,L3E~]a'QJ=Q_poA^!|Om,)gU]V\psa h -:sqK}U wY #_ ot Лu'a>?QjYmUhtgw^5u="+t*nQ)-@ Btc+'j>nWA[*L$ZHe} $ ]syJaUw|,ty$󣫇!&tFT dNK*rӼ6cke":"<>.U, 8ؐS4б2p\ B\slq kB?q @S[|گz~ޔ?oo}NoZU}U}Z~ޗ7_KmJr~ޕof~ގ7ѷl}[ez_.޽mķDpdQ0$[tRK Ӻ):͏(,]\I%e;ȏ&gó%;~UuσQHUk}GZx÷qd)E ?ر Jؑ0mSlas+ƯєmQܽZC /,߿S=]1(춓_MNC2%&6.6sBeCZzJkqn=AWj@f@8P^-vG̾5p=duɿA Kм(";,DSSZܓr9Qn=9֞CZ=٥|d<-"RpW0th?&PB[s>0Yyyؗ2O|rMƝc pz3046`za%?2iED+ Zp):W=mX,INs܉֖nxBM`qy>#i ;w4l3"~a.Bb1))ޜ8SV$Ә[LrCGoD:ģLSf =<, o_3 d״zh %+a~ɲ}ӇQ_~(r5aRk+4uDs lPe^u0MI10W B[7 2F .-4|U<ƒcD ʗڡ ahZ s:>2瑝G<$(+QlU_oR%#{gᚫx!skc3W}OQ,!״I!/Gb\C%827 1"@[yKOA'C-}n߬9(+#ol/J v~XuKJ;^)Fc6. DdA($5H:Ճ366_HNrM/.B+9݈٨>ڀ67c|4P@r 㽁՛ayZJ&k 2Kg;3$gV Ce9%ZTnL]ǰTCBZEa24r>NKX rEQ}9nQ7.fMKSX <.VߢdAEfd>GYT_zv-@M̮x fW+Lr əB~>̟Qc)fOE\m mz9h=}>1Y#7y9~F Msm|ؽ'V7iKEz^ 'ŷu!Mw0nP?o-L&1<<#Uy8yJi;5NRo򚉕%!GX,)>SerLK˄UIo;?t <jNOr5S|s1t[g2UP͜knV3aiO&W 7U͢xhV?ʃ@p23&WRkUWa 5`ЌY$ vCbLyZM t5[o_I ?tTBdu:#ĭN* %:`RxpwBCg`89ЫgD:ifF}%(tv} ,Ӝ!w2'`$HJ'YG% ZA(c*X)ppe:Gĸy֧R ݔ1Dt:3CG9_OlSk7>!Z閔,Ja6f73uݽ= Q4Jؓ e H&ی"y 8&"',_OZh œRioi[ RO;D mr }pл #(l$t-T0d7& 'b]hgma{аmeo@oA5P"RppIG\9AٔڱZY+e>p9Z ė.!|ظyLU&I5jGfYZ}U5BA1l]_Li"yG3N!9m p0j=,'7@6ޟCΉopS"NIM)1hnv:!a~Z #k}oB_b)~$rtl ckBk@6ҭU x Z?v|06&.6uRŇ'ܧգP)1A?{KE15ipE~UFA "*$A<<%lBcfUaIT_9KtQ"۞{PV" ~#*M0=I E[|t ߢQ!Lo>BufttSG(I*?WQDw`JfwK̷ 7z" NxB79wɶ-,Bx]]O /p\\G‡:wS&ѾBl^J ]ypoڄc"m:1Йx¾r=26)(2U;m9i,86GkI_'6ox%%]N]7EHj,dd@ۅb~mЌ\ f"JwEH9.gjZÊd敀[s.L2&h_~r%mڼujVָY+4>1KTq̡ {]/:!$pmo͹ȼKOSTE܏%K}/h g v6HhD5pܧڥ.-X=VEՐj (uRit7Nmѕ؂ȗ=~EyGd"H0OL -LR{G7 Ȣ{q 5>& ?>)d|'1nUC͉1 C"MB&݋V4 Ǒl. MI =XMxŴ7W J9э ŒI̖CV( b>Uo H?5/S<ۍ yNOq+Tw ;|^5:vb Z*n6<G_AmtIm;pISFělc7~?LBaT&62GC$yilDqnPej!gb}˩gDO5Z5(N9lt61u2%JW+[9dD%nL7RǸ܀YZ}-gK3|H0q^y _{&}(≲Lpr W=W- \~^`< Qg ؔ/ _F߈lJ+$:dEIe-lԙ >:&lgPI<6[i]5VA^5+'Բ a):\BQ aXط܄\.Ṙ'JKA,OWo޷#H{M"VmS%AЧuR4]Lb 1FWiTZ;ev C0xn4Ǡ*b3aB5/w&^Q cJ>:^mHL :Vohn$:rUH$ɵ8?G*7ZGx$珇4ш| AuI0:D<9SWOW' ~UI`R yQ*j0M,xZ, FxЭ;x$U2Ge4 ^'fqH73 Å1Q(7h/ݶ5K+C&iyةX=kT?2M~ƼΪ]LEOE6zĪ'aK9ժ[*{݃=Uz0j#R@T+lkM&_棫W=[b.;$t;|YUk:W"՜~ػ[ViEy(WT9RL0q'WUX(t`WJM<̑Uk' bp34^.Y%pluKϤ y@tnz Q<>J ?` ͷÙw ζǐClWv wkqDBh2d:}Avbz4T hƎ'Hd9R_l7'Ч)3lB|խ}@JAhRvo~S xqU^>Hݘ9.c:'# ,[$]p} ŀDr2i&aN2E7iMa=LWCBOWpO-D.uOHOBTpvXDJ3:C,9}`9RPa=+K,.Ve=="u{j=h FǏ|֙=y%sϽN]X2mV)y+U>K| Y9_݄z|$;6\1٠H{g@>ԣ^R`C<(3Uzo>rM?jv)q]WNP3Ti.R6LIuEH7kٸ XaWђīO"<-uyB$? M084H+ܛ`(oӶ.lO" alo},.E <*+q\HUHqqLƚ)M 1ni$v# UV!~*N EW 'Pz=ƚXi6l>Or|y~I(ɟ?5RQc a"8`bG.~oiˊDlʶ!=V!2͠ 6Mq"k%n@sˡ"0 ߇v)W/ L}i0UG s5lתqD,Du]a^Mnb\9+z>[pžq5<|FLHhjL A0XZ$Yӈ;y@ JLރ)YzߋҬra,M!vH-yО Կ'`ef&YϡƊFaF<,wZ3]c48b10[llJB^# 0>i޳V *yd"'X}e4׮$f |7lP** XO4s*C3i7Po!&dyqP xɤ_|W*O(,i&UX0/#TJd3-NyJ A忪^ 'T= RUsjGڂvuZL~ĕUfi#A-d, %q-HN-<@á(gkKҤ+{ϿDwJϡ\tw\7L=U`6\^q!TƛDn/VZr[_ۮ;场Ж4 7NRDqytUqB21f4^sщxHKF~;Ҟ71߾p\h賌(jo) "}t>{_{n.>RWVKffYHq}T[cdmkE74d'/ >8[Q#KNB?RҩW+vV5]M DT'͛T:!`)~=9գŷ͗5t*E\7a[J=ո.u >JmZblpI nehO(A^V'y{3$PIP~%i\o55zqRVҲs6wYSoЯe,2d&W5]s\bR?>jϞj8/Be1A" (ͣ"&;3rU>SZE%Xvυq#-3<ηRf) ) a"hTKsTDza;M[{E$dr1 oV=f3&b3RhNE))`"|z,^: '!9Em0ԫ<`2LYH p>D٠xסQb`'Q CB,^#cpI;Z~KZYoS깸3:pus AY]#h;1a^ 4<;e R+EV QB],7S~6aJ6S^)+*Bn.1`4Վêq"T^xŅǑ& hP @%O %GoKI] {w+NdG<pO (w;=q}k gP*΁$ ,4\ox Xv2j \m;)ĄPb;RhdC "cqSއELj 3'5@{_ʕQxr^ <0rAݜ5~S_2S#u~7a-b04\N0(x +lx}͋"'_,n3NmsGW1j4;!' H?J<u }I |qK@v3S.ƶ>̣ޑ*_/.,و/_CbXtKk a.2ѣ^,0.OU?$GsJr]086b;xS$#dpֈl4[,vvc>t7N id?#(Q\Р&Dus#D 5/AnDe)S#%;W@uSuQg!t^J=N9*d=[3?%4r/D@- W7!moDLӰi9rf1V}=*9eQU]Lkn F{EMHN9 *5pI`gw G*5zNE(Ed%\ 2V7 D1\b  ;I"y̱(.}n/~hG7 ?μm,J^G%lC'Ԝc[7u# ߮$G" i$'[&6IY(%?#7;)Nң3x ǀVyxRe'A-yJ_2L &d4|JD%n9ミNd>yjBܔZ? =' 1r{RGoZU+\{@:_ t9P_rnkgZ+8(0Iӎ> 7ϤcD1p8毂2gmÝɞKP:pv՘F}hr+^K#xBUO̐znd^ZL{|nx5bZ[/ ֕m6L,yYUFkiet<GP\a\s򝔀S joq}D'`JyJ|U,Qso(C=uQ$wSK=H~r$P^+bkR[(w#GR1~ܝB~*dIh){=Kᦾ%_qPEOE{XMYeAݩ"Qa[&bleZ3L}?Qd̺+>'(nGjSPe1rxjYG_|%>Dcy :*ͣOEMz ?Cp˖h^z}Fxlʼ?z VIy`4E_J(rBb~*޶Eey:|`}8K] ̯_ ĹUs4E Ҕ@6T5M!}ќprZn=wzt,ҌBd #pdII\w&>RQ)9-;3ۖ?E8ô2ھzEA c)J{u @ek㱗9WWx+jq*afx~u ‚H\2bhlR+ih ~}e+ ko5_tٙDm|D.WD~MDR59Zn-e /Й,A G9o}ĢU'?8: N Sn@/`+~e:abHqS7C,MTA e_&%Eoj$KG3SW)M|Q6`3XDd}Q?FO߷rj7B* hg]o&h#rs)M?UGm|]>w8޸RV+T7DŽpvc#nK*7%h_1‘{o[bݔ:9SNϻpNaX\U3!14&'NnW9EuNR͐-[)-Y tk)1 -<ȦZibq A`?t5JP-=kW0=F`oɀT5vy½ 5x:@G /#|eTDH>5%Co-ĭ0ʹAo~mG$} z)5{g*6>vc#N @:Ǹո)>DZSXDz%U\Sn jB :R0r+Y+1m1rHmnI3Di$ˡ CgxK zQr(&7 }?7fqw&U?L0OMps8WUz7xi v'7(?,Z+}$k+Ws z pLV+Yۆ eY5EJEdWgYX6Եs7tҭ\>EDd.C7-KELŶB~I|lMZV t?3=6] DUtH>lN:ao8Ug1&T4׌}ilͪp=|e;o\,gmuB/EvxM{/9jR d:Enqu E 5$1y~|psL}†jؙ_!H9KLkf瑳Fw,GWھ"D[3j^9\3PԁB{/*">o.|8Mln(&brC%y1˓(iߴcNovk~ YY]T1Vpx9MZbrģZ̈M:ůp;6Kvth֯gUn1j&;eQtq wN|xHЀ0 8%VF/O+sxk\m و155(}§L421YK['0&UV?FCPqR~Ui33eB@kWϾ!N+CΓNh ;|jc`eޯNG3iÜi>e{"*jq5U'\L5X'(L߶k<"6bʧH֬ٱJF^.c{Ǫ`E+M7eHcRED{ H K7 @Ѝ!Umhd7OL m - 7+0C>k4zEw~Ő7#U.Ah:|_wwYe}݁ldhCn]2$hW L@:RRb-x9ۦX|ib*&׊O ;g˧$ ܸQПGq9lڏX7d>6`J)c3v q \=<[zyIٓvXsj\ʗeLgt ײ (8%dE"_D dz1W~<= =sRֳO&JPEJiؼ 1m&m< B5c"_;Ӏ)͜#=s6|hHUXք[_Tk/S$ְ1[F{_o#eV~?kgJͩAtM'nD/<6wVMS)C1P]ZXzm\Ii{4蝝+ŧ;Iѽ8"\Spp Uj.2#H^ `:GuE;5gENM 3Aig2<3Qk!ܓ1k5ZG(iݪf|0r( 9SؚYuho<]6ӺgtսLn?CzwR!VtY@)!(Z-,=)PYgkO6$s6ΑWDb9ՙdvRXSuRTX:яdu;h+( OI@僽ɭLS8>ٲonB/#7;u`> ⻺[9ӽzp';G[Z"YJeBs_4f2h].[URV.P sI:  9b#zH/tgU5'ABu>8RV[,}7N$_tHĪ[wZxALu E"F  ҹ8N&x_C͋Ju/:͊>bnS0}dGg_ώ` kM*wkJ6. dVdE' ){Ew?)70'Gҭ'zA-f?6VQȃ~SW)&j-aE7ɶW!LY.M]LXܳjNnsER:'7OE\^zYv0(1ު7nhF~~Op齥)D¦Ϛ&JRc?svy+;O/Qp*X<5di0)!qZVrs,ˌb#[tZu/7JEgx!I3d MdHItdBr%Qi'跿GD ;Al{oZu]'|\SH4Mזր:}'U) FGԤSΤXccJʅod 2QF&&aty%&<-2c@e&'A\<Έ_j5ׂ(i:6Q^4wlV_f!Kf{}a(樗ݞ7#EUuJe҄7q`UhQ~%34-ObMӥm;CK{< Eh 8LZ,b^_9sd@9xSkmH q݈5D7nC_7bVo4hypd$M`/`>`rDȩP=P3v{s0'[3.]Pu:ڸ9lԝ3{;h"n.!#ج*;e=F~"Wmi{%QLSeݓa~K2`yV#ME~=) JwR;`tBnkf5*,K=as6 OӮҞDP*XBOhEXVEW!0R,zϞ]}0},9FPzx=H~Z Ty}|(-k|*EY GWJ=bu:wekr",F.%~~Dh+kLʹϬyǺzFUzk{lEG6&`9?}#؇Oׁ'Q; ǰɰ0% 븨ȣAmAe 6o͔49yfryot dh2sKi@5ۂ2#)_JO"'_;Ӊ׉,QIC)>,ίRfhR%'o3Aǩm|r/(?F} D"g4ōl_pQh-ȣ9I}z=T -ן˲FVȺ5WI?IH8ƶdh@X8T& E.G=Fv*@NAubWĻkŔ A~nsj=u7S?aP>`FCOMr:nծ+VGr>(<2l. _?^*٘XCδ=# '~DJNnr9:$^x ¡!Vse3P3I$Z`,SF6TVT2gmK24^cG \$i '#'%.D!FȶdN5=\mz_/]qNsOj. \Vq{j2(mKU`=`I?ސ]^kr0'we L=L^QwHnroKƔs7d=o nZ}-KYf43 xM)`2iI-mqFYQ i󭮚eЅ:1J&6V4ܖQExƪcWas WQx޺n]Mg%՗9 nOR=ŗ1K=󭀦EG{1O=fw!QzS-8]:(,G0[Y&uyǪ"ofH-]y F1qڧD}-5Xa;/ Β,)iy+ yCA\êBEhvq gNn@:bU+s38|^ mGP.4hX6v{qv*$62Q $JO@Յflk9ձL<[iT|Cԛb2nOLʦVF[}{G5f˱f}zhyxܢDZ '1"hL} ))^ ˟Y s,k:#V1`V0J-yr*raqa '0&w?1e m9/sE)I)?m0 wJ-%;WЧvV%T%˟ӟ} Dw3q KkJcud|F"~H'I˕٪1WbqCu,=iW],:R~+o0`/~|OIZmZct*gwޮ;,*e#;3.-eDg?3 ,a/gxY]-;Qa9l{\ .\Mz*Nkrah1WMAQ؉X޷3p^jBe"pWj; z70ytPw9C}+e3E%Q( "C&3[~BtسE0/H^_tv>OGhLzNGۚ%ڞu-NK_@0H@L @G5L0g*VV9zaa WS7$d}OsH:JD1fV$Av 8v[ QED״释ڀL`m.Lj`oܷӅzr+'-T qtiUŽw-o-Vf'2xض $DXg#݆Y@urKO@xuĿQrd0t:cxfAgU.JcO)-aYP d 4VRE󷫢qC`H ǻdp֍Pgj8} c*29X:Tkru S+꧴¦, 7pt{Wt\lBQh>H⁩QUo0,t)^p(Z#Y.̨3PxgL!9Q'̀34\o<` R/|< _j3Iĕ03UAs=F6㖥Y:[B: :r~5.Il';ȰgF6MĭV@ m;#'w4P lXbE͹蘬tou.õh\⋞!FSJJN6qƒwp)6NꞴd/$OR]|=p8MtTISj}K5rH+[D1MF24|Wت>z3+\Da~(7.%i_7@h"]$=Lb_nD0TGMABf$Z';L[7@7'6,5bN!0r 5@~hks6n6D#dĔto^g<"u$Z cvm$ϸ ›h*|XdKmpپ&YT98RyB F1YJȖ K(zO^zRwK;@mю\@}VHhZF9g3&ØXiwąDubY'2E2P{tpEu"UΩsFk_%:H]Y>2{R2kR+!3mi%1N{=BW'*_OY{+F\1vOn8!MYp ~E F[6E0bn3C ĘG5eП1=w1j3l%}1mc4GUT>(\P"@ʺmKxaAe/1(k'Ԣ?r^Hetj&W8&P>۔_|)Y;YƦH*ttTԬ-O_EK0h2ڻ1MdIE@$@R\XQ]W-X+\{-;fsgnj2.[J:T?VKfM\/^AnS Iw4E ?WkxDhf7cؔw%p9F*]01f9gĄd *?c |\r1$Sz: d+G.V91 ۄwltA@$rޏ୒&8{2!҅"d~kDX |Y?@]f7g N>Fn^Zٺ+BDOƮUB33 ͡1͂ʣC?\BǷy& \G^^ ?/W9%rc}w*yb&9l"T. C-Sw_B<(ab7FE;R.-+̲'n<-W 8xiY8M[<UX+Sd&:Q#Ɛ8\F8%HٱXdR ""ORU/R|v6mqnv8SbS 4pkmXr_ǢCNǜ jpfKmK)wHD 9(/DZӊSx,hX],COs)/v\2R Ahƻ40Nj1$)&I?2"acTAgԌ1׭)?mk}#,oi/hf}Jya&7\D @}{<6@:UYC@e8@~fTwt$Å VyXD5IpÚzk#)W @3jSA #RLW|J+[kH$e.wѯqʹΡdp&jd0B:NTZ30$m6W zֹ"(vaĿz.|;!& aFweg־,6M!L\8]fԹ;-F  nT _c:Gl?}\\~{+,vQ//W=3OtEa0XnCĘmr SEB}#cKBU20?l6 y-MtF8Gٚ`~<r("ÿ3CxYߥBXtZ]߄3zhuf2~r١*{;=[KŌvb3ZL3 "q R.űeDAyƳx<14o\u-5U4H_X^!p$G!ã^'-j0܃ TZ&)h(G(2F߆v[]J:[cWw!7e~f'hhH]ICvB/ :䷛Hv 9Lτ AVqwQ鍵l6YO &^IU̐VP"n=j$ql.i+L\BReU)ꮛj[es:Cs Pl%eg,TTfQF*~rF\K̲ s4^ʺI͵FBDA޶qIMnfO=58akD[Ql 2l<,>y ݄wA`Ks1'Uxo鴢0.(-Yd/|VUD3\'г2k@b艏!ձ,}P=KO6[IRaHƈKcԜ7HGXagjhvQbt0i-mMё~yB5}sS`2?nY?nJnfs~Wun6S IPaml>Ij~JCO*\1F?a՜,&o]ҕrŬ.لiI)i\]Wض2$Se4{*aoXG3'FZNy:W3fNw+5d\kM216QI7£>L@|=|g:.K8JxM D59,_E&vA)I| l_"U@LpZ(9-HGFL9BuJ܁]|7%4`Z_wvR,nT:NN܏c*=D=t%OexLSs-}z ]_:ʪAG]*ѧBނYI5/~a&F|:B+v$lX|ɜ8dT *!G\-`3kf=3KʫtD]RS-2-5 AdN}"{6^Žz;GR41h>R#gBGhyJ`ZŸ3l0VF:({ aG*zM}&ij`Na@yʶmjoWSP K^p$(vE猛н ]q6vr>70ֳ)S`g/S.M@q%>WoAOsծtrgqGPMCJNM;UDLnǙ+4$ gבmƺn*?UCXRV一 ,hCa,0QPL K,eV/{@XMG)|&װGc+`ōhQ:&O_Nyt dM`;5 Ty_X #r$][#$f|YKzW I( 5rڪνÚ,l4w|Ơm E~Nt}mm v~_oPWR/x'BiOͿm~ZD_UCm}ӿoQ[7+۾?ӷm}Iޠ?oGX?n7~KT;s~J<ݪ-uFQ3cwp }tkMvA0)+8̆*XXo!U[ʏg!Zf`up3e5'_;{w T#Qm`_5N"CŠΏCx<7Lp12p ޥ.f\E=G @&z#Z+gpl@}\+^Ô[K0Gb2;]oA.sQ[]M~FT Gӣnn5=p#):uԗϑg2\h$Uq^Ch?y8 h>{\(_0 O@k^ $6 qREwP"ljm/AUD>)ρ4([ݫv]dPh?чQ4U]Hw `r$a$ŷ^+k @)`_yrI@kBY9&(P$Ư]V{]UL+C2[(p}f|tV ,YwVpܿog)3ms*:HeEYu`E]3{xk %ǃ}];ϒG8g]J6ZVNv~n1nJCJ}@RAyX !k)xA}"U@d'+ڬ 0]5xh+ \6>`(]nʓXp(/SS@B!YSKΊEf%Eo_ˇUnY`U_Exx|#VZ'H]F2L"=Ggli$5`I.2d~,*b9@6mV]Ӽ.z1ʃP B'7I5{P0t_N[V2TU[ DѬeD.X,%")P68h?pkh[iu0븭/ۺF@8oĜ-aq԰ASfaX5c8SAf=bHL BI͢iȘv$벚b$,$BgaHK|RgV_Q*H!7?{ 1BVW[+ iS " yxL&"hVQK!($J^4@ZmGTQ] mpbsp@IC|0| 8x׊գstvGn6h)Ȅg] 0'[_>SU)}&/b]TZe) UV XNn-z4~؇nh(M+FR(%'ic; Z 5o8$qȴ+W'oTOL㢭J$&#A ["~Adp5IwN"X^Β q>~$.lFА/5ukj 3eWͲ Uq CoM̗+ ,$C,AU+z_Ћ1/* RosЦ o$lb$PȅgE"c7Q Џ4Fj~6/$/x IJPe!(,(^^grsthLy3*~_s`֞d,4z5DnA1<,jV`8b7uvt ek (ыY -L!uNNrxf^|9TIBdT 'AǤR8#Ѯ%z$ɯŦI3)/3թJа:^yǕ!.8foA;2ZhY^KzU AcIr^۽ IQasRC-9 yUL [سLko6+`"-0Bbj0M1JNC~JZPlk8)`(-KFHi%bп`JtUK裒hƵ"ΐ?,= gfm^GDFYYrW ">7C)Th&[d7@+z;^v~[g>߶/3I~$Vau,6G%Ѳ3CaWJuP[j΢c=LAE\tۚyLݩkِzbAb}*97*A CCO$j $ͣel\s eLC %`0,iэE 3/@/J@ ӗȶU\V"" _+A}A/M&|# EoNOr:RD͉|4$B*ݠ 1 TS2GeyրTtW[R$'b&M)aԓclw#`JV *%mg̵ ܶS[$ rFi˵/ 3rdL+cA^d P!̀#q́?&Xj1mb3>R"wr#Mygf$m|Cn.0XRsuZ]%t3v 5P +q&<̐w$h1Wx\"gOpt"B K9sfl(].F(k(ˑ:[K 0W֊Œ/Q@ c3DNf[*;e6*ri! ?A7 ͳt: oKv yˮ!IBvS4?G~Qdo].w/8ze?/PiV.i<7{MWpTSmфZX23wKao K5g+xHey3 2{QTKwPʀgD/ڥnt1YY;:eBp?YL0lp땊;b6]R<724y?`xk6 [VH~$8wUÛ~8CFz?s͂)g4ea=sm>MtݜI,&I/N HY>T8s,]FWTVWo4*v]Ov$jM..*oms| Zȇ{.N+y$}-X+?oİD~Iȫ=v!Z]H~! Ԕ~(Wu7n 0 Pf^ĝ0xϓnRb#B\-4knY ]4;CG#) xrh g@ZTc 慦y WZ6fKv]ׅE1ė;  Fڰ%]-:v}Gtx" j=4z$U**KɭrR/;'56YY5hiCb@cQ^>-o9J:o4SEX\!6O]ВRFh&bS};Y{Q` -`tøf٨qYiNF,QW& ,/QR/Dޯ?W> #U 7a{\f ?ԋֆϦ.{N7qcfSʎ#rkqTFYQt)lHqRl )ݤ ]um]=X]'n7yK?ɭjPaC$lGA!zG"1zlg7$ϣaj^t,1 1v1e˨ J$8o[ fbkəo %*Ǐbkp ) &Ue(V FDtU[V?V!^[B9\){v_ =#/}V6Ҩ7I*<פ| GDp1#JBz5,`郼9 bJwt-1!G+L ײ](};EߝPB$b|>VzIպaʼٲӡc^@]*37(YpIGxmjRV,M8cIk ( 8Սj.iyC9y#n.?K*;=IX~2׏hak0^CMjRuؗO dV:KqлS*<&ȍ2cd fiI3?~^,"kjB0GZ婫aQR5a|(ɫX}UOCRc1Xvoe_^ZGjV/Pβ4_J621ܕRr1S'aGtA^P=ʁ:g{2]!}>ScCRUا^Ύev0ݩ5 pOVtW{mG(C(7{ KjKUyl&Yj{t˖YS9 б$ft./Fᄋ\\dw T3WU}7 9up pۼ*jPG\]~k5'2Rvɬ6f+N8.Zj M#zk pN<u=v}eJ<5sfiEK̩R+wY#cP)ZkR ?.ͨx 5JA*bЬ~f͞$o|J~YKPtgh„nYK/'t]L Jj|v%HZ˲1(Ñ8^yWuWRߩ߫RSq7uX$M$p iDvowoIaqePyu(G,݌~]N*[bF#XtFF=}ȫfX40&&zhѐe(uk|7J;{YU|X?aڙrkT҂gz3V͊bdsf#D{e^L]Ӟ;udo5m fjr_Fa.MKk:`fxt@^j'&'$˯6B޷G $\Ʉa?`Z)f?,5)ay'0W1,sJ*ѽ`NJg>*i*Zu۵DN\Gɍ;O%UL9$Oɘbhk[)E.掻0g3h\_c(ܽCuhR/6nK=v߫jo?v{ƨ]+n,UTГ D^/Rޜ6@z\Gלu z j8*2% ŘyQ8@z^pgh8P+]AqY&UrH~3v|_`jy~A,9l~f_{ Ug'fOzM{ɫ2E/ŎRGI=O h rX}@'hTU8$/qyi"I(Gh0qSHHK`{b$4jtw rR]Ff <&S {}EN@Ɠ2Ayπ1.Ys+hI*gmb㭈_;1K3Ŧ(׶Jdgc8gJ> %!SU^b0ɶJQQMb.؈%ұ'߀V澙 CY5V`v.Gv%,A,cټph'1p&gHd^qVwZ%D^ %ii~`4t|Pv}w=3êfb& dRLKI(TOYxK(%\x*|J= q XxVI}#W3h@C:XϼRjNxn}4H(6ȏ##^]^TbFTTj@HƁIPeTA1={#G ϫ.ў$IEwJz}ě^+ǰfht XYnj*W  ]BEG=7l&$Q)ۖLXGS({HQl۷9kX⚫JF2{!xԪB^ᘜ)zQէ(&1h/lfp*?P30V`Ą6Y4|Cuܿ3Ƙx3[`C_“ɶqH'd2?ulmQ.%:?BxLF|..eM!Fv?R.JY+,^%{JCy?Mx5W$Jch֨l@)1,?Ae˚jqZCa ́@Ĥx*e?}9~O;y˨ha=VV+eL3{U`W8oߦEbݣӜ\92ڎ%Z84paTDd7,Ka={ҲPFBHXg~ZpHs "'1ىc( !RWR閆,?{n2߈“|X(-b79šGd@n!q3ۊfKțeV]@۾./{pO8FfPy53ȧj+-a` ?1s)Si1n } |$@}5j_ _ Ē\ M mW+$ʭp46Ja_Y8gDwK6a(:tn֘zsQpn[Y鍠yrRN" &+OEfT=oz޾ 1#MF9٭5b O,&B.t7,kJRap^t9Y~̏ 4R}dN@YJ|I[n9.ڻyq,_R;(L(%&Ech$'y5XΑ e$903lvIP;M0n8DjT3챬AD# 0{g(XV9}blϳ^]%]x^Ɖ8r05/uUBCav4m&dŞ`y%. |Ze͘xIjoa*!t8c)Ț(x( W\q?J0ܓ,,[hZRG&;,%\{sx^XGxoQ|pQU}(C%(Clyk݆ٺ}06׋2{R$@6YJT]7zR32R^-]~pǔnlŨ6O#qQ3}fR:+Ppഢ#3گ3ru}jD$'Y݀j\$ ~FI:7ʹ7{} 7cUk:%_b=;sB(K"U/ٽcsO)rYoTPIݔrۨeg.wRѱ=.o#QH8rWAYs?'n{Z7 l I I#, : dT ]<]c N<* 媱9K&'ȓ n ʷ<"< y~^؞F kHBuLSr֓sZ1~Q/K=0B$shaNٍUoQYJc,Iض8`-B8׾:N  &kL5EMcX-X'Rv9ksnNŇۺE۔/[Hudjgɂk Hv^#PWyYCn^V'b WI6#mrOtGpEKSt D ,xCXhm#˞7cVmdulˁMBN+ߧ#(z[!u4\̀ H4V?1X P19̗ W8֭q7]ϒvbJrZv SZЊ3qa ׋`m y-*6^j-Ϧ I5]W<܂`! (ʗ3}ReI1!xzs?F$mud4 oN Cs=.`ˮU./?2BO>\fu}pPgP|Rnġ5  E%sXmsbgW粖*"Le/Jl9Cl,GF^q{o2RP,lS+520-r.R_p3( g24 i9,.8E%wP} }^ʺvZgJ3/hZv`dF+Wk!u<)-UR$wMD4ƨ1}%MIr#w;4)͎aT)ƶ2w|w|ҢM&{I3 -#Cә|+swzvޜ|*vJ"Վv2˳yz޻4rI|Ŀ?o)~ v孜 yӸRVX(hG7YR䃵OgM\$xgbQiG=Wb !$XC*!a =1:BZ&NFXKEg7bJWT"LOulm 2TgvO7nq L-K|bZ %]g]t(0ePđLKz76(vlZgt L˘SG݈j+hd[wyIcsP?ǛEk0PZ/p 3|m-SZL̻w/-gO-X|Cz*r̩\;+q߾#ضPzwRA2 8;׉<5P ˩+.U}}ý=.VZL(*{;>i|/R1Aa,Z˄6<0CKII AExȀ0,K-cGegH\Wr'\s(P%.zA3%t/ƴ rĮ W Z$PHҶ;s~Ŗ7 Qi*O~:evL֋ sailcut-1.5.0/icons/sailcut.ico000066400000000000000000010554461477005247400164650ustar00rootroot00000000000000 ( F00 %n   F hV( gfffeeteVf7fgfffffffffffef{gYf7afffaassaaMM{;;t((ngfffffffffgfieGg%UeSfl{{ffQQ{<>qfffffgfeImfffYYzzEEkffgfh@c$gg~22fffe+c$foxx~>>iffffe0f_fpw##fffiffyyvv>>hfffgwagf@@wwnfffgeVf{99iiv((fffffFmffooý\\hffd.UehQQmfffgce5fi 44fff] ff[[;;hfffgMfuft##nffh@c$foaapffffg] gfPPžMMfff`ff||}55gfeff(dff~~pfff2fUf|::LLj ffeh1fFfkRRffeoUfhggqfffd=ffz00j ff`ef\\w%%ffegMfff]]y%%fge0f#fpy))fffeQf#ffhr|55OOhhSSfgeVff~~88ffffAeGefffffffhq}55OOjj~~hfffUf~<<}11ffed.c$gHflgefffffffm{00OOmmofgq ffhw%%fffi"i"fFfnfeffffffn}33RRttƺz((feief^^{{qfffmiffgff{))vvƿfemeLf~99~~{00fffeoq hegfqzz66fge0f-fj gg;;nffffffgCq b gceffiGGSSfffh99fffgwfffffv""YYfgeGfvfy,,zzNNv!!gffffeyh6Ue&ffffz''||y##febffddPPhfgfdh,gff}00~~gggWUffddKKqfffggebaUeNfffpnnƳigi'e&ft""UUj fefe&g>ffgCChffgd!ghwwBBlfffgfi'h1fffjXX³~~feĀffjjnffgg9eQffjggk ffkeefu##__v ffffgf2bgfffCC66feoetf^^qqsffffFUfugfsk fejffYYmm|--ffffff#f fifffKKĶ;igi"ffu""z**ffggMbfff;;k ffgffg¸zz::hffggcfg^ffhVVɾzzfggf|..fffeGf>ǹiifgTeof]]v""fefbiffgTT``feq ffBB|++fffe[Ug4ffillffshfu!!xxpfgfxUgEefw!!@@fgf ff}}??gffgfUgmgf|**ïfffgjjj ffeIfefhuux""ffgf7ek EEgffgRbgfgmmξfgffrrKKgfgi"fUgf99ɿͻjff2ef~44GGgfef<e[gf22̾gfe:f<>hffefuu99fgj ff//sfbfffuHHffmefppRRfgWf(fi66fe] ffgg66fhjg%g%fffy''33ffdfgƩӻfffpf|--::ffmaggSSfh6`ffaf2gff77sfg\gEfu{$$fcffii11ffeDfqppfeVffgeoffAefgWW˵igd)efddfe~hfgz$$fgffTTffvffffffUg^ffmyyffm`ggζhfg^fw""tfgwq ff£ǫfgffeeDDgfge0j fff{((GGffeNfz$$BBfg4ff\\nffPfAfuffgTf[[}//ffffi"fffYYrfd8fffgagfVVyy¶ĩgfg/ffuugfc$f55rfff{mgTefpffUhgnhfeLfffffk z((GGfffgdhfjtffmllk fffKmfffKKIIfeyffpp44fh,bfFgmgfffffffiz((NNtt``ffUeyfUU77fdff¸ƼLLgfff(f7ffpk gjcfm гgfff e0eVffffffffq>>kk88ff`fg--ff7efz''fffj q effVVwwfeffpfeGUe+g^ffffffftNNxxoffFgffffgWghfllnffg^d=efz%%ɸufe+bfu33fe~i'g^ffffffk >>vv¯ħgfbffffgwd8fGGTTffff#mffjffffʬccffU] e?fxeffffoHHɺnnfffgffe] fw!!00ffgwUfgffRRvff(fFfNNÜfgch,eofffffsYY00fghmffffgk ffh1d.ff22fffjk gg4hffefxeLcd8fzgfffl LLjfi"gffgf˾<i] gRefffi>>ffdfffzfl fefefk ssfeygEf[[JJfeghfr]]88offffffffg\f-dBffffiII88fflfffKfYY55fgeXghehgf`fuffq ff{{}}[[11j fffffffeof>ffjfi̻Ȩgfd!c$fpͯfgfil ffaff88m fgfggfggff33xxffȀffhhͮfgfiоtffq ] ff--66ffgfƠfgaffBBfemgiͮffff~**ff`mgf77aafe?ef~~igg4e&gl pfe?fsf``ͭfeff88ffjUff>>ffigfgfe[f}fFFȨffq q gg̬ffffLLfgf(f ffBBԷfffffeUffYYfffpfll˫fgffɰddffg/mffWWfegfff7fqqfg/b gm ˪ffff£~~fgd8cfffff{faff[[feffʩffe~ffffAg%ggʬgfejd3mggƭ55fgMg%f--˩feflfggf<gCfopfffKfy""ռff׀efxxfffZfvvggf-f}f77z!!fefqqLLfeefdfwfgeIffffghffwfUfgigf݀`gfffd8fVVmmffq cfjaafgUgff22PPfe[ffffi'fHHFFffgmfFFfgcgfgfրflffe~hf>>z""fgWffѵչggh,i'gl DDfeGd!fff}cf55gfhgEf..nggJf}fEEϰffffg|q f..||ffffв|%%ffsffxfcfff{f|&&}''feIfFf??IIfeg9frfgfZffnfwҶffӀffllffmfff{%%hhƪhfgEmfsFFfeSghfrrĝfgbf fzffffk DDDDfh6fm ffffrifg4ieVfffffx ddʮÛfffiAAfe?ffqfeSg/gwffffp^^ɭiffhʨfgfdf||--fe~b gRefffoddӽIIfg4fgrgidf66NNff`fPfgff}''ff}ffoofe[fhvvfgf `fUgefgHHγffffֻfeffǢffjdeyfff++~((fkffm ff}fĝjgd8eNfffqJJff#ffOOff2gRfvvsfe]gJgfvc$d)fffo~~77f`gffghd8f__55fefzfffffd.degfo{##fefֺfecfFFXXffU`ffy!!gffffd8dggf{$$˫offfgfq f11ffb fxf]]??gfffff7cfff??gfffsfmfl ggi"q fgXXk ffffe0g9gfjffff55fi`ffgfAejfQQFFgfffgfmgfgf//ffffVVfh1`ffgfUfg55ffgff<cffiffffrrffKq fee]fEErrqfffgfq fdffaaͬfffgfeXf fffϷƤ>>fffghg/ff00™ffqfjffdifPf88jjk fffdmefsfg^foÛffqffɫ}}pffgfffnqqfgJft::ffng>f++sfgffeofjб^^ff7fy\\ffUffpfgejfZghӶJJff#f~((ffih6f{$$ppiffg9eQfl 66ff`f00˩gfg%gfQQfffj eefp{##fif88jgfAe+fuήufggEf}fxofff@@rfg\efmmgfffgfKKgfi'fNN,,fgd!gpպrffjmffffe5f]]EEffffzz==ffh;f#ggffeDfkkiifff jgm wwgffPeVf{##ٿffgRfzzffdgfooȣhffiffͬffe`fӵhgf-ifjչl ffjgjffqfnfl feLeyfccsfgwetfPPfg^f}fȤvffk] fhpfgffffqqfgJefҴ22fgflfVVl feVfPfHH]]fh6efPPffUUfgֺifh6ffJJff#efssfffg^fIIȣfgce`fYY66ffffĝfffUffռhhfeffhz""ffjiff7eQf==44ffzfvfoffvofeXefгoge+jf~((gf`f..|%%fgweDf--ĜffffӶfejf??<ffuufe~gCffe]e&feeh gqjgb f ffgJeGffkkffsefh6fgm gfgMeq eftt==fh1`gjfff{fggifU] ghQQfeDgmfZZȣffUfgffe`fLL}&&f`UffhhfeNeSf==˩ffffԷffgEf33ӵfggfͫffph6f}&&ttfgOffĝSSfd.h,fw22ffgfqfh gqfgfffefgnϯfgffvvfej`fjnnfgJg|fhhMMfd)] gh--ff eof[[n fUfgfggafNNfeUff̪ffgTf==feeffչhhfeDeGf33HHff#ffͬ}''fUh6f}&&kfffşfff-fyffffȤffd!grff_ffccfe?fgnBBffffwwz""fUifjiff}fjjffj ghٿfffpf\\ŞffzUfg~~ffZgcfOO]]fg9Uff==fjfUf==wfgfNNgfiffHHff`ff>>ֺfg] gf55ffuf efhffU`gffg4Ueff??????????????~??????????~31?0|>??||?~?>>~?~?>??????|~>??~??x|<?|?~?n>~?~>>>>?>>?>>>>>?>?>?>>>>~?~|||?||||p|x|8|~? ????(0` $r XXƂPPFF{88v&&]cs*iidd܋\\MMz11ws*w..iii֋VV}55tf|;;``~66u`f] UUɨvv݌OOx##$q##SS~AAu!!Fu'';||第EE``hhᣣaaӂEEt!!.|77}oo΄;;WFFTTy,,R@@__kkء񯦦FFq!!F__|00Pmfs P@@ZZnnϨ񿼼LLU~;;iiְVVr""&sECCܐ``OO::u Hfm 88v^^{{LLt""{22pb }66vccɵޅ<<^>>mm̐XX;;zo'`{//]``EEwz..onn؀;;c~55ojjͿJJm[[ǻllljIIr/|!LL{""4rr߹vvچCCc??IIy((9鿿dd~11SvNN??zTTxxڅAAu%UUɿKK<<ŷgg66G55D~~WW~55skkˀ33FDDuū11>UWWMMraaiih FFy77Jqq€w$$+bbpbbxxeeNN77FFFu<>W}}AANmmm}}ҞiiAAzms*XXp DDa77AħooRRVV66Lnn;;d{VV==p~~̴EE]CCgn 3RRzzˉ>>RAAVBBxoo|''!nnUiXX,,.>>w]]gg11SѲ::9==dοdd}**7Ţ<<{??Uɱʫp IIe^^ccFF{22GGsAAVŧIIvyyȝ]]t!LLņ99NN==Oγff{""UGGzޖPP88PPyFFx__jjHH~))Ժ669wyBBxoor8nnOOǢۆ11*}**1u%`GGvϮe5™s>ÛDDOz##,ss~~ęYY{&&HHn›ǡo 5eD<<^^ɩcc|''!{&&uu~))EԹs(x ȩʩSS~] zzʇ66YOOz\\]]++*б淈<?0  D&CC@# 0'8 D?&C/??$( @ z99nnff\\LLkx..H] t''!}}ݣzzÕllFF[`~CCWvvCCHr++NhXXOOGIIziiHHu mnnŮrr q竫jj99-px22HSSnkk}}༶99ZZ촴kk++{))YYΝ}}pp\\r55D55CooûsKK{44SiiхCCAOOdᧄ]]q88N||ôzzuuzz@@[kkòVVGmmyy;;N܋TTp~~CC[ȵJJ0..Ŵeewff}μz2³__yuuRRT}}^^o::>ssqq{{``]kkù{{MMTTgbbxfflŧġv..w>QQavvïkkBBFFB˰נddn00 ߶Աww::Oddn77JǷɶccdzzVVwrr€^^oѧvvWWd˲eeboȮ֛ZZcӽOOaggJGG/̼ffqϴӱiihxx{έެvvull``iieehɥBBfĝ>>ZZ6ζ~++Y``m˩Ā++ |,,)]]ptiih̯XX}ʥkkWW&áտ輑>>)xxMM{ʦo aaY~~uu|CCzdd=ŢǍBBpmmY__KQQ99?nn{ǡÜYY?ո›ҳLL/˨™II#춅{yyrYY_`?(CP   OH_?S(  aasWW5NNܮܫQQ__sggMUoo>Ҹøޥ~~Assd֣g@@m$$~~gg}}^^oo5ŸڬԳᯌʶyIv'' }}Įyyȼ赑Ġ*¥ӼD@@ ̲ͶHëř.. z׽UU ӺͬȪwwffnnh!պz׼s]] ʧWϰdyy;sailcut-1.5.0/icons/sailcut.svg000066400000000000000000000110411477005247400164700ustar00rootroot00000000000000 sailcut-1.5.0/icons/sailcut.xpm000066400000000000000000000200221477005247400164740ustar00rootroot00000000000000/* XPM */ static const char *sailcut_xpm[] = { /* width height ncolors chars_per_pixel */ "32 32 369 2", /* colors */ " c #000000", " . c #7E7EAA", " X c #DFDFE8", " o c #ADADAD", " O c #8A8AB9", " + c #383883", " @ c #9D9DC5", " # c #B8B8C5", " $ c #7B7B9D", " % c #8888B7", " & c #8B8BB0", " * c #9B9BC3", " = c #9E9EBC", " - c #AEAECF", " ; c #4C4C86", " : c #7474A0", " > c #9C9CBA", " , c #4A4A84", " < c #A5A5A5", " 1 c #B0B0BD", " 2 c #40408E", " 3 c #6B6BA1", " 4 c #59598C", " 5 c #CCCCDF", " 6 c #7A7AA9", " 7 c #0D0D73", " 8 c #4D4D94", " 9 c #F2F2F7", " 0 c #9090AE", " q c #6B6B8D", " w c #7878A7", " e c #ABABAE", " r c #363684", " t c #B1B1CB", " y c #B4B4C4", " u c #43438A", " i c #2E2E7C", " p c #9393BE", " a c #6E6E9D", " s c #2C2C7A", " d c #7C7CAE", " f c #8F8FBA", " g c #525292", " h c #9292B3", " j c #55558B", " k c #C8C8DE", " l c #474791", " z c #B5B5BE", " x c #EAEAF2", " c c #ADADCA", " v c #73739B", " b c #5B5B94", " n c #ACACBF", " m c #5A5A89", " M c #6767A3", " N c #F7F7F8", " B c #A5A5C2", " V c #63639F", " C c #7E7E9F", " Z c #7676AB", " A c #9E9EC5", " S c #5F5F9B", " D c #8686AA", " F c #71719C", " G c #E4E4EF", " H c #BDBDCC", " J c #2B2B75", " K c #ABABB7", " L c #7979A7", " P c #6161A0", " I c #9797A0", " U c #4C4C92", " Y c #DFDFE0", " T c #A8A8AA", " R c #333380", " E c #5B5B9A", " W c #B6B6BB", " Q c #595998", " ! c #D9D9DA", " ~ c #C1C1D3", " ^ c #7F7FB0", " / c #D2D2DD", " ( c #707094", " ) c #7D7DAE", " _ c #404086", " ` c #D0D0DB", " ' c #B8B8D4", " ] c #3C3C82", " [ c #272774", " { c #6A6A8E", " } c #62629A", " | c #7575A6", ". c #202077", ".. c #EDEDF4", ".X c #333383", ".o c #CBCBCC", ".O c #7373A4", ".+ c #B3B3C5", ".@ c #5E5E96", ".# c #9999BC", ".$ c #FEFEFE", ".% c #C1C1D6", ".& c #ACACC8", ".* c #FCFCFC", ".= c #FAFAFA", ".- c #8080AA", ".; c #535395", ".: c #F8F8F8", ".> c #7B7BAF", "., c #F6F6F6", ".< c #828298", ".1 c #F4F4F4", ".2 c #9F9FC5", ".3 c #DFDFE6", ".4 c #9595A4", ".5 c #8D8DB0", ".6 c #F2F2F2", ".7 c #B8B8C3", ".8 c #3B3B7A", ".9 c #36367F", ".0 c #D6D6E7", ".q c #D9D9E0", ".w c #9C9CB8", ".e c #ECECEC", ".r c #EAEAEA", ".t c #484880", ".y c #8080AD", ".u c #E8E8E8", ".i c #E6E6E6", ".p c #E4E4E4", ".a c #B7B7CF", ".s c #E2E2E2", ".d c #7878A5", ".f c #F0F0F3", ".g c #A9A9AA", ".h c #DEDEDE", ".j c #9999C2", ".k c #DCDCDC", ".l c #6F6FA6", ".z c #9797C0", ".x c #DADADA", ".c c #D8D8D8", ".v c #ABABC3", ".b c #BBBBD6", ".n c #9696B5", ".m c #59598D", ".M c #44447F", ".N c #D4D4D4", ".B c #6A6A97", ".V c #CFCFD9", ".C c #525290", ".Z c #D2D2D2", ".A c #CACADE", ".S c #D0D0D0", ".D c #CECECE", ".F c #8989B2", ".G c #C9C9D3", ".H c #CCCCCC", ".J c #47478F", ".K c #C7C7D1", ".L c #6F6FA9", ".P c #CACACA", ".I c #B5B5BC", ".U c #C8C8C8", ".Y c #C6C6C6", ".T c #6E6E9E", ".R c #565697", ".E c #7E7EB1", ".W c #C4C4C4", ".Q c #545495", ".! c #9494B6", ".~ c #7C7CAF", ".^ c #C2C2C2", "./ c #A5A5C0", ".( c #C0C0C0", ".) c #D0D0D3", "._ c #63639D", ".` c #9E9EC3", ".' c #BCBCBC", ".] c #BABABA", ".[ c #626292", ".{ c #35357D", ".} c #454590", ".| c #B8B8B8", "X c #484889", "X. c #7070A3", "XX c #C4C4C7", "Xo c #6F6F98", "XO c #B2B2B2", "X+ c #D2D2D8", "X@ c #B0B0B0", "X# c #AEAEAE", "X$ c #646497", "X% c #8F8FAA", "X& c #AAAAAA", "X* c #9F9FBD", "X= c #A8A8A8", "X- c #9D9DBB", "X; c #48488C", "X: c #ADADCE", "X> c #31317C", "X, c #A2A2A2", "X< c #B2B2B5", "X1 c #9A9AAE", "X2 c #2D2D78", "X3 c #A3A3C4", "X4 c #7E7EA3", "X5 c #292974", "X6 c #393987", "X7 c #4C4C93", "X8 c #0A0A70", "X9 c #7272AB", "X0 c #5D5D9D", "Xq c #DDDDDF", "Xw c #5B5B9B", "Xe c #1C1C71", "Xr c #8181B3", "Xt c #7F7FB1", "Xy c #5A5A90", "Xu c #BFBFD2", "Xi c #D5D5D7", "Xp c #000066", "Xa c #404087", "Xs c #73738E", "Xd c #C0C0C9", "Xf c #B9B9CC", "Xg c #4F4F8F", "Xh c #4A4A94", "Xj c #656594", "Xk c #A5A5B5", "Xl c #DADAE9", "Xz c #7878A0", "Xx c #0E0E63", "Xc c #7373A5", "Xv c #9999BD", "Xb c #57579A", "Xn c #000069", "Xm c #9B9BAB", "XM c #29297A", "XN c #F6F6F7", "XB c #F4F4F5", "XV c #000055", "XC c #7878A3", "XZ c #000080", "XA c #7C7C93", "XS c #EEEEEF", "XD c #B4B4C0", "XF c #C1C1DA", "XG c #454588", "XH c #00006C", "XJ c #9898B5", "XK c #BBBBD4", "XL c #6666A5", "XP c #9999AC", "XI c #A6A6C6", "XU c #9191B8", "XY c #6C6C97", "XT c #545490", "XR c #27277B", "XE c #4F4F95", "XW c #8F8FB6", "XQ c #E2E2E3", "X! c #50508C", "X~ c #9090AD", "X^ c #9E9EBE", "X/ c #C4C4D6", "X( c #5A5A99", "X) c #9595BF", "X_ c #585897", "X` c #6E6E9C", "X' c #B1B1B6", "X] c #9191BB", "X[ c #D2D2D3", "X{ c #DDDDEB", "X} c #B8B8CA", "X| c #8B8BB5", "o c #CECECF", "o. c #DCDCE0", "oX c #626290", "oo c #5A5A9C", "oO c #FFFFFF", "o+ c #FDFDFD", "o@ c #6B6BA6", "o# c #FBFBFB", "o$ c #F9F9F9", "o% c #F7F7F7", "o& c #7A7AAE", "o* c #7D7DA7", "o= c #686899", "o- c #F5F5F5", "o; c #515189", "o: c #9191AA", "o> c #61619C", "o, c #F1F1F1", "o< c #8F8FA8", "o1 c #373780", "o2 c #EFEFEF", "o3 c #8D8DA6", "o4 c #787898", "o5 c #202070", "o6 c #EDEDED", "o7 c #33337C", "o8 c #EBEBEB", "o9 c #9696BC", "o0 c #595994", "oq c #E9E9E9", "ow c #E7E7E7", "oe c #6A6A9E", "or c #525297", "ot c #E5E5E5", "oy c #E3E3E3", "ou c #A6A6BB", "oi c #E1E1E1", "op c #242477", "oa c #0F0F69", "os c #5F5F9D", "od c #DFDFDF", "of c #BABABE", "og c #DDDDDD", "oh c #DBDBDB", "oj c #D9D9D9", "ok c #8181B1", "ol c #5F5F89", "oz c #9494BD", "ox c #171774", "oc c #D7D7D7", "ov c #A7A7C9", "ob c #2D2D79", "on c #D5D5D5", "om c #D0D0DA", "oM c #696996", "oN c #848496", "oB c #A4A4BC", "oV c #F1F1F7", "oC c #CFCFCF", "oZ c #626299", "oA c #CACAD4", "oS c #CDCDCD", "oD c #7575A5", "oF c #5D5D9E", "oG c #484890", "oH c #CBCBCB", "oJ c #8E8EA3", "oK c #C9C9C9", "oL c #8181B4", "oP c #C7C7C7", "oI c #8A8A9F", "oU c #E7E7ED", "oY c #C5C5C5", "oT c #C0C0CA", "oR c #7B7BAE", "oE c #C1C1C1", "oW c #7C7CA5", "oQ c #BFBFBF", "o! c #4F4F90", "o~ c #7D7D9C", "o^ c #BDBDBD", "o/ c #B0B0CE", "o( c #4C4C83", "o) c #B7B7B7", "o_ c #D4D4E4", "o` c #D7D7DD", "o' c #B5B5B5", "o] c #555599", "o[ c #B3B3B3", "o{ c #6E6E97", "o} c #16166F", "o| c #BBBBD2", "O c None", /* pixels */ "O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O ", "O O O O O O O O O O O O O O O O O .0O O O O O O O O O O O O O O ", "O O O O O O O O O O O O O O O O .zoO.2O O O O O O O O O O O O O ", "O O O O O O O O O O O O O O O O X{oOX:O O O O O O O O O O O O O ", "O O O O O O O O O O O O O O O *oOoO 'O O O O O O O O O O O O O ", "O O O O O O O O O O O O O O O GoOoO.bO O O O O O O O O O O O O ", "O O O O O O O O O O O O O O AoOoOoOX)O O O O O O O O O O O O O ", "O O O O O O O O O O O O O O xoOoO..orO O O O O O O O O O O O O ", "O O O O O O O O O O O O O .`o#.$ 9.>.jO GO O O O O O O O O O O ", "O O O O O O O O O O O O O oU.:.AO ^oV 8oOo_O O O O O O O O O O ", "O O O O O O O O O O O O o9 cO O .~ 9oOXb.$oOovO O O O O O O O O ", "O O O O O O O O O O O O O O O o/ N.*oOoFo$o+ @o@O O O O O O O O ", "O O O O O O O O O O O O Xv.aXS.1o%o$ 5O .1.fO k -O O O O O O O ", "O O O O O O O O O O O X^oq.eo2o,.1o%Xtoro2 f )o#oO pO O O O O O ", "O O O O O O O O O O .OXQowoq.eo2o,.%o& Z.FO .3.,.=.2.}O O O O O ", "O O O O O O O O O O Hoi.powoq.eX/O XKokO .qo6o,o-O XFO O O O O ", "O O O O O O O O O &.k.hoi.pow BO t.6X].!.p.u.eo|O XNXlO O O O ", "O O O O O O O O O .)oj.koAX-O O ~o6o2X| >odoy `O XI.1.: OO O O ", "O O O O O O O O DXJ.5 LO O X*o.ow.rXuO y.x.vO .yo8o2 XO %O O ", "O O O O O O O O O O o* h.+ogod.sotomO uXd.-O =.s.i.rX3O XBXrO ", "O O O O O O O X$.7oC.Z.Noc.xogodXq 3.#X;O aoTojogoi.VO .&.6ozO ", "O O O O O O O z.P.HoC.Z.Noc.xX+ |O o`O XzoH.S.N.c.KO XWoq /O O ", "O O O O O O o:.WoP.P.HoC.Z.N.wO oD.GXfO .I.YoHoC nO . Y.pXUO O ", "O O O O O XYoQ.^.WoP.P.oou.TO .n !og./O o^oEXkX`O XJocohX}O O O ", "O O O O O X'.'oQofX%X4O O oW #on.cXi wo~XmoMO X`XD.D.ZoBO O O O ", "O O O O .m $XoO O O FX~XXoS.S.ZX[.dO ;O .BXPoEoYoK 0O O O O O ", "O O O O O O o{ Co< W.^oY.U.PoSo XCO O O .4o[o).'X1o=O O O O O O ", "O O O ( eXOo'.|.]o^.(.^oY.U 1 :O O O . /dev/null`" ]; then target="mac" elif [ -n "`which cmd.exe 2> /dev/null`" ]; then target="win32" elif [ "`uname`" = "Linux" ]; then target="linux" fi fi if [ -z "$target" ]; then echo "Unknown target" exit 1 fi echo "Target: $target" # configure MAKE=make QMAKE=qmake case "$target" in mac) export PATH=~/Qt/5.5/clang_64/bin:$PATH ;; win32) export PATH="/c/Qt/5.5/mingw492_32/bin:$PATH" export PATH="/c/Qt/Tools/mingw492_32/bin:$PATH" export PATH="/c/Program Files (x86)/NSIS:$PATH" MAKE=mingw32-make ;; esac rm -rf release-$target mkdir release-$target cd release-$target $QMAKE .. $MAKE $MAKE package sailcut-1.5.0/sailcut.nsi.in000066400000000000000000000060401477005247400157570ustar00rootroot00000000000000!define PRODUCT_NAME "Sailcut CAD" !define PRODUCT_DIR_REGKEY "Software\${PRODUCT_NAME}" Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "${PRODUCT_OUTPUT}" SetCompressor lzma InstallDir "$PROGRAMFILES\${PRODUCT_NAME}" InstallDirRegKey HKCU "${PRODUCT_DIR_REGKEY}" "" !include "MUI.nsh" !define MUI_ABORTWARNING !insertmacro MUI_PAGE_LICENSE "${PRODUCT_LICENSE}" !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES !define MUI_FINISHPAGE_RUN "$INSTDIR\bin\sailcut.exe" !define MUI_FINISHPAGE_LINK "Visit the Sailcut CAD website" !define MUI_FINISHPAGE_LINK_LOCATION "http://www.sailcut.com/" !insertmacro MUI_PAGE_FINISH !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_LANGUAGE "English" RequestExecutionLevel admin Function ConditionalAddToRegisty Pop $0 Pop $1 StrCmp "$0" "" ConditionalAddToRegisty_EmptyString WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\Sailcut CAD" "$1" "$0" ;MessageBox MB_OK "Set Registry: '$1' to '$0'" DetailPrint "Set install registry entry: '$1' to '$0'" ConditionalAddToRegisty_EmptyString: FunctionEnd Section "Sailcut CAD" SecSailcut SectionIn RO SetOutPath "$INSTDIR" WriteRegStr HKCU "${PRODUCT_DIR_REGKEY}" "" $INSTDIR File /r bin File /r share WriteUninstaller "$INSTDIR\uninstall.exe" Push "DisplayIcon" Push "$INSTDIR\bin\sailcut.exe" Call ConditionalAddToRegisty Push "DisplayName" Push "${PRODUCT_NAME}" Call ConditionalAddToRegisty Push "DisplayVersion" Push "${PRODUCT_VERSION}" Call ConditionalAddToRegisty Push "UninstallString" Push "$INSTDIR\uninstall.exe" Call ConditionalAddToRegisty Push "NoRepair" Push "1" Call ConditionalAddToRegisty SectionEnd Section "Start Menu Shortcuts" SecShortcut ;Remove old shortcut folder RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}" CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}.lnk" "$INSTDIR\bin\sailcut.exe" SectionEnd Section "Register File Types" SecFileType WriteRegStr HKCR "SailcutCAD.SailDef" "" "Sailcut CAD Sail definition" WriteRegStr HKCR "SailcutCAD.SailDef\shell\open\command" "" '"$INSTDIR\sailcut.exe" "%1"' WriteRegStr HKCR "SailcutCAD.SailDef\DefaultIcon" "" "$INSTDIR\icons\sailcut-file.ico" WriteRegStr HKCR ".saildef" "" "SailcutCAD.SailDef" SectionEnd !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SecSailcut} "Installs Sailcut CAD." !insertmacro MUI_DESCRIPTION_TEXT ${SecShortcut} "Adds icons to your start menu for easy access." !insertmacro MUI_DESCRIPTION_TEXT ${SecFileType} "Register Sailcut CAD file types." !insertmacro MUI_FUNCTION_DESCRIPTION_END Section "Uninstall" DeleteRegKey HKCR "SailcutCAD.SailDef" DeleteRegKey HKCR ".saildef" DeleteRegKey HKCU "${PRODUCT_DIR_REGKEY}" ;Remove shortcuts Delete "$SMPROGRAMS\${PRODUCT_NAME}.lnk" ;Remove the uninstaller itself. Delete "$INSTDIR\uninstall.exe" DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\Sailcut CAD" ;Remove files RMDir /r "$INSTDIR" SectionEnd sailcut-1.5.0/sailcut.pri000066400000000000000000000011741477005247400153560ustar00rootroot00000000000000SAILCUT_VERSION = 1.5.0 SAILCUT_SOURCE_TREE = $$PWD isEmpty(SAILCUT_BUILD_TREE) { sub_dir = $$_PRO_FILE_PWD_ sub_dir ~= s,^$$re_escape($$PWD),, SAILCUT_BUILD_TREE = $$clean_path($$OUT_PWD) SAILCUT_BUILD_TREE ~= s,$$re_escape($$sub_dir)$,, } BUILD_APP_PATH = $$SAILCUT_BUILD_TREE/bin mac { BUILD_DATA_PATH = "$$BUILD_APP_PATH/Sailcut CAD.app/Contents/Resources" SAILCUT_DATA_PATH = ../Resources } else { BUILD_DATA_PATH = $$SAILCUT_BUILD_TREE/share/sailcut SAILCUT_DATA_PATH = ../share/sailcut } BUILD_DOC_PATH = $$SAILCUT_BUILD_TREE/share/doc/sailcut/html SAILCUT_DOC_PATH = ../share/doc/sailcut/html sailcut-1.5.0/sailcut.pro000066400000000000000000000021621477005247400153620ustar00rootroot00000000000000include(sailcut.pri) TEMPLATE = subdirs SUBDIRS = src tests # Package generation mac { package.depends = first package.output = sailcut-$$SAILCUT_VERSION-mac.dmg package.commands = \ rm -f $$package.output; \ ln -s /Applications $$BUILD_APP_PATH/Applications; \ hdiutil create $$package.output -srcdir $$BUILD_APP_PATH -format UDBZ -volname \"Sailcut CAD $$SAILCUT_VERSION\"; \ rm -f $$BUILD_APP_PATH/Applications QMAKE_EXTRA_TARGETS = package } else:win32 { package.depends = first package.output = sailcut-$$SAILCUT_VERSION-win32.exe package.commands = makensis sailcut.nsi QMAKE_EXTRA_TARGETS = package NSI_HEADER = "!define PRODUCT_VERSION \"$$SAILCUT_VERSION\"" NSI_HEADER += "!define PRODUCT_LICENSE \"$$system_path($$SAILCUT_SOURCE_TREE/LICENSE)\"" NSI_HEADER += "!define PRODUCT_OUTPUT \"$$system_path($$package.output)\"" NSI_BODY = $$cat($$SAILCUT_SOURCE_TREE/sailcut.nsi.in, blob) write_file($$SAILCUT_BUILD_TREE/sailcut.nsi, NSI_HEADER) write_file($$SAILCUT_BUILD_TREE/sailcut.nsi, NSI_BODY, append) QMAKE_CLEAN += sailcut.nsi } sailcut-1.5.0/src/000077500000000000000000000000001477005247400137625ustar00rootroot00000000000000sailcut-1.5.0/src/app.cpp000066400000000000000000000155171477005247400152570ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "app.h" #include #include #include #include #include #include #include #include "formboat.h" #include "formhull.h" #include "formpanelgroup.h" #include "formrig.h" #include "formsail.h" #include "sailwriter-xml.h" /** * Creates an new Sailcut application. * * @param argc * @param argv */ CSailApp::CSailApp(int &argc, char** argv) : QApplication(argc, argv) { // create and install translators transApp = new QTranslator( this ); transQt = new QTranslator( this ); // the file containing the user's preferences prefsfile = QDir::home().filePath(".sailcutrc"); } /** * Creates a new boat and shows it in a new window. */ void CSailApp::createBoat() const { CFormMain *wnd = new CFormBoat; wnd->show(); } /** * Creates a new hull and shows it in a new window. */ void CSailApp::createHull() const { CFormMain *wnd = new CFormHull; wnd->show(); } /** * Creates a new rig and shows it in a new window. */ void CSailApp::createRig() const { CFormMain *wnd = new CFormRig; wnd->show(); } /** * Creates a new sail and shows it in a new window. */ void CSailApp::createSail() const { CFormMain *wnd = new CFormSail; wnd->show(); } /** * Shows the Sailcut CAD Handbook. */ void CSailApp::showHandbook() const { QDir appDir(applicationDirPath()); const QString locale = prefs.language; QStringList locales(locale); if (locale != "en") locales.append("en"); // look for local documentation or fall back to online documentation QUrl url("http://www.sailcut.com/handbook/en/"); for (int i = 0; i < locales.size(); i++) { const QString handbook = appDir.absoluteFilePath(QString(SAILCUT_DOC_PATH) + QDir::separator() + locales.at(i) + QDir::separator() + "index.html"); if (QFile::exists(handbook)) { url = QUrl::fromLocalFile(handbook); break; } } QDesktopServices::openUrl(url); } /** * Returns the preferred language. */ QString CSailApp::language() const { return prefs.language; } /** * Sets the preferred language. */ void CSailApp::setLanguage(const QString &language) { if (language != prefs.language) { prefs.language = language; loadTranslation(language); emit languageChanged(); } } /** * Returns the preferred window size. */ QSize CSailApp::windowSize() const { return QSize(prefs.mainWindowWidth, prefs.mainWindowHeight); } /** * Sets the preferred window size. */ void CSailApp::setWindowSize(const QSize &size) { if (size != windowSize()) { prefs.mainWindowHeight = size.height(); prefs.mainWindowWidth = size.width(); emit windowSizeChanged(); } } /** * Loads translation strings for a given language. */ void CSailApp::loadTranslation(const QString locale) { QDir appDir(applicationDirPath()); // translation file for Qt removeTranslator(transQt); if (transQt->load(QString("qt_") + locale, QLibraryInfo::path(QLibraryInfo::TranslationsPath))) { installTranslator(transQt); } // translation file for application strings removeTranslator(transApp); if (transApp->load(QString("sailcut_") + locale, appDir.absoluteFilePath(SAILCUT_DATA_PATH))) { installTranslator(transApp); } } /** * Opens the specified file in a new window. */ void CSailApp::open(const QString &filename) { CFormMain *wnd; if (CSailDefXmlWriter().isDocument(filename)) { wnd = new CFormSail; } else if (CHullDefXmlWriter().isDocument(filename)) { wnd = new CFormHull; } else if (CBoatDefXmlWriter().isDocument(filename)) { wnd = new CFormBoat; } else if (CRigDefXmlWriter().isDocument(filename)) { wnd = new CFormRig; } else if (CPanelGroupXmlWriter().isDocument(filename)) { wnd = new CFormPanelGroup; } else { //statusbar->showMessage( tr("unknown document type '%1'").arg(filename) ); return; } if (wnd->load(filename)) wnd->show(); else wnd->deleteLater(); } QStringList CSailApp::recentDocuments() const { QStringList documents; for (unsigned int i = 0; i < prefs.mruDocuments.size(); ++i) documents.push_back(prefs.mruDocuments[i]); return documents; } /** * Puts an entry at the top of the Most Recently Used files. * * @param filename The entry to be added */ void CSailApp::addRecentDocument(const QString &filename) { std::vector &mru = prefs.mruDocuments; removeRecentDocument(filename); mru.insert(mru.begin(), filename); // limit the number of entries if (mru.size() > 9) mru.resize(9); emit recentDocumentsChanged(); } /** * Removes an entry from the Most Recently Used files. * * @param filename The entry to be removed */ void CSailApp::removeRecentDocument(const QString &filename) { std::vector &mru = prefs.mruDocuments; std::vector::iterator it = std::find(mru.begin(), mru.end(), filename); if (it != mru.end()) { mru.erase(it); emit recentDocumentsChanged(); } } /** * Try to read the user's preferences */ void CSailApp::readPrefs() { try { if (QFile(prefsfile).exists()) { CPrefs newPrefs = CPrefsXmlWriter().read(prefsfile); setLanguage(newPrefs.language); if (newPrefs.mruDocuments != prefs.mruDocuments) { prefs.mruDocuments = newPrefs.mruDocuments; emit recentDocumentsChanged(); } setWindowSize(QSize(newPrefs.mainWindowWidth, newPrefs.mainWindowHeight)); } } catch (read_error const&) { std::cout << "CSailApp::readPrefs : could not read preferences" << std::endl; } } /** * Try to write the user's preferences. */ void CSailApp::writePrefs() { try { CPrefsXmlWriter().write(prefs, prefsfile); } catch (write_error const&) { std::cout << "CSailApp::writePrefs : could not write preferences" << std::endl; } } sailcut-1.5.0/src/app.h000066400000000000000000000045011477005247400147130ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILCUTQT_H #define SAILCUTQT_H #include #include "prefs.h" class QTranslator; class QUrl; /** * Class representing a Sailcut application. */ class CSailApp : public QApplication { Q_OBJECT Q_PROPERTY(QString language READ language WRITE setLanguage NOTIFY languageChanged) Q_PROPERTY(QStringList recentDocuments READ recentDocuments NOTIFY recentDocumentsChanged) Q_PROPERTY(QSize windowSize READ windowSize WRITE setWindowSize NOTIFY windowSizeChanged) public: CSailApp(int &argc, char** argv); void readPrefs(); void writePrefs(); QString language() const; void setLanguage(const QString &language); QStringList recentDocuments() const; void addRecentDocument(const QString &filename); void removeRecentDocument(const QString &filename); QSize windowSize() const; void setWindowSize(const QSize &size); public slots: void createBoat() const; void createHull() const; void createRig() const; void createSail() const; void open(const QString &filename); void showHandbook() const; signals: void languageChanged(); void recentDocumentsChanged(); void windowSizeChanged(); private: void loadTranslation(const QString locale); /** the user's preferences */ CPrefs prefs; /** the file in which the preferences are stored */ QString prefsfile; /** translator for Qt's messages */ QTranslator *transQt; /** transator for Sailcut's messages */ QTranslator *transApp; }; #endif sailcut-1.5.0/src/boatdef-panel.cpp000066400000000000000000000175301477005247400171750ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "boatdef-panel.h" #include "sailwriter-xml.h" #include "sailcpp/hullworker.h" #include "sailcpp/rigworker.h" #include "sailcpp/sailworker.h" #include #include #include #include #include #include #include #include /** The constructor for a CVector3dWidget. * * @param parent the parent widget */ CVector3dWidget::CVector3dWidget(QWidget *parent) : QWidget(parent) { for (int i = 0; i < 3; i++) { QSpinBox *spin = new QSpinBox(this); spin->setRange(-10000, 10000); spin->setSingleStep(10); spinBox.push_back(spin); } QLabel *lblStaticX = new QLabel(this); lblStaticX->setText("x"); QLabel *lblStaticY = new QLabel(this); lblStaticY->setText("y"); QLabel *lblStaticZ = new QLabel(this); lblStaticZ->setText("z"); QHBoxLayout* layout = new QHBoxLayout(this); layout->addWidget(lblStaticX); layout->addWidget(spinBox[0], 1); layout->addWidget(lblStaticY); layout->addWidget(spinBox[1], 1); layout->addWidget(lblStaticZ); layout->addWidget(spinBox[2], 1); } /** Returns the vector corresponding to the user's input. */ CVector3d CVector3dWidget::getVector() { CVector3d v; for (int i = 0; i < 3; i++) v[i] = spinBox[i]->value(); return v; } /** Set the input boxes from a given vector. * * @param v the new vector to display */ void CVector3dWidget::setVector(const CVector3d &v) { for (unsigned int i = 0; i < 3; i++) spinBox[i]->setValue(int(v[i])); } /** The constructor. * * @param parent the parent widget */ CBoatElementWidget::CBoatElementWidget(QWidget *parent) : QWidget(parent) { grpInfo = new QGroupBox( 0 ); QGridLayout* iLayout = new QGridLayout( grpInfo ); lblFileStatic = new QLabel( grpInfo ); iLayout->addWidget( lblFileStatic, 0, 0 ); lblFile = new QLabel( grpInfo ); iLayout->addWidget( lblFile, 0, 1 ); lblNameStatic = new QLabel( grpInfo ); iLayout->addWidget( lblNameStatic, 1, 0 ); txtName = new QLineEdit( grpInfo ); iLayout->addWidget( txtName, 1, 1 ); btnReload = new QPushButton(grpInfo); iLayout->addWidget( btnReload, 2, 1); wdgOrigin = new CVector3dWidget(grpInfo); iLayout->addWidget(wdgOrigin, 3, 0, 1, 3); //iLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ), 4, 1 ); // add button below frame btnUpdate = new QPushButton(this); btnRemove = new QPushButton(this); QGridLayout* layout = new QGridLayout(this); layout->addWidget(grpInfo, 0, 0, 1, 3); layout->addWidget(btnRemove, 1, 0); layout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 1, 1 ); layout->addWidget(btnUpdate, 1, 2); // pack everything upward layout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ), 2, 0 ); // set language connect(qApp, SIGNAL(languageChanged()), this, SLOT(languageChange())); languageChange(); /* connect signals */ connect( btnUpdate, SIGNAL( clicked() ), this, SLOT(slotUpdate()) ); connect( btnReload, SIGNAL( clicked() ), this, SLOT(slotReload()) ); connect( btnRemove, SIGNAL( clicked() ), this, SLOT(slotRemove()) ); } /** * Sets the strings of the subwidgets using the current language. */ void CBoatElementWidget::languageChange() { grpInfo->setTitle( tr( "Element information" ) ); lblFileStatic->setText( tr("file") ); lblNameStatic->setText( tr("name") ); btnReload->setText( tr("Reload") ); btnRemove->setText( tr("Remove") ); btnUpdate->setText( tr("Update") ); } /** * The boat element changed, update widgets. * * @param newelement The new value of the boat element */ void CBoatElementWidget::setElement(const CBoatElement& newelement) { element = newelement; lblFile->setText( QString::fromStdString(element.filename) ); txtName->setText( QString::fromStdString(element.title) ); wdgOrigin->setVector( element.origin ); } /** * The "reload" button was pressed, fire signalUpdate. */ void CBoatElementWidget::slotReload() { QString filename = QString::fromStdString(element.filename); try { switch (element.type) { case SAILDEF: (CPanelGroup&)element = CSailWorker(CSailDefXmlWriter().read(filename)).makeSail(); break; case HULLDEF: (CPanelGroup&)element = CHullWorker(CHullDefXmlWriter().read(filename)).makeHull(); break; case RIGDEF: (CPanelGroup&)element = CRigWorker(CRigDefXmlWriter().read(filename)).makeRig(); break; case PANELGROUP: (CPanelGroup&)element = CPanelGroupXmlWriter().read(filename); break; } signalUpdate(element); } catch (read_error const&) { CSailDefXmlWriter::readErrorMessage(); } } /** * The "remove" button was pressed, fire signalRemove. */ void CBoatElementWidget::slotRemove() { signalRemove(); } /** * The "update" button was pressed, fire signalUpdate. */ void CBoatElementWidget::slotUpdate() { element.title = txtName->text().toStdString(); element.origin = wdgOrigin->getVector(); signalUpdate(element); } /** * The constructor. * * @param parent the parent widget */ CBoatDefPanel::CBoatDefPanel(QWidget *parent) : QWidget(parent) { QGridLayout *layout = new QGridLayout( this ); tabs = new QTabWidget(this); layout->addWidget( tabs, 0, 0); } /** * We were passed a new boat definition, update the widgets. * * @param newdef The new boat definition */ void CBoatDefPanel::setDef(const CBoatDef& newdef) { unsigned int i; for (i = 0; i < elementwidget.size(); i++) { tabs->removeTab(i); delete elementwidget[i]; } def = newdef; elementwidget.resize(def.size()); for (i = 0; i < def.size(); i++) { elementwidget[i] = new CBoatElementWidget(0); elementwidget[i]->setElement(def[i]); connect(elementwidget[i], SIGNAL(signalRemove()), this, SLOT(slotRemove())); connect(elementwidget[i], SIGNAL(signalUpdate(const CBoatElement&)), this, SLOT(slotUpdate(const CBoatElement&))); tabs->addTab(elementwidget[i], QString::fromStdString(def[i].title)); } if (elementwidget.size() > 0) tabs->setCurrentIndex(0); } /** * The user requested the removal of the current boat element. */ void CBoatDefPanel::slotRemove() { int tabIndex = tabs->currentIndex(); tabs->removeTab(tabIndex); delete elementwidget[tabIndex]; elementwidget.erase(elementwidget.begin()+tabIndex); def.erase(def.begin()+tabIndex); signalUpdate(def); } /** * The user updated the current boat element. * * @param newelement The new boat element */ void CBoatDefPanel::slotUpdate(const CBoatElement& newelement) { int tabIndex = tabs->currentIndex(); def[tabIndex] = newelement; tabs->setTabText(tabIndex, QString::fromStdString(def[tabIndex].title)); signalUpdate(def); } sailcut-1.5.0/src/boatdef-panel.h000066400000000000000000000064011477005247400166350ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef BOATDEF_PANEL_H #define BOATDEF_PANEL_H #include "sailcpp/boatdef.h" #include class QGroupBox; class QTabWidget; class QLabel; class QLineEdit; class QPushButton; class QSpinBox; /** * A widget for displaying info about a CVector3d. */ class CVector3dWidget : public QWidget { Q_OBJECT public: CVector3dWidget(QWidget *parent); CVector3d getVector(); void setVector(const CVector3d &v); protected: /** The spin boxes. */ std::vector spinBox; }; /** A widget for displaying information about a boat element. */ class CBoatElementWidget : public QWidget { Q_OBJECT public: CBoatElementWidget(QWidget *parent); void setElement(const CBoatElement &newelement); signals: /** Signals that the user hit the "Remove" button. */ void signalRemove(); /** Signals that the element was modified. */ void signalUpdate(const CBoatElement& newelement); private slots: void languageChange(); protected slots: void slotReload(); void slotRemove(); void slotUpdate(); protected: /** the boat element we are operating on */ CBoatElement element; /** groupbox for the element info */ QGroupBox* grpInfo; /** label for the filename */ QLabel* lblFile; /** label for the element name */ QLineEdit* txtName; /** static label saying "file" */ QLabel* lblFileStatic; /** static label saying "name" */ QLabel* lblNameStatic; /** widget for the origin */ CVector3dWidget *wdgOrigin; /** button to accept changes to the CBoatElement */ QPushButton *btnUpdate; /** button to reload this element from file */ QPushButton *btnReload; /** button to remove this CBoatElement */ QPushButton *btnRemove; }; /** A panel displaying one tab per element of a given * boat definition. */ class CBoatDefPanel : public QWidget { Q_OBJECT public: CBoatDefPanel(QWidget *parent); void setDef(const CBoatDef &newdef); public slots: virtual void slotRemove(); virtual void slotUpdate(const CBoatElement& newelement); signals: /** Signals that the boat definition was modified. */ void signalUpdate(const CBoatDef& newdef); protected: /** the tabbed widget, with one tab per boat element */ QTabWidget *tabs; /** the widgets for the boat element parameters */ std::vector elementwidget; /** the boat definition we are operating one */ CBoatDef def; }; #endif sailcut-1.5.0/src/examples/000077500000000000000000000000001477005247400156005ustar00rootroot00000000000000sailcut-1.5.0/src/examples/Star45-JIB.dxf000066400000000000000000001125071477005247400177750ustar00rootroot00000000000000999 DXF created by Sailcut CAD 0 SECTION 2 HEADER 0 ENDSEC 0 SECTION 2 TABLES 0 TABLE 2 LAYER 70 6 0 LAYER 2 1 70 64 62 4 6 CONTINUOUS 0 LAYER 2 2 70 64 62 2 6 CONTINUOUS 0 LAYER 2 3 70 64 62 4 6 CONTINUOUS 0 LAYER 2 4 70 64 62 2 6 CONTINUOUS 0 LAYER 2 5 70 64 62 4 6 CONTINUOUS 0 ENDTAB 0 ENDSEC 0 SECTION 2 ENTITIES 0 3DFACE 8 1 10 227.296 20 162.802 30 1.25297e-10 11 196.667 21 60 31 0 12 206.816 22 94.2638 32 1.57692e-11 13 206.816 23 94.2638 33 1.57692e-11 0 3DFACE 8 1 10 227.296 20 162.802 30 1.25297e-10 11 206.816 21 94.2638 31 1.57692e-11 12 216.989 22 128.529 32 1.33438e-11 13 216.989 23 128.529 33 1.33438e-11 0 3DFACE 8 1 10 227.296 20 162.802 30 1.25297e-10 11 216.989 21 128.529 31 1.33438e-11 12 227.187 22 162.796 32 6.79915e-11 13 227.187 23 162.796 33 6.79915e-11 0 3DFACE 8 1 10 227.296 20 162.802 30 1.25297e-10 11 227.187 21 162.796 31 6.79915e-11 12 237.409 22 197.064 32 1.33544e-10 13 237.409 23 197.064 33 1.33544e-10 0 3DFACE 8 1 10 227.296 20 162.802 30 1.25297e-10 11 237.409 21 197.064 31 1.33544e-10 12 247.655 22 231.333 32 1.97649e-10 13 247.655 23 231.333 33 1.97649e-10 0 3DFACE 8 1 10 227.296 20 162.802 30 1.25297e-10 11 247.655 21 231.333 31 1.97649e-10 12 257.926 22 265.605 32 2.50594e-10 13 257.926 23 265.605 33 2.50594e-10 0 3DFACE 8 1 10 257.926 20 265.605 30 2.50594e-10 11 196.667 21 60 31 0 12 272.768 22 266.51 32 3.67824 13 272.768 23 266.51 33 3.67824 0 3DFACE 8 1 10 272.768 20 266.51 30 3.67824 11 214.868 21 60.8552 31 2.57587 12 196.667 22 60 32 0 13 196.667 23 60 33 0 0 3DFACE 8 1 10 272.768 20 266.51 30 3.67824 11 214.868 21 60.8552 31 2.57587 12 287.634 22 267.416 32 6.8339 13 287.634 23 267.416 33 6.8339 0 3DFACE 8 1 10 287.634 20 267.416 30 6.8339 11 233.07 21 61.9572 31 4.75575 12 214.868 22 60.8552 32 2.57587 13 214.868 23 60.8552 33 2.57587 0 3DFACE 8 1 10 287.634 20 267.416 30 6.8339 11 233.07 21 61.9572 31 4.75575 12 302.521 22 268.321 32 9.50799 13 302.521 23 268.321 33 9.50799 0 3DFACE 8 1 10 302.521 20 268.321 30 9.50799 11 251.272 21 63.3078 31 6.56238 12 233.07 22 61.9572 32 4.75575 13 233.07 23 61.9572 33 4.75575 0 3DFACE 8 1 10 302.521 20 268.321 30 9.50799 11 251.272 21 63.3078 31 6.56238 12 317.428 22 269.227 32 11.7409 13 317.428 23 269.227 33 11.7409 0 3DFACE 8 1 10 317.428 20 269.227 30 11.7409 11 269.473 21 64.9088 31 8.01779 12 251.272 22 63.3078 32 6.56238 13 251.272 23 63.3078 33 6.56238 0 3DFACE 8 1 10 317.428 20 269.227 30 11.7409 11 269.473 21 64.9088 31 8.01779 12 332.353 22 270.133 32 13.5723 13 332.353 23 270.133 33 13.5723 0 3DFACE 8 1 10 332.353 20 270.133 30 13.5723 11 287.675 21 66.7622 31 9.14343 12 269.473 22 64.9088 32 8.01779 13 269.473 23 64.9088 33 8.01779 0 3DFACE 8 1 10 332.353 20 270.133 30 13.5723 11 287.675 21 66.7622 31 9.14343 12 347.295 22 271.038 32 15.0409 13 347.295 23 271.038 33 15.0409 0 3DFACE 8 1 10 347.295 20 271.038 30 15.0409 11 305.876 21 68.8698 31 9.96018 12 287.675 22 66.7622 32 9.14343 13 287.675 23 66.7622 33 9.14343 0 3DFACE 8 1 10 347.295 20 271.038 30 15.0409 11 305.876 21 68.8698 31 9.96018 12 362.253 22 271.944 32 16.1844 13 362.253 23 271.944 33 16.1844 0 3DFACE 8 1 10 362.253 20 271.944 30 16.1844 11 324.078 21 71.2335 31 10.4885 12 305.876 22 68.8698 32 9.96018 13 305.876 23 68.8698 33 9.96018 0 3DFACE 8 1 10 362.253 20 271.944 30 16.1844 11 324.078 21 71.2335 31 10.4885 12 377.225 22 272.849 32 17.0393 13 377.225 23 272.849 33 17.0393 0 3DFACE 8 1 10 377.225 20 272.849 30 17.0393 11 342.28 21 73.8553 31 10.7483 12 324.078 22 71.2335 32 10.4885 13 324.078 23 71.2335 33 10.4885 0 3DFACE 8 1 10 377.225 20 272.849 30 17.0393 11 342.28 21 73.8553 31 10.7483 12 392.209 22 273.755 32 17.6405 13 392.209 23 273.755 33 17.6405 0 3DFACE 8 1 10 392.209 20 273.755 30 17.6405 11 360.481 21 76.737 31 10.7594 12 342.28 22 73.8553 32 10.7483 13 342.28 23 73.8553 33 10.7483 0 3DFACE 8 1 10 392.209 20 273.755 30 17.6405 11 360.481 21 76.737 31 10.7594 12 407.204 22 274.661 32 18.0215 13 407.204 23 274.661 33 18.0215 0 3DFACE 8 1 10 407.204 20 274.661 30 18.0215 11 378.683 21 79.8808 31 10.5413 12 360.481 22 76.737 32 10.7594 13 360.481 23 76.737 33 10.7594 0 3DFACE 8 1 10 407.204 20 274.661 30 18.0215 11 378.683 21 79.8808 31 10.5413 12 422.209 22 275.566 32 18.2139 13 422.209 23 275.566 33 18.2139 0 3DFACE 8 1 10 422.209 20 275.566 30 18.2139 11 396.885 21 83.2886 31 10.1131 12 378.683 22 79.8808 32 10.5413 13 378.683 23 79.8808 33 10.5413 0 3DFACE 8 1 10 422.209 20 275.566 30 18.2139 11 396.885 21 83.2886 31 10.1131 12 437.222 22 276.472 32 18.2475 13 437.222 23 276.472 33 18.2475 0 3DFACE 8 1 10 437.222 20 276.472 30 18.2475 11 415.086 21 86.9624 31 9.49399 12 396.885 22 83.2886 32 10.1131 13 396.885 23 83.2886 33 10.1131 0 3DFACE 8 1 10 437.222 20 276.472 30 18.2475 11 415.086 21 86.9624 31 9.49399 12 452.242 22 277.377 32 18.1495 13 452.242 23 277.377 33 18.1495 0 3DFACE 8 1 10 452.242 20 277.377 30 18.1495 11 433.288 21 90.9043 31 8.70317 12 415.086 22 86.9624 32 9.49399 13 415.086 23 86.9624 33 9.49399 0 3DFACE 8 1 10 452.242 20 277.377 30 18.1495 11 433.288 21 90.9043 31 8.70317 12 467.269 22 278.283 32 17.9451 13 467.269 23 278.283 33 17.9451 0 3DFACE 8 1 10 467.269 20 278.283 30 17.9451 11 451.489 21 95.1164 31 7.75979 12 433.288 22 90.9043 32 8.70317 13 433.288 23 90.9043 33 8.70317 0 3DFACE 8 1 10 467.269 20 278.283 30 17.9451 11 451.489 21 95.1164 31 7.75979 12 482.3 22 279.189 32 17.6568 13 482.3 23 279.189 33 17.6568 0 3DFACE 8 1 10 482.3 20 279.189 30 17.6568 11 469.691 21 99.6008 31 6.68319 12 451.489 22 95.1164 32 7.75979 13 451.489 23 95.1164 33 7.75979 0 3DFACE 8 1 10 482.3 20 279.189 30 17.6568 11 469.691 21 99.6008 31 6.68319 12 497.335 22 280.094 32 17.3041 13 497.335 23 280.094 33 17.3041 0 3DFACE 8 1 10 497.335 20 280.094 30 17.3041 11 487.893 21 104.36 31 5.49291 12 469.691 22 99.6008 32 6.68319 13 469.691 23 99.6008 33 6.68319 0 3DFACE 8 1 10 497.335 20 280.094 30 17.3041 11 487.893 21 104.36 31 5.49291 12 512.373 22 281 32 16.9036 13 512.373 23 281 33 16.9036 0 3DFACE 8 1 10 512.373 20 281 30 16.9036 11 506.094 21 109.395 31 4.20885 12 487.893 22 104.36 32 5.49291 13 487.893 23 104.36 33 5.49291 0 3DFACE 8 1 10 512.373 20 281 30 16.9036 11 506.094 21 109.395 31 4.20885 12 527.414 22 281.906 32 16.4685 13 527.414 23 281.906 33 16.4685 0 3DFACE 8 1 10 527.414 20 281.906 30 16.4685 11 524.296 21 114.709 31 2.85133 12 506.094 22 109.395 32 4.20885 13 506.094 23 109.395 33 4.20885 0 3DFACE 8 1 10 527.414 20 281.906 30 16.4685 11 524.296 21 114.709 31 2.85133 12 542.457 22 282.811 32 16.0084 13 542.457 23 282.811 33 16.0084 0 3DFACE 8 1 10 542.457 20 282.811 30 16.0084 11 542.498 21 120.305 31 1.44121 12 524.296 22 114.709 32 2.85133 13 524.296 23 114.709 33 2.85133 0 3DFACE 8 1 10 542.457 20 282.811 30 16.0084 11 542.498 21 120.305 31 1.44121 12 557.502 22 283.717 32 15.5288 13 557.502 23 283.717 33 15.5288 0 3DFACE 8 1 10 557.502 20 283.717 30 15.5288 11 560.699 21 126.183 31 -1.02926e-15 12 542.498 22 120.305 32 1.44121 13 542.498 23 120.305 33 1.44121 0 3DFACE 8 1 10 559.101 20 204.95 30 7.76442 11 560.699 21 126.183 31 -1.02926e-15 12 560.389 22 152.449 32 2.95745 13 560.389 23 152.449 33 2.95745 0 3DFACE 8 1 10 559.101 20 204.95 30 7.76442 11 560.389 21 152.449 31 2.95745 12 559.987 22 178.711 32 5.77017 13 559.987 23 178.711 33 5.77017 0 3DFACE 8 1 10 559.101 20 204.95 30 7.76442 11 559.987 21 178.711 31 5.77017 12 559.495 22 204.968 32 8.4359 13 559.495 23 204.968 33 8.4359 0 3DFACE 8 1 10 559.101 20 204.95 30 7.76442 11 559.495 21 204.968 31 8.4359 12 558.915 22 231.222 32 10.9524 13 558.915 23 231.222 33 10.9524 0 3DFACE 8 1 10 559.101 20 204.95 30 7.76442 11 558.915 21 231.222 31 10.9524 12 558.25 22 257.471 32 13.3174 13 558.25 23 257.471 33 13.3174 0 3DFACE 8 1 10 559.101 20 204.95 30 7.76442 11 558.25 21 257.471 31 13.3174 12 557.502 22 283.717 32 15.5288 13 557.502 23 283.717 33 15.5288 0 3DFACE 8 2 10 288.992 20 368.426 30 1.76695e-10 11 257.926 21 265.605 31 2.50594e-10 12 268.22 22 299.875 32 2.85186e-10 13 268.22 23 299.875 33 2.85186e-10 0 3DFACE 8 2 10 288.992 20 368.426 30 1.76695e-10 11 268.22 21 299.875 31 2.85186e-10 12 278.539 22 334.147 32 2.96349e-10 13 278.539 23 334.147 33 2.96349e-10 0 3DFACE 8 2 10 288.992 20 368.426 30 1.76695e-10 11 278.539 21 334.147 31 2.96349e-10 12 288.882 22 368.42 32 2.82186e-10 13 288.882 23 368.42 33 2.82186e-10 0 3DFACE 8 2 10 288.992 20 368.426 30 1.76695e-10 11 288.882 21 368.42 31 2.82186e-10 12 299.25 22 402.694 32 2.42515e-10 13 299.25 23 402.694 33 2.42515e-10 0 3DFACE 8 2 10 288.992 20 368.426 30 1.76695e-10 11 299.25 21 402.694 31 2.42515e-10 12 309.642 22 436.97 32 1.80982e-10 13 309.642 23 436.97 33 1.80982e-10 0 3DFACE 8 2 10 288.992 20 368.426 30 1.76695e-10 11 309.642 21 436.97 31 1.80982e-10 12 320.059 22 471.248 32 1.02796e-10 13 320.059 23 471.248 33 1.02796e-10 0 3DFACE 8 2 10 320.059 20 471.248 30 1.02796e-10 11 257.926 21 265.605 31 2.50594e-10 12 331.13 22 471.945 32 4.67389 13 331.13 23 471.945 33 4.67389 0 3DFACE 8 2 10 331.13 20 471.945 30 4.67389 11 272.768 21 266.51 31 3.67824 12 257.926 22 265.605 32 2.50594e-10 13 257.926 23 265.605 33 2.50594e-10 0 3DFACE 8 2 10 331.13 20 471.945 30 4.67389 11 272.768 21 266.51 31 3.67824 12 342.286 22 472.641 32 8.61202 13 342.286 23 472.641 33 8.61202 0 3DFACE 8 2 10 342.286 20 472.641 30 8.61202 11 287.634 21 267.416 31 6.8339 12 272.768 22 266.51 32 3.67824 13 272.768 23 266.51 33 3.67824 0 3DFACE 8 2 10 342.286 20 472.641 30 8.61202 11 287.634 21 267.416 31 6.8339 12 353.515 22 473.338 32 11.9109 13 353.515 23 473.338 33 11.9109 0 3DFACE 8 2 10 353.515 20 473.338 30 11.9109 11 302.521 21 268.321 31 9.50799 12 287.634 22 267.416 32 6.8339 13 287.634 23 267.416 33 6.8339 0 3DFACE 8 2 10 353.515 20 473.338 30 11.9109 11 302.521 21 268.321 31 9.50799 12 364.807 22 474.035 32 14.6588 13 364.807 23 474.035 33 14.6588 0 3DFACE 8 2 10 364.807 20 474.035 30 14.6588 11 317.428 21 269.227 31 11.7409 12 302.521 22 268.321 32 9.50799 13 302.521 23 268.321 33 9.50799 0 3DFACE 8 2 10 364.807 20 474.035 30 14.6588 11 317.428 21 269.227 31 11.7409 12 376.154 22 474.731 32 16.9361 13 376.154 23 474.731 33 16.9361 0 3DFACE 8 2 10 376.154 20 474.731 30 16.9361 11 332.353 21 270.133 31 13.5723 12 317.428 22 269.227 32 11.7409 13 317.428 23 269.227 33 11.7409 0 3DFACE 8 2 10 376.154 20 474.731 30 16.9361 11 332.353 21 270.133 31 13.5723 12 387.547 22 475.428 32 18.8151 13 387.547 23 475.428 33 18.8151 0 3DFACE 8 2 10 387.547 20 475.428 30 18.8151 11 347.295 21 271.038 31 15.0409 12 332.353 22 270.133 32 13.5723 13 332.353 23 270.133 33 13.5723 0 3DFACE 8 2 10 387.547 20 475.428 30 18.8151 11 347.295 21 271.038 31 15.0409 12 398.98 22 476.125 32 20.3605 13 398.98 23 476.125 33 20.3605 0 3DFACE 8 2 10 398.98 20 476.125 30 20.3605 11 362.253 21 271.944 31 16.1844 12 347.295 22 271.038 32 15.0409 13 347.295 23 271.038 33 15.0409 0 3DFACE 8 2 10 398.98 20 476.125 30 20.3605 11 362.253 21 271.944 31 16.1844 12 410.444 22 476.821 32 21.6292 13 410.444 23 476.821 33 21.6292 0 3DFACE 8 2 10 410.444 20 476.821 30 21.6292 11 377.225 21 272.849 31 17.0393 12 362.253 22 271.944 32 16.1844 13 362.253 23 271.944 33 16.1844 0 3DFACE 8 2 10 410.444 20 476.821 30 21.6292 11 377.225 21 272.849 31 17.0393 12 421.936 22 477.518 32 22.6712 13 421.936 23 477.518 33 22.6712 0 3DFACE 8 2 10 421.936 20 477.518 30 22.6712 11 392.209 21 273.755 31 17.6405 12 377.225 22 272.849 32 17.0393 13 377.225 23 272.849 33 17.0393 0 3DFACE 8 2 10 421.936 20 477.518 30 22.6712 11 392.209 21 273.755 31 17.6405 12 433.45 22 478.215 32 23.5291 13 433.45 23 478.215 33 23.5291 0 3DFACE 8 2 10 433.45 20 478.215 30 23.5291 11 407.204 21 274.661 31 18.0215 12 392.209 22 273.755 32 17.6405 13 392.209 23 273.755 33 17.6405 0 3DFACE 8 2 10 433.45 20 478.215 30 23.5291 11 407.204 21 274.661 31 18.0215 12 444.981 22 478.911 32 24.239 13 444.981 23 478.911 33 24.239 0 3DFACE 8 2 10 444.981 20 478.911 30 24.239 11 422.209 21 275.566 31 18.2139 12 407.204 22 274.661 32 18.0215 13 407.204 23 274.661 33 18.0215 0 3DFACE 8 2 10 444.981 20 478.911 30 24.239 11 422.209 21 275.566 31 18.2139 12 456.527 22 479.608 32 24.8308 13 456.527 23 479.608 33 24.8308 0 3DFACE 8 2 10 456.527 20 479.608 30 24.8308 11 437.222 21 276.472 31 18.2475 12 422.209 22 275.566 32 18.2139 13 422.209 23 275.566 33 18.2139 0 3DFACE 8 2 10 456.527 20 479.608 30 24.8308 11 437.222 21 276.472 31 18.2475 12 468.084 22 480.305 32 25.3283 13 468.084 23 480.305 33 25.3283 0 3DFACE 8 2 10 468.084 20 480.305 30 25.3283 11 452.242 21 277.377 31 18.1495 12 437.222 22 276.472 32 18.2475 13 437.222 23 276.472 33 18.2475 0 3DFACE 8 2 10 468.084 20 480.305 30 25.3283 11 452.242 21 277.377 31 18.1495 12 479.651 22 481.001 32 25.7499 13 479.651 23 481.001 33 25.7499 0 3DFACE 8 2 10 479.651 20 481.001 30 25.7499 11 467.269 21 278.283 31 17.9451 12 452.242 22 277.377 32 18.1495 13 452.242 23 277.377 33 18.1495 0 3DFACE 8 2 10 479.651 20 481.001 30 25.7499 11 467.269 21 278.283 31 17.9451 12 491.226 22 481.698 32 26.109 13 491.226 23 481.698 33 26.109 0 3DFACE 8 2 10 491.226 20 481.698 30 26.109 11 482.3 21 279.189 31 17.6568 12 467.269 22 278.283 32 17.9451 13 467.269 23 278.283 33 17.9451 0 3DFACE 8 2 10 491.226 20 481.698 30 26.109 11 482.3 21 279.189 31 17.6568 12 502.807 22 482.395 32 26.4147 13 502.807 23 482.395 33 26.4147 0 3DFACE 8 2 10 502.807 20 482.395 30 26.4147 11 497.335 21 280.094 31 17.3041 12 482.3 22 279.189 32 17.6568 13 482.3 23 279.189 33 17.6568 0 3DFACE 8 2 10 502.807 20 482.395 30 26.4147 11 497.335 21 280.094 31 17.3041 12 514.395 22 483.091 32 26.6721 13 514.395 23 483.091 33 26.6721 0 3DFACE 8 2 10 514.395 20 483.091 30 26.6721 11 512.373 21 281 31 16.9036 12 497.335 22 280.094 32 17.3041 13 497.335 23 280.094 33 17.3041 0 3DFACE 8 2 10 514.395 20 483.091 30 26.6721 11 512.373 21 281 31 16.9036 12 525.989 22 483.788 32 26.8834 13 525.989 23 483.788 33 26.8834 0 3DFACE 8 2 10 525.989 20 483.788 30 26.8834 11 527.414 21 281.906 31 16.4685 12 512.373 22 281 32 16.9036 13 512.373 23 281 33 16.9036 0 3DFACE 8 2 10 525.989 20 483.788 30 26.8834 11 527.414 21 281.906 31 16.4685 12 537.589 22 484.485 32 27.0479 13 537.589 23 484.485 33 27.0479 0 3DFACE 8 2 10 537.589 20 484.485 30 27.0479 11 542.457 21 282.811 31 16.0084 12 527.414 22 281.906 32 16.4685 13 527.414 23 281.906 33 16.4685 0 3DFACE 8 2 10 537.589 20 484.485 30 27.0479 11 542.457 21 282.811 31 16.0084 12 549.196 22 485.181 32 27.1635 13 549.196 23 485.181 33 27.1635 0 3DFACE 8 2 10 549.196 20 485.181 30 27.1635 11 557.502 21 283.717 31 15.5288 12 542.457 22 282.811 32 16.0084 13 542.457 23 282.811 33 16.0084 0 3DFACE 8 2 10 553.349 20 384.449 30 21.3462 11 557.502 21 283.717 31 15.5288 12 556.425 22 317.311 32 18.1322 13 556.425 23 317.311 33 18.1322 0 3DFACE 8 2 10 553.349 20 384.449 30 21.3462 11 556.425 21 317.311 31 18.1322 12 555.219 22 350.898 32 20.4756 13 555.219 23 350.898 33 20.4756 0 3DFACE 8 2 10 553.349 20 384.449 30 21.3462 11 555.219 21 350.898 31 20.4756 12 553.888 22 384.479 32 22.5548 13 553.888 23 384.479 33 22.5548 0 3DFACE 8 2 10 553.349 20 384.449 30 21.3462 11 553.888 21 384.479 31 22.5548 12 552.438 22 418.053 32 24.3653 13 552.438 23 418.053 33 24.3653 0 3DFACE 8 2 10 553.349 20 384.449 30 21.3462 11 552.438 21 418.053 31 24.3653 12 550.872 22 451.62 32 25.9029 13 550.872 23 451.62 33 25.9029 0 3DFACE 8 2 10 553.349 20 384.449 30 21.3462 11 550.872 21 451.62 31 25.9029 12 549.196 22 485.181 32 27.1635 13 549.196 23 485.181 33 27.1635 0 3DFACE 8 3 10 351.502 20 574.038 30 6.16085e-11 11 320.059 21 471.248 31 1.02796e-10 12 330.494 22 505.508 32 1.63442e-11 13 330.494 23 505.508 33 1.63442e-11 0 3DFACE 8 3 10 351.502 20 574.038 30 6.16085e-11 11 330.494 21 505.508 31 1.63442e-11 12 340.951 22 539.77 32 3.68686e-11 13 340.951 23 539.77 33 3.68686e-11 0 3DFACE 8 3 10 351.502 20 574.038 30 6.16085e-11 11 340.951 21 539.77 31 3.68686e-11 12 351.425 22 574.033 32 6.48391e-11 13 351.425 23 574.033 33 6.48391e-11 0 3DFACE 8 3 10 351.502 20 574.038 30 6.16085e-11 11 351.425 21 574.033 31 6.48391e-11 12 361.916 22 608.297 32 6.51159e-11 13 361.916 23 608.297 33 6.51159e-11 0 3DFACE 8 3 10 351.502 20 574.038 30 6.16085e-11 11 361.916 21 608.297 31 6.51159e-11 12 372.422 22 642.561 32 2.76955e-11 13 372.422 23 642.561 33 2.76955e-11 0 3DFACE 8 3 10 351.502 20 574.038 30 6.16085e-11 11 372.422 21 642.561 31 2.76955e-11 12 382.945 22 676.827 32 2.04214e-11 13 382.945 23 676.827 33 2.04214e-11 0 3DFACE 8 3 10 382.945 20 676.827 30 2.04214e-11 11 320.059 21 471.248 31 1.02796e-10 12 390.167 22 677.301 32 4.0311 13 390.167 23 677.301 33 4.0311 0 3DFACE 8 3 10 390.167 20 677.301 30 4.0311 11 331.13 21 471.945 31 4.67389 12 320.059 22 471.248 32 1.02796e-10 13 320.059 23 471.248 33 1.02796e-10 0 3DFACE 8 3 10 390.167 20 677.301 30 4.0311 11 331.13 21 471.945 31 4.67389 12 397.505 22 677.774 32 7.43747 13 397.505 23 677.774 33 7.43747 0 3DFACE 8 3 10 397.505 20 677.774 30 7.43747 11 342.286 21 472.641 31 8.61202 12 331.13 22 471.945 32 4.67389 13 331.13 23 471.945 33 4.67389 0 3DFACE 8 3 10 397.505 20 677.774 30 7.43747 11 342.286 21 472.641 31 8.61202 12 404.94 22 678.247 32 10.3154 13 404.94 23 678.247 33 10.3154 0 3DFACE 8 3 10 404.94 20 678.247 30 10.3154 11 353.515 21 473.338 31 11.9109 12 342.286 22 472.641 32 8.61202 13 342.286 23 472.641 33 8.61202 0 3DFACE 8 3 10 404.94 20 678.247 30 10.3154 11 353.515 21 473.338 31 11.9109 12 412.458 22 678.721 32 12.7503 13 412.458 23 678.721 33 12.7503 0 3DFACE 8 3 10 412.458 20 678.721 30 12.7503 11 364.807 21 474.035 31 14.6588 12 353.515 22 473.338 32 11.9109 13 353.515 23 473.338 33 11.9109 0 3DFACE 8 3 10 412.458 20 678.721 30 12.7503 11 364.807 21 474.035 31 14.6588 12 420.045 22 679.194 32 14.8173 13 420.045 23 679.194 33 14.8173 0 3DFACE 8 3 10 420.045 20 679.194 30 14.8173 11 376.154 21 474.731 31 16.9361 12 364.807 22 474.035 32 14.6588 13 364.807 23 474.035 33 14.6588 0 3DFACE 8 3 10 420.045 20 679.194 30 14.8173 11 376.154 21 474.731 31 16.9361 12 427.688 22 679.668 32 16.5817 13 427.688 23 679.668 33 16.5817 0 3DFACE 8 3 10 427.688 20 679.668 30 16.5817 11 387.547 21 475.428 31 18.8151 12 376.154 22 474.731 32 16.9361 13 376.154 23 474.731 33 16.9361 0 3DFACE 8 3 10 427.688 20 679.668 30 16.5817 11 387.547 21 475.428 31 18.8151 12 435.377 22 680.141 32 18.1 13 435.377 23 680.141 33 18.1 0 3DFACE 8 3 10 435.377 20 680.141 30 18.1 11 398.98 21 476.125 31 20.3605 12 387.547 22 475.428 32 18.8151 13 387.547 23 475.428 33 18.8151 0 3DFACE 8 3 10 435.377 20 680.141 30 18.1 11 398.98 21 476.125 31 20.3605 12 443.104 22 680.615 32 19.4202 13 443.104 23 680.615 33 19.4202 0 3DFACE 8 3 10 443.104 20 680.615 30 19.4202 11 410.444 21 476.821 31 21.6292 12 398.98 22 476.125 32 20.3605 13 398.98 23 476.125 33 20.3605 0 3DFACE 8 3 10 443.104 20 680.615 30 19.4202 11 410.444 21 476.821 31 21.6292 12 450.86 22 681.088 32 20.5824 13 450.86 23 681.088 33 20.5824 0 3DFACE 8 3 10 450.86 20 681.088 30 20.5824 11 421.936 21 477.518 31 22.6712 12 410.444 22 476.821 32 21.6292 13 410.444 23 476.821 33 21.6292 0 3DFACE 8 3 10 450.86 20 681.088 30 20.5824 11 421.936 21 477.518 31 22.6712 12 458.64 22 681.561 32 21.62 13 458.64 23 681.561 33 21.62 0 3DFACE 8 3 10 458.64 20 681.561 30 21.62 11 433.45 21 478.215 31 23.5291 12 421.936 22 477.518 32 22.6712 13 421.936 23 477.518 33 22.6712 0 3DFACE 8 3 10 458.64 20 681.561 30 21.62 11 433.45 21 478.215 31 23.5291 12 466.438 22 682.035 32 22.5595 13 466.438 23 682.035 33 22.5595 0 3DFACE 8 3 10 466.438 20 682.035 30 22.5595 11 444.981 21 478.911 31 24.239 12 433.45 22 478.215 32 23.5291 13 433.45 23 478.215 33 23.5291 0 3DFACE 8 3 10 466.438 20 682.035 30 22.5595 11 444.981 21 478.911 31 24.239 12 474.251 22 682.508 32 23.4221 13 474.251 23 682.508 33 23.4221 0 3DFACE 8 3 10 474.251 20 682.508 30 23.4221 11 456.527 21 479.608 31 24.8308 12 444.981 22 478.911 32 24.239 13 444.981 23 478.911 33 24.239 0 3DFACE 8 3 10 474.251 20 682.508 30 23.4221 11 456.527 21 479.608 31 24.8308 12 482.075 22 682.982 32 24.2237 13 482.075 23 682.982 33 24.2237 0 3DFACE 8 3 10 482.075 20 682.982 30 24.2237 11 468.084 21 480.305 31 25.3283 12 456.527 22 479.608 32 24.8308 13 456.527 23 479.608 33 24.8308 0 3DFACE 8 3 10 482.075 20 682.982 30 24.2237 11 468.084 21 480.305 31 25.3283 12 489.91 22 683.455 32 24.9757 13 489.91 23 683.455 33 24.9757 0 3DFACE 8 3 10 489.91 20 683.455 30 24.9757 11 479.651 21 481.001 31 25.7499 12 468.084 22 480.305 32 25.3283 13 468.084 23 480.305 33 25.3283 0 3DFACE 8 3 10 489.91 20 683.455 30 24.9757 11 479.651 21 481.001 31 25.7499 12 497.752 22 683.929 32 25.6859 13 497.752 23 683.929 33 25.6859 0 3DFACE 8 3 10 497.752 20 683.929 30 25.6859 11 491.226 21 481.698 31 26.109 12 479.651 22 481.001 32 25.7499 13 479.651 23 481.001 33 25.7499 0 3DFACE 8 3 10 497.752 20 683.929 30 25.6859 11 491.226 21 481.698 31 26.109 12 505.602 22 684.402 32 26.3588 13 505.602 23 684.402 33 26.3588 0 3DFACE 8 3 10 505.602 20 684.402 30 26.3588 11 502.807 21 482.395 31 26.4147 12 491.226 22 481.698 32 26.109 13 491.226 23 481.698 33 26.109 0 3DFACE 8 3 10 505.602 20 684.402 30 26.3588 11 502.807 21 482.395 31 26.4147 12 513.458 22 684.875 32 26.9967 13 513.458 23 684.875 33 26.9967 0 3DFACE 8 3 10 513.458 20 684.875 30 26.9967 11 514.395 21 483.091 31 26.6721 12 502.807 22 482.395 32 26.4147 13 502.807 23 482.395 33 26.4147 0 3DFACE 8 3 10 513.458 20 684.875 30 26.9967 11 514.395 21 483.091 31 26.6721 12 521.321 22 685.349 32 27.5996 13 521.321 23 685.349 33 27.5996 0 3DFACE 8 3 10 521.321 20 685.349 30 27.5996 11 525.989 21 483.788 31 26.8834 12 514.395 22 483.091 32 26.6721 13 514.395 23 483.091 33 26.6721 0 3DFACE 8 3 10 521.321 20 685.349 30 27.5996 11 525.989 21 483.788 31 26.8834 12 529.192 22 685.822 32 28.1664 13 529.192 23 685.822 33 28.1664 0 3DFACE 8 3 10 529.192 20 685.822 30 28.1664 11 537.589 21 484.485 31 27.0479 12 525.989 22 483.788 32 26.8834 13 525.989 23 483.788 33 26.8834 0 3DFACE 8 3 10 529.192 20 685.822 30 28.1664 11 537.589 21 484.485 31 27.0479 12 537.07 22 686.296 32 28.6954 13 537.07 23 686.296 33 28.6954 0 3DFACE 8 3 10 537.07 20 686.296 30 28.6954 11 549.196 21 485.181 31 27.1635 12 537.589 22 484.485 32 27.0479 13 537.589 23 484.485 33 27.0479 0 3DFACE 8 3 10 543.133 20 585.738 30 27.9294 11 549.196 21 485.181 31 27.1635 12 547.416 22 518.717 32 28.1423 13 547.416 23 518.717 33 28.1423 0 3DFACE 8 3 10 543.133 20 585.738 30 27.9294 11 547.416 21 518.717 31 28.1423 12 545.536 22 552.247 32 28.837 13 545.536 23 552.247 33 28.837 0 3DFACE 8 3 10 543.133 20 585.738 30 27.9294 11 545.536 21 552.247 31 28.837 12 543.56 22 585.77 32 29.244 13 543.56 23 585.77 33 29.244 0 3DFACE 8 3 10 543.133 20 585.738 30 27.9294 11 543.56 21 585.77 31 29.244 12 541.494 22 619.286 32 29.3598 13 541.494 23 619.286 33 29.3598 0 3DFACE 8 3 10 543.133 20 585.738 30 27.9294 11 541.494 21 619.286 31 29.3598 12 539.342 22 652.795 32 29.1805 13 539.342 23 652.795 33 29.1805 0 3DFACE 8 3 10 543.133 20 585.738 30 27.9294 11 539.342 21 652.795 31 29.1805 12 537.07 22 686.296 32 28.6954 13 537.07 23 686.296 33 28.6954 0 3DFACE 8 4 10 414.692 20 779.65 30 2.73739e-10 11 382.945 21 676.827 31 2.04214e-11 12 393.486 22 711.099 32 6.7514e-11 13 393.486 23 711.099 33 6.7514e-11 0 3DFACE 8 4 10 414.692 20 779.65 30 2.73739e-10 11 393.486 21 711.099 31 6.7514e-11 12 404.044 22 745.372 32 1.30896e-10 13 404.044 23 745.372 33 1.30896e-10 0 3DFACE 8 4 10 414.692 20 779.65 30 2.73739e-10 11 404.044 21 745.372 31 1.30896e-10 12 414.618 22 779.646 32 2.10185e-10 13 414.618 23 779.646 33 2.10185e-10 0 3DFACE 8 4 10 414.692 20 779.65 30 2.73739e-10 11 414.618 21 779.646 31 2.10185e-10 12 425.209 22 813.92 32 3.04089e-10 13 425.209 23 813.92 33 3.04089e-10 0 3DFACE 8 4 10 414.692 20 779.65 30 2.73739e-10 11 425.209 21 813.92 31 3.04089e-10 12 435.815 22 848.196 32 4.1062e-10 13 435.815 23 848.196 33 4.1062e-10 0 3DFACE 8 4 10 414.692 20 779.65 30 2.73739e-10 11 435.815 21 848.196 31 4.1062e-10 12 446.439 22 882.473 32 5.27056e-10 13 446.439 23 882.473 33 5.27056e-10 0 3DFACE 8 4 10 446.439 20 882.473 30 5.27056e-10 11 382.945 21 676.827 31 2.04214e-11 12 449.801 22 882.705 32 2.3599 13 449.801 23 882.705 33 2.3599 0 3DFACE 8 4 10 449.801 20 882.705 30 2.3599 11 390.167 21 677.301 31 4.0311 12 382.945 22 676.827 32 2.04214e-11 13 382.945 23 676.827 33 2.04214e-11 0 3DFACE 8 4 10 449.801 20 882.705 30 2.3599 11 390.167 21 677.301 31 4.0311 12 453.257 22 882.938 32 4.36106 13 453.257 23 882.938 33 4.36106 0 3DFACE 8 4 10 453.257 20 882.938 30 4.36106 11 397.505 21 677.774 31 7.43747 12 390.167 22 677.301 32 4.0311 13 390.167 23 677.301 33 4.0311 0 3DFACE 8 4 10 453.257 20 882.938 30 4.36106 11 397.505 21 677.774 31 7.43747 12 456.789 22 883.17 32 6.06452 13 456.789 23 883.17 33 6.06452 0 3DFACE 8 4 10 456.789 20 883.17 30 6.06452 11 404.94 21 678.247 31 10.3154 12 397.505 22 677.774 32 7.43747 13 397.505 23 677.774 33 7.43747 0 3DFACE 8 4 10 456.789 20 883.17 30 6.06452 11 404.94 21 678.247 31 10.3154 12 460.384 22 883.402 32 7.52334 13 460.384 23 883.402 33 7.52334 0 3DFACE 8 4 10 460.384 20 883.402 30 7.52334 11 412.458 21 678.721 31 12.7503 12 404.94 22 678.247 32 10.3154 13 404.94 23 678.247 33 10.3154 0 3DFACE 8 4 10 460.384 20 883.402 30 7.52334 11 412.458 21 678.721 31 12.7503 12 464.031 22 883.635 32 8.7832 13 464.031 23 883.635 33 8.7832 0 3DFACE 8 4 10 464.031 20 883.635 30 8.7832 11 420.045 21 679.194 31 14.8173 12 412.458 22 678.721 32 12.7503 13 412.458 23 678.721 33 12.7503 0 3DFACE 8 4 10 464.031 20 883.635 30 8.7832 11 420.045 21 679.194 31 14.8173 12 467.72 22 883.867 32 9.88305 13 467.72 23 883.867 33 9.88305 0 3DFACE 8 4 10 467.72 20 883.867 30 9.88305 11 427.688 21 679.668 31 16.5817 12 420.045 22 679.194 32 14.8173 13 420.045 23 679.194 33 14.8173 0 3DFACE 8 4 10 467.72 20 883.867 30 9.88305 11 427.688 21 679.668 31 16.5817 12 471.441 22 884.1 32 10.8557 13 471.441 23 884.1 33 10.8557 0 3DFACE 8 4 10 471.441 20 884.1 30 10.8557 11 435.377 21 680.141 31 18.1 12 427.688 22 679.668 32 16.5817 13 427.688 23 679.668 33 16.5817 0 3DFACE 8 4 10 471.441 20 884.1 30 10.8557 11 435.377 21 680.141 31 18.1 12 475.188 22 884.332 32 11.7282 13 475.188 23 884.332 33 11.7282 0 3DFACE 8 4 10 475.188 20 884.332 30 11.7282 11 443.104 21 680.615 31 19.4202 12 435.377 22 680.141 32 18.1 13 435.377 23 680.141 33 18.1 0 3DFACE 8 4 10 475.188 20 884.332 30 11.7282 11 443.104 21 680.615 31 19.4202 12 478.956 22 884.564 32 12.5229 13 478.956 23 884.564 33 12.5229 0 3DFACE 8 4 10 478.956 20 884.564 30 12.5229 11 450.86 21 681.088 31 20.5824 12 443.104 22 680.615 32 19.4202 13 443.104 23 680.615 33 19.4202 0 3DFACE 8 4 10 478.956 20 884.564 30 12.5229 11 450.86 21 681.088 31 20.5824 12 482.739 22 884.797 32 13.2574 13 482.739 23 884.797 33 13.2574 0 3DFACE 8 4 10 482.739 20 884.797 30 13.2574 11 458.64 21 681.561 31 21.62 12 450.86 22 681.088 32 20.5824 13 450.86 23 681.088 33 20.5824 0 3DFACE 8 4 10 482.739 20 884.797 30 13.2574 11 458.64 21 681.561 31 21.62 12 486.534 22 885.029 32 13.9457 13 486.534 23 885.029 33 13.9457 0 3DFACE 8 4 10 486.534 20 885.029 30 13.9457 11 466.438 21 682.035 31 22.5595 12 458.64 22 681.561 32 21.62 13 458.64 23 681.561 33 21.62 0 3DFACE 8 4 10 486.534 20 885.029 30 13.9457 11 466.438 21 682.035 31 22.5595 12 490.339 22 885.262 32 14.5981 13 490.339 23 885.262 33 14.5981 0 3DFACE 8 4 10 490.339 20 885.262 30 14.5981 11 474.251 21 682.508 31 23.4221 12 466.438 22 682.035 32 22.5595 13 466.438 23 682.035 33 22.5595 0 3DFACE 8 4 10 490.339 20 885.262 30 14.5981 11 474.251 21 682.508 31 23.4221 12 494.151 22 885.494 32 15.2222 13 494.151 23 885.494 33 15.2222 0 3DFACE 8 4 10 494.151 20 885.494 30 15.2222 11 482.075 21 682.982 31 24.2237 12 474.251 22 682.508 32 23.4221 13 474.251 23 682.508 33 23.4221 0 3DFACE 8 4 10 494.151 20 885.494 30 15.2222 11 482.075 21 682.982 31 24.2237 12 497.969 22 885.726 32 15.8232 13 497.969 23 885.726 33 15.8232 0 3DFACE 8 4 10 497.969 20 885.726 30 15.8232 11 489.91 21 683.455 31 24.9757 12 482.075 22 682.982 32 24.2237 13 482.075 23 682.982 33 24.2237 0 3DFACE 8 4 10 497.969 20 885.726 30 15.8232 11 489.91 21 683.455 31 24.9757 12 501.792 22 885.959 32 16.4044 13 501.792 23 885.959 33 16.4044 0 3DFACE 8 4 10 501.792 20 885.959 30 16.4044 11 497.752 21 683.929 31 25.6859 12 489.91 22 683.455 32 24.9757 13 489.91 23 683.455 33 24.9757 0 3DFACE 8 4 10 501.792 20 885.959 30 16.4044 11 497.752 21 683.929 31 25.6859 12 505.62 22 886.191 32 16.9673 13 505.62 23 886.191 33 16.9673 0 3DFACE 8 4 10 505.62 20 886.191 30 16.9673 11 505.602 21 684.402 31 26.3588 12 497.752 22 683.929 32 25.6859 13 497.752 23 683.929 33 25.6859 0 3DFACE 8 4 10 505.62 20 886.191 30 16.9673 11 505.602 21 684.402 31 26.3588 12 509.453 22 886.423 32 17.5127 13 509.453 23 886.423 33 17.5127 0 3DFACE 8 4 10 509.453 20 886.423 30 17.5127 11 513.458 21 684.875 31 26.9967 12 505.602 22 684.402 32 26.3588 13 505.602 23 684.402 33 26.3588 0 3DFACE 8 4 10 509.453 20 886.423 30 17.5127 11 513.458 21 684.875 31 26.9967 12 513.29 22 886.656 32 18.0401 13 513.29 23 886.656 33 18.0401 0 3DFACE 8 4 10 513.29 20 886.656 30 18.0401 11 521.321 21 685.349 31 27.5996 12 513.458 22 684.875 32 26.9967 13 513.458 23 684.875 33 26.9967 0 3DFACE 8 4 10 513.29 20 886.656 30 18.0401 11 521.321 21 685.349 31 27.5996 12 517.132 22 886.888 32 18.5488 13 517.132 23 886.888 33 18.5488 0 3DFACE 8 4 10 517.132 20 886.888 30 18.5488 11 529.192 21 685.822 31 28.1664 12 521.321 22 685.349 32 27.5996 13 521.321 23 685.349 33 27.5996 0 3DFACE 8 4 10 517.132 20 886.888 30 18.5488 11 529.192 21 685.822 31 28.1664 12 520.98 22 887.121 32 19.0377 13 520.98 23 887.121 33 19.0377 0 3DFACE 8 4 10 520.98 20 887.121 30 19.0377 11 537.07 21 686.296 31 28.6954 12 529.192 22 685.822 32 28.1664 13 529.192 23 685.822 33 28.1664 0 3DFACE 8 4 10 529.025 20 786.708 30 23.8666 11 537.07 21 686.296 31 28.6954 12 534.671 22 719.791 32 27.8971 13 534.671 23 719.791 33 27.8971 0 3DFACE 8 4 10 529.025 20 786.708 30 23.8666 11 534.671 21 719.791 31 27.8971 12 532.151 22 753.277 32 26.7807 13 532.151 23 753.277 33 26.7807 0 3DFACE 8 4 10 529.025 20 786.708 30 23.8666 11 532.151 21 753.277 31 26.7807 12 529.515 22 786.753 32 25.3412 13 529.515 23 786.753 33 25.3412 0 3DFACE 8 4 10 529.025 20 786.708 30 23.8666 11 529.515 21 786.753 31 25.3412 12 526.771 22 820.218 32 23.574 13 526.771 23 820.218 33 23.574 0 3DFACE 8 4 10 529.025 20 786.708 30 23.8666 11 526.771 21 820.218 31 23.574 12 523.924 22 853.675 32 21.4744 13 523.924 23 853.675 33 21.4744 0 3DFACE 8 4 10 529.025 20 786.708 30 23.8666 11 523.924 21 853.675 31 21.4744 12 520.98 22 887.121 32 19.0377 13 520.98 23 887.121 33 19.0377 0 3DFACE 8 5 10 474.751 20 973.387 30 2.63528e-10 11 446.439 21 882.473 31 5.27056e-10 12 455.844 22 912.776 32 6.34624e-10 13 455.844 23 912.776 33 6.34624e-10 0 3DFACE 8 5 10 474.751 20 973.387 30 2.63528e-10 11 455.844 21 912.776 31 6.34624e-10 12 465.262 22 943.079 32 7.44634e-10 13 465.262 23 943.079 33 7.44634e-10 0 3DFACE 8 5 10 474.751 20 973.387 30 2.63528e-10 11 465.262 21 943.079 31 7.44634e-10 12 474.693 22 973.384 32 8.5324e-10 13 474.693 23 973.384 33 8.5324e-10 0 3DFACE 8 5 10 474.751 20 973.387 30 2.63528e-10 11 474.693 21 973.384 31 8.5324e-10 12 484.137 22 1003.69 32 9.56672e-10 13 484.137 23 1003.69 33 9.56672e-10 0 3DFACE 8 5 10 474.751 20 973.387 30 2.63528e-10 11 484.137 21 1003.69 31 9.56672e-10 12 493.594 22 1033.99 32 1.05075e-09 13 493.594 23 1033.99 33 1.05075e-09 0 3DFACE 8 5 10 474.751 20 973.387 30 2.63528e-10 11 493.594 21 1033.99 31 1.05075e-09 12 503.064 22 1064.3 32 0 13 503.064 23 1064.3 33 0 0 3DFACE 8 5 10 503.064 20 1064.3 30 0 11 446.439 21 882.473 31 5.27056e-10 12 503.11 22 1064.31 32 0.0152135 13 503.11 23 1064.31 33 0.0152135 0 3DFACE 8 5 10 503.11 20 1064.31 30 0.0152135 11 449.801 21 882.705 31 2.3599 12 446.439 22 882.473 32 5.27056e-10 13 446.439 23 882.473 33 5.27056e-10 0 3DFACE 8 5 10 503.11 20 1064.31 30 0.0152135 11 449.801 21 882.705 31 2.3599 12 503.157 22 1064.32 32 0.0304273 13 503.157 23 1064.32 33 0.0304273 0 3DFACE 8 5 10 503.157 20 1064.32 30 0.0304273 11 453.257 21 882.938 31 4.36106 12 449.801 22 882.705 32 2.3599 13 449.801 23 882.705 33 2.3599 0 3DFACE 8 5 10 503.157 20 1064.32 30 0.0304273 11 453.257 21 882.938 31 4.36106 12 503.204 22 1064.33 32 0.0456414 13 503.204 23 1064.33 33 0.0456414 0 3DFACE 8 5 10 503.204 20 1064.33 30 0.0456414 11 456.789 21 883.17 31 6.06452 12 453.257 22 882.938 32 4.36106 13 453.257 23 882.938 33 4.36106 0 3DFACE 8 5 10 503.204 20 1064.33 30 0.0456414 11 456.789 21 883.17 31 6.06452 12 503.251 22 1064.34 32 0.0608558 13 503.251 23 1064.34 33 0.0608558 0 3DFACE 8 5 10 503.251 20 1064.34 30 0.0608558 11 460.384 21 883.402 31 7.52334 12 456.789 22 883.17 32 6.06452 13 456.789 23 883.17 33 6.06452 0 3DFACE 8 5 10 503.251 20 1064.34 30 0.0608558 11 460.384 21 883.402 31 7.52334 12 503.298 22 1064.34 32 0.0760704 13 503.298 23 1064.34 33 0.0760704 0 3DFACE 8 5 10 503.298 20 1064.34 30 0.0760704 11 464.031 21 883.635 31 8.7832 12 460.384 22 883.402 32 7.52334 13 460.384 23 883.402 33 7.52334 0 3DFACE 8 5 10 503.298 20 1064.34 30 0.0760704 11 464.031 21 883.635 31 8.7832 12 503.345 22 1064.35 32 0.0912853 13 503.345 23 1064.35 33 0.0912853 0 3DFACE 8 5 10 503.345 20 1064.35 30 0.0912853 11 467.72 21 883.867 31 9.88305 12 464.031 22 883.635 32 8.7832 13 464.031 23 883.635 33 8.7832 0 3DFACE 8 5 10 503.345 20 1064.35 30 0.0912853 11 467.72 21 883.867 31 9.88305 12 503.391 22 1064.36 32 0.1065 13 503.391 23 1064.36 33 0.1065 0 3DFACE 8 5 10 503.391 20 1064.36 30 0.1065 11 471.441 21 884.1 31 10.8557 12 467.72 22 883.867 32 9.88305 13 467.72 23 883.867 33 9.88305 0 3DFACE 8 5 10 503.391 20 1064.36 30 0.1065 11 471.441 21 884.1 31 10.8557 12 503.438 22 1064.37 32 0.121716 13 503.438 23 1064.37 33 0.121716 0 3DFACE 8 5 10 503.438 20 1064.37 30 0.121716 11 475.188 21 884.332 31 11.7282 12 471.441 22 884.1 32 10.8557 13 471.441 23 884.1 33 10.8557 0 3DFACE 8 5 10 503.438 20 1064.37 30 0.121716 11 475.188 21 884.332 31 11.7282 12 503.485 22 1064.38 32 0.136932 13 503.485 23 1064.38 33 0.136932 0 3DFACE 8 5 10 503.485 20 1064.38 30 0.136932 11 478.956 21 884.564 31 12.5229 12 475.188 22 884.332 32 11.7282 13 475.188 23 884.332 33 11.7282 0 3DFACE 8 5 10 503.485 20 1064.38 30 0.136932 11 478.956 21 884.564 31 12.5229 12 503.532 22 1064.39 32 0.152148 13 503.532 23 1064.39 33 0.152148 0 3DFACE 8 5 10 503.532 20 1064.39 30 0.152148 11 482.739 21 884.797 31 13.2574 12 478.956 22 884.564 32 12.5229 13 478.956 23 884.564 33 12.5229 0 3DFACE 8 5 10 503.532 20 1064.39 30 0.152148 11 482.739 21 884.797 31 13.2574 12 503.579 22 1064.4 32 0.167364 13 503.579 23 1064.4 33 0.167364 0 3DFACE 8 5 10 503.579 20 1064.4 30 0.167364 11 486.534 21 885.029 31 13.9457 12 482.739 22 884.797 32 13.2574 13 482.739 23 884.797 33 13.2574 0 3DFACE 8 5 10 503.579 20 1064.4 30 0.167364 11 486.534 21 885.029 31 13.9457 12 503.626 22 1064.41 32 0.18258 13 503.626 23 1064.41 33 0.18258 0 3DFACE 8 5 10 503.626 20 1064.41 30 0.18258 11 490.339 21 885.262 31 14.5981 12 486.534 22 885.029 32 13.9457 13 486.534 23 885.029 33 13.9457 0 3DFACE 8 5 10 503.626 20 1064.41 30 0.18258 11 490.339 21 885.262 31 14.5981 12 503.672 22 1064.41 32 0.197797 13 503.672 23 1064.41 33 0.197797 0 3DFACE 8 5 10 503.672 20 1064.41 30 0.197797 11 494.151 21 885.494 31 15.2222 12 490.339 22 885.262 32 14.5981 13 490.339 23 885.262 33 14.5981 0 3DFACE 8 5 10 503.672 20 1064.41 30 0.197797 11 494.151 21 885.494 31 15.2222 12 503.719 22 1064.42 32 0.213014 13 503.719 23 1064.42 33 0.213014 0 3DFACE 8 5 10 503.719 20 1064.42 30 0.213014 11 497.969 21 885.726 31 15.8232 12 494.151 22 885.494 32 15.2222 13 494.151 23 885.494 33 15.2222 0 3DFACE 8 5 10 503.719 20 1064.42 30 0.213014 11 497.969 21 885.726 31 15.8232 12 503.766 22 1064.43 32 0.228232 13 503.766 23 1064.43 33 0.228232 0 3DFACE 8 5 10 503.766 20 1064.43 30 0.228232 11 501.792 21 885.959 31 16.4044 12 497.969 22 885.726 32 15.8232 13 497.969 23 885.726 33 15.8232 0 3DFACE 8 5 10 503.766 20 1064.43 30 0.228232 11 501.792 21 885.959 31 16.4044 12 503.813 22 1064.44 32 0.243449 13 503.813 23 1064.44 33 0.243449 0 3DFACE 8 5 10 503.813 20 1064.44 30 0.243449 11 505.62 21 886.191 31 16.9673 12 501.792 22 885.959 32 16.4044 13 501.792 23 885.959 33 16.4044 0 3DFACE 8 5 10 503.813 20 1064.44 30 0.243449 11 505.62 21 886.191 31 16.9673 12 503.86 22 1064.45 32 0.258667 13 503.86 23 1064.45 33 0.258667 0 3DFACE 8 5 10 503.86 20 1064.45 30 0.258667 11 509.453 21 886.423 31 17.5127 12 505.62 22 886.191 32 16.9673 13 505.62 23 886.191 33 16.9673 0 3DFACE 8 5 10 503.86 20 1064.45 30 0.258667 11 509.453 21 886.423 31 17.5127 12 503.907 22 1064.46 32 0.273885 13 503.907 23 1064.46 33 0.273885 0 3DFACE 8 5 10 503.907 20 1064.46 30 0.273885 11 513.29 21 886.656 31 18.0401 12 509.453 22 886.423 32 17.5127 13 509.453 23 886.423 33 17.5127 0 3DFACE 8 5 10 503.907 20 1064.46 30 0.273885 11 513.29 21 886.656 31 18.0401 12 503.953 22 1064.47 32 0.289104 13 503.953 23 1064.47 33 0.289104 0 3DFACE 8 5 10 503.953 20 1064.47 30 0.289104 11 517.132 21 886.888 31 18.5488 12 513.29 22 886.656 32 18.0401 13 513.29 23 886.656 33 18.0401 0 3DFACE 8 5 10 503.953 20 1064.47 30 0.289104 11 517.132 21 886.888 31 18.5488 12 504 22 1064.47 32 0.304322 13 504 23 1064.47 33 0.304322 0 3DFACE 8 5 10 504 20 1064.47 30 0.304322 11 520.98 21 887.121 31 19.0377 12 517.132 22 886.888 32 18.5488 13 517.132 23 886.888 33 18.5488 0 3DFACE 8 5 10 512.49 20 975.798 30 9.67103 11 520.98 21 887.121 31 19.0377 12 518.3 22 916.699 32 16.5978 13 518.3 23 916.699 33 16.5978 0 3DFACE 8 5 10 512.49 20 975.798 30 9.67103 11 518.3 21 916.699 31 16.5978 12 515.555 22 946.27 32 13.8877 13 515.555 23 946.27 33 13.8877 0 3DFACE 8 5 10 512.49 20 975.798 30 9.67103 11 515.555 21 946.27 31 13.8877 12 512.747 22 975.833 32 10.9045 13 512.747 23 975.833 33 10.9045 0 3DFACE 8 5 10 512.49 20 975.798 30 9.67103 11 512.747 21 975.833 31 10.9045 12 509.883 22 1005.39 32 7.64521 13 509.883 23 1005.39 33 7.64521 0 3DFACE 8 5 10 512.49 20 975.798 30 9.67103 11 509.883 21 1005.39 31 7.64521 12 506.967 22 1034.94 32 4.10714 13 506.967 23 1034.94 33 4.10714 0 3DFACE 8 5 10 512.49 20 975.798 30 9.67103 11 506.967 21 1034.94 31 4.10714 12 504 22 1064.47 32 0.304322 13 504 23 1064.47 33 0.304322 0 ENDSEC 0 EOF sailcut-1.5.0/src/examples/Star45-JIB.xml000066400000000000000000000027431477005247400200140ustar00rootroot00000000000000 sailcut-1.5.0/src/examples/main.saildef000066400000000000000000000035711477005247400200630ustar00rootroot00000000000000 sailcut-1.5.0/src/filewriter.h000066400000000000000000000113001477005247400163020ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FILEWRITER_H #define FILEWRITER_H #include #include #include #include class read_error : public std::runtime_error { public: read_error(const std::string &message) : std::runtime_error(message) { std::cout << what() << std::endl; } }; class write_error : public std::runtime_error { public: write_error(const std::string &message) : std::runtime_error(message) { std::cout << what() << std::endl; } }; /** This is a generic class used as the base for various file * input and output modules. */ template class CFileWriter : public QObject { public: /** The constructor. * * @param ext the file extension * @param desc description of the file type */ CFileWriter(const QString &ext, const QString &desc) : _ext(ext) , _desc(desc) {}; /** Return the file extension associated with this CFileWriter. */ QString fileExtension() const { return _ext; }; QString getOpenFileName(const QString &filename) const { return QFileDialog::getOpenFileName(0, tr("Open"), QFileInfo(filename).absolutePath(), _desc + " (*" + _ext + ")"); }; QString getSaveFileName(const QString &filename) const { QString newfilename = QFileDialog::getSaveFileName(0, tr("Save"), filename, _desc + " (*" + _ext + ")"); if (!newfilename.isNull() && newfilename.right(_ext.length()).toLower() != _ext) newfilename += _ext; return newfilename; }; /** Perform the actual reading operation, may be overriden * to provide this functionality. */ virtual const objtype read(const QString &) const { throw std::logic_error("Reading is not supported for this file type."); }; /** Display a dialog then read file. * * @param dest the object we read to * @param filename initial file name */ QString readDialog(objtype &dest, const QString &filename = QString()) const { const QString newfilename = getOpenFileName(filename); if (!newfilename.isNull()) { try { dest = read(newfilename); } catch (read_error const&) { readErrorMessage(); return QString(); } } return newfilename; }; /** Show an error message indicating that reading failed. */ static void readErrorMessage() { QMessageBox::information(0, tr("error"), tr("There was an error reading from the selected file.")); }; /** Perform the actual writing operation, must be overriden. */ virtual void write(const objtype &, const QString &) const = 0; /** Opens of a dialog to ask for a filename * then writes to a file. * * @param obj The object to write. * @param filename The filename to start off with (default = "") */ QString writeDialog(const objtype &obj, const QString &filename = QString()) const { const QString newfilename = getSaveFileName(filename); if (!newfilename.isNull()) { try { write(obj, newfilename); } catch (write_error const&) { writeErrorMessage(); return QString(); } } return newfilename; }; /** Show an error message indicating that writing failed. */ static void writeErrorMessage() { QMessageBox::information(0, tr("error"), tr("There was an error writing to the selected file.")); }; /** * Returns whether the given file is associated with this CFileWriter. */ bool isDocument(QString filename) const { return (filename.right(_ext.length()).toLower() == _ext); }; protected: /** file extension */ QString _ext; /** description of the file type */ QString _desc; }; #endif sailcut-1.5.0/src/formboat.cpp000066400000000000000000000114261477005247400163030ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "formboat.h" #include "boatdef-panel.h" #include "sailcpp/hullworker.h" #include "sailcpp/sailworker.h" #include "sailcpp/rigworker.h" #include "sailwriter-xml.h" #include #include #include #include #include /** * The constructor. * * @param parent the parent widget */ CFormBoat::CFormBoat(QWidget *parent) : CFormMain(parent) { // create main widget setupMainWidget(); // create menu bar setupMenuBar(); // set language connect(qApp, SIGNAL(languageChanged()), this, SLOT(languageChange())); languageChange(); // set initial definition setDef(def); } /** * Adds a new element to the boat. * * @param newfile name of the file to add */ void CFormBoat::add(const QString &newfile) { CBoatElement element; if (CSailDefXmlWriter().isDocument(newfile)) { CSailDef saildef = CSailDefXmlWriter().read(newfile); (CPanelGroup&)element = CSailWorker(saildef).makeSail(); element.type = SAILDEF; } else if (CHullDefXmlWriter().isDocument(newfile)) { CHullDef hulldef = CHullDefXmlWriter().read(newfile); (CPanelGroup&)element = CHullWorker(hulldef).makeHull(); element.type = HULLDEF; } else if (CRigDefXmlWriter().isDocument(newfile)) { CRigDef rigdef = CRigDefXmlWriter().read(newfile); (CPanelGroup&)element = CRigWorker(rigdef).makeRig(); element.type = RIGDEF; } else if (CPanelGroupXmlWriter().isDocument(newfile)) { (CPanelGroup&)element = CPanelGroupXmlWriter().read(newfile); element.type = PANELGROUP; } else { throw std::invalid_argument("CFormBoat::add : unknown document type"); } element.filename = newfile.toStdString(); def.push_back(element); setDef(def); } /** * Sets the strings of the subwidgets using the current * language. */ void CFormBoat::languageChange() { setWindowTitle( tr("boat") ); menuAdd->setTitle( tr("&Add") ); actionAddFile->setText( tr("file") ); } bool CFormBoat::read(const QString &filename) { try { setDef(writer.read(filename)); return true; } catch (read_error const&) { return false; } } bool CFormBoat::write(const QString &filename) { try { writer.write(def, filename); return true; } catch (write_error const&) { return false; } } /** * We got a new boat definition, update widgets. * * @param newdef The new boat definition */ void CFormBoat::setDef(const CBoatDef &newdef) { def = newdef; defpanel->setDef(def); tabs->setObject(def.makePanelGroup()); } /** * Creates the main widget */ void CFormBoat::setupMainWidget() { tabs = new CSailViewerTabs(this); defpanel = new CBoatDefPanel(this); QSplitter *splitter = new QSplitter(Qt::Horizontal, this); splitter->addWidget(tabs); splitter->addWidget(defpanel); setCentralWidget(splitter); connect(defpanel, SIGNAL(signalUpdate(const CBoatDef& )), this, SLOT(slotUpdate(const CBoatDef& ))); } /** * Creates the menu bar */ void CFormBoat::setupMenuBar() { menuAdd = new QMenu(this); actionAddFile = menuAdd->addAction( "", this, SLOT( slotAdd() ) ); addFileMenu(menuAdd); } /** * The file menu's "Add" item was clicked. */ void CFormBoat::slotAdd() { QString filter = "Sailcut CAD files ("; filter += QString("*") + CSailDefXmlWriter().fileExtension(); filter += QString(" *") + CHullDefXmlWriter().fileExtension(); filter += QString(" *") + CRigDefXmlWriter().fileExtension(); filter += QString(" *") + CPanelGroupXmlWriter().fileExtension(); filter += ")"; QString newfile = QFileDialog::getOpenFileName(0, tr("Open"), "", filter); if ( !newfile.isNull() ) add(newfile); } /** * The boat definition was modified by the user. * * @param newdef The new boat definition */ void CFormBoat::slotUpdate(const CBoatDef& newdef) { setDef(newdef); } sailcut-1.5.0/src/formboat.h000066400000000000000000000034201477005247400157430ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FORMBOAT_H #define FORMBOAT_H #include "formmain.h" #include "sailwriter-xml.h" class CBoatDefPanel; /** A form allowing the user to assemble several elements into a boat. */ class CFormBoat : public CFormMain { Q_OBJECT public: CFormBoat(QWidget *parent = 0); protected: QString getSaveFileName(const QString &filename) { return writer.getSaveFileName(filename); }; bool read(const QString &filename); bool write(const QString &filename); private slots: void languageChange(); void slotAdd(); void slotUpdate(const CBoatDef& newdef); private: void add(const QString &newfile); void setDef(const CBoatDef &newdef); void setupMainWidget(); void setupMenuBar(); CBoatDef def; CBoatDefXmlWriter writer; /** A panel with one tab per element in the current boat. */ CBoatDefPanel *defpanel; /** The Add menu. */ QMenu *menuAdd; /** add a file */ QAction *actionAddFile; }; #endif sailcut-1.5.0/src/formhull.cpp000066400000000000000000000051441477005247400163220ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "formhull.h" #include "formhulldef.h" #include "sailcpp/hullworker.h" #include /** * Constructs a window to display a hull. * * @param parent the parent widget */ CFormHull::CFormHull(QWidget *parent) : CFormMain(parent) { // create menu bar setupMenuBar(); // create main widget tabs = new CSailViewerTabs(this); setCentralWidget(tabs); // set language connect(qApp, SIGNAL(languageChanged()), this, SLOT(languageChange())); languageChange(); // set initial definition setDef(def); } /** * Sets the strings of the subwidgets using the current * language. */ void CFormHull::languageChange() { setWindowTitle( tr("hull") ); actionViewDef->setText( tr("&Dimensions") ); } bool CFormHull::read(const QString &filename) { try { setDef(writer.read(filename)); return true; } catch (read_error const&) { return false; } } bool CFormHull::write(const QString &filename) { try { writer.write(def, filename); return true; } catch (write_error const&) { return false; } } /** * Replaces the current sail definition. * * @param newdef */ void CFormHull::setDef(const CHullDef& newdef) { def = newdef; tabs->setObject(CHullWorker(def).makeHull()); } /** * Creates the menu bar */ void CFormHull::setupMenuBar() { // view actions actionViewDef = new QAction(this); connect( actionViewDef, SIGNAL( triggered() ), this, SLOT( slotDef() ) ); addViewAction(actionViewDef); } /** * Displays the sail CFormHullDef sail definition dialog. */ void CFormHull::slotDef() { CHullDef defcopy = def; if ( CFormHullDef(this, &defcopy).exec() ) { // we returned from the dialog with an 'OK', setDef(defcopy); } } sailcut-1.5.0/src/formhull.h000066400000000000000000000027351477005247400157720ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FORMHULL_H #define FORMHULL_H #include "formmain.h" #include "sailwriter-xml.h" /** Dialog holding a hull. */ class CFormHull : public CFormMain { Q_OBJECT public: CFormHull(QWidget *parent = 0); protected: QString getSaveFileName(const QString &filename) { return writer.getSaveFileName(filename); }; bool read(const QString &filename); bool write(const QString &filename); private slots: void languageChange(); void slotDef(); private: void setDef(const CHullDef& newdef); void setupMenuBar(); CHullDef def; CHullDefXmlWriter writer; /** view hull definition */ QAction *actionViewDef; }; #endif sailcut-1.5.0/src/formhulldef.cpp000066400000000000000000000210371477005247400170000ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "formhulldef.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// /** The constructor. * * @param parent the parent window * @param hullptr pointer to the CHullDef */ CFormHullDef::CFormHullDef( QWidget* parent, CHullDef * hullptr ) : QDialog(parent) { setupUi(this); setModal(true); /* we store the pointer to the CHullDef so we can update it when the user clicks OK */ hulldef = hullptr; txt_HullID->setText(QString::fromStdString(hulldef->hullID)); /// deck parameters txt_BLWL->setText( QString::number(hulldef->BLWL) ); txt_DfwdHeight->setText( QString::number(hulldef->DfwdHeight) ); txt_DaftHeight->setText( QString::number(hulldef->DaftHeight) ); txt_BBW->setText( QString::number(hulldef->BBW) ); txt_BaftW->setText( QString::number(hulldef->BaftW) ); spinBox_BSlopeA->setValue(hulldef->BSlopeA); spinBox_BBWPos->setValue(hulldef->BBWPos); spinBox_StemA->setValue(hulldef->StemA); spinBox_TransomA->setValue(hulldef->TransomA); spinBox_BfwdShape->setValue(hulldef->BfwdShape); spinBox_BaftShape->setValue(hulldef->BaftShape); /// bottom parameters txt_BfwdHeight->setText( QString::number(hulldef->BfwdHeight) ); txt_BaftHeight->setText( QString::number(hulldef->BaftHeight) ); spinBox_BSlopeA->setValue(hulldef->BSlopeA); spinBox_BDeadriseA->setValue(hulldef->BDeadriseA); spinBox_BSweepA->setValue(hulldef->BSweepA); /// planking parameters spinBox_NBPlank->setValue(hulldef->NBPlank); spinBox_TopPlankA->setValue(hulldef->TopPlankA); spinBox_LowPlankA->setValue(hulldef->LowPlankA); checkBox_AutoPlank->setChecked(hulldef->AutoPlank); /// signal and slots connections connect( btnCheck, SIGNAL( clicked() ), this, SLOT( slotCheck() ) ); connect( btnOK, SIGNAL( clicked() ), this, SLOT( accept() ) ); connect( btnCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); // resize resize(minimumSizeHint()); } // Qt overrides /** Saves the parameters entered by the user in the CHullDef. * slot connected to OK button */ void CFormHullDef::accept() { // return data if everything is OK. ///////////////////////// if (check() == true) QDialog::accept(); } /** slot for dealing with automatic planking */ void CFormHullDef::slotAutoPlank() { if (checkBox_AutoPlank->isChecked() ) hulldef->AutoPlank = true; check(); } /** slot for dealing with check button */ void CFormHullDef::slotCheck() { check(); } /** Check all dimensions entered in order * to make sure that the hull is possible and reasonable */ bool CFormHullDef::check() { /// return true IF everything is OK long L1=1; // real A1=0, A2=0; bool flag = true; QString txt; /// create four palettes QPalette palStd, palHi, palLo, palRel; palStd = txt_HullID->palette(); palLo = palHi = palRel = palStd; palLo.setColor( QPalette::Text, Qt::magenta); // too low value palHi.setColor( QPalette::Text, Qt::red ); // too high value palRel.setColor( QPalette::Text, Qt::blue ); // related value to be checked /// check hull ID txt = txt_HullID->text(); txt = txt.simplified(); if (txt.length() > 40) { txt.truncate(40); flag = false; txt_HullID->setPalette(palHi); txt_HullID->setText(QString(txt)); } else { txt_HullID->setPalette(palStd); txt_HullID->setText(QString(txt)); } hulldef->hullID = txt.toStdString(); /// check bottom data hulldef->BLWL = txt_BLWL->text().toDouble(); // length waterline if (hulldef->BLWL < 100) { flag = false; txt_BLWL->setPalette(palLo); hulldef->BLWL = 100; } else if (hulldef->BLWL > 100000) { flag = false; txt_BLWL->setPalette(palHi); hulldef->BLWL = 100000; } else { txt_BLWL->setPalette(palStd); } txt_BLWL->setText(QString::number(hulldef->BLWL)); L1 = (long)(hulldef->BLWL); // lower chine height hulldef->BfwdHeight = txt_BfwdHeight->text().toDouble(); if (hulldef->BfwdHeight > L1/5) { flag = false; txt_BfwdHeight->setPalette(palHi); hulldef->BfwdHeight = floor(L1 / 5); } else { txt_BfwdHeight->setPalette(palStd); } txt_BfwdHeight->setText(QString::number(hulldef->BfwdHeight)); hulldef->BaftHeight = txt_BaftHeight->text().toDouble(); if (hulldef->BaftHeight > L1 / 5) { flag = false; txt_BaftHeight->setPalette(palHi); hulldef->BaftHeight = floor(L1 / 5); } else { txt_BaftHeight->setPalette(palStd); } txt_BaftHeight->setText(QString::number(hulldef->BaftHeight)); // bottom width hulldef->BBW = txt_BBW->text().toDouble(); if (hulldef->BBW < L1/20) { flag = false; txt_BBW->setPalette(palLo); hulldef->BBW = ceil(L1/20); } else if (hulldef->BBW > L1/2) { flag = false; txt_BBW->setPalette(palHi); hulldef->BBW = floor(L1/2); } else { txt_BBW->setPalette(palStd); } txt_BBW->setText(QString::number(hulldef->BBW)); hulldef->BaftW = txt_BaftW->text().toDouble(); if (hulldef->BaftW < 0) { flag = false; txt_BaftW->setPalette(palLo); hulldef->BaftW = 0; } else if (hulldef->BaftW > hulldef->BBW) { flag = false; txt_BaftW->setPalette(palHi); hulldef->BaftW = floor(hulldef->BBW); } else { txt_BaftW->setPalette(palStd); } txt_BaftW->setText(QString::number(hulldef->BaftW)); hulldef->BBWPos = spinBox_BBWPos->value(); // bottom shape hulldef->BfwdShape = spinBox_BfwdShape->value(); hulldef->BaftShape = spinBox_BaftShape->value(); hulldef->BSlopeA = spinBox_BSlopeA->value(); hulldef->BDeadriseA = spinBox_BDeadriseA->value(); hulldef->BSweepA = spinBox_BSweepA->value(); hulldef->StemA = spinBox_StemA->value(); hulldef->TransomA = spinBox_TransomA->value(); /// check deck data hulldef->DfwdHeight = txt_DfwdHeight->text().toDouble(); if (hulldef->DfwdHeight < (hulldef->BfwdHeight + L1 / 20) ) { flag = false; txt_DfwdHeight->setPalette(palLo); hulldef->DfwdHeight = ceil( hulldef->BfwdHeight + L1 / 20 ); } else if (hulldef->DfwdHeight > ( L1 / 4 ) ) { flag = false; txt_DfwdHeight->setPalette(palHi); hulldef->DfwdHeight = floor( L1 / 4 ); } else { txt_DfwdHeight->setPalette(palStd); } txt_DfwdHeight->setText(QString::number(hulldef->DfwdHeight)); hulldef->DaftHeight = txt_DaftHeight->text().toDouble(); if (hulldef->DaftHeight < (hulldef->BaftHeight + L1 / 20) ) { flag = false; txt_DaftHeight->setPalette(palLo); hulldef->DaftHeight = ceil( hulldef->BaftHeight + L1 / 20); } else if (hulldef->DaftHeight > ( L1 / 4 ) ) { flag = false; txt_DaftHeight->setPalette(palHi); hulldef->DaftHeight = floor( L1 / 4 ); } else { txt_DaftHeight->setPalette(palStd); } txt_DaftHeight->setText(QString::number(hulldef->DaftHeight)); /// planking parameters hulldef->NBPlank = spinBox_NBPlank->value(); hulldef->TopPlankA = spinBox_TopPlankA->value(); hulldef->LowPlankA = spinBox_LowPlankA->value(); /// check automatic planking if (checkBox_AutoPlank->isChecked() ) hulldef->AutoPlank = true; else hulldef->AutoPlank = false; /// return true IF everything is OK return flag; } sailcut-1.5.0/src/formhulldef.h000066400000000000000000000025201477005247400164410ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FORMHULLDEF_H #define FORMHULLDEF_H #include "ui_formhulldefbase.h" #include "sailcpp/hulldef.h" /** The hull definition dialog, where the user enters * the parameters of the hull. */ class CFormHullDef : public QDialog, private Ui::CFormHullDefBase { Q_OBJECT public: CFormHullDef( QWidget *, CHullDef* ); bool check(); virtual void accept(); protected slots: void slotAutoPlank(); void slotCheck(); protected: /** a pointer to the hull definion */ CHullDef *hulldef; }; #endif sailcut-1.5.0/src/formhulldefbase.ui000066400000000000000000001655761477005247400175070ustar00rootroot00000000000000 Robert lainé CFormHullDefBase 0 0 641 567 640 555 Dialog 5 5 4 10 Qt::Horizontal 381 31 Check OK Cancel 50 false 1 Deck and bottom 9 6 50 false Planking 9 6 Automatic planking true false Qt::Horizontal QSizePolicy::MinimumExpanding 31 20 60 22 Qt::AlignHCenter 45 30 40 lower plank angle 0 0 0 0 60 22 Qt::AlignHCenter 45 85 0 0 0 0 60 22 Qt::AlignHCenter 6 1 2 top plank angle Number of planks 0 0 0 0 Bottom 9 6 0 0 0 0 60 22 Qt::AlignHCenter 60 Qt::Horizontal 211 20 0 0 0 0 Bottom sweep angle 0 0 0 0 20 22 % 0 0 0 0 60 22 Qt::AlignHCenter 80 20 50 0 0 0 0 60 22 Qt::AlignHCenter 50 0 0 0 0 60 22 Qt::AlignHCenter 90 45 80 0 0 0 0 60 22 txt_BBW Max Width 0 0 0 0 60 22 txt_BfwdHeight 0 0 0 0 60 22 txt_BLWL 0 0 0 0 60 22 txt_BaftW 60 22 Qt::AlignHCenter 9 2 0 0 0 0 60 22 Qt::AlignHCenter 9 2 0 0 0 0 60 22 Qt::AlignHCenter 30 12 0 0 0 0 60 22 txt_BaftHeight 0 0 0 0 60 22 Qt::AlignHCenter 99 45 80 0 0 0 0 Dead rise angle Forward shape Length 0 0 0 0 Forward height Max Width position 0 0 0 0 Chine angle Stem angle Transom angle 0 0 0 0 Aft height Aft width Aft shape QFrame::StyledPanel QFrame::Plain 6 6 400 22 txt_HullID 0 0 0 0 60 20 Hull name Deck 9 6 0 0 0 0 60 22 Qt::AlignHCenter 24 0 12 0 0 0 0 60 22 txt_DaftHeight 0 0 0 0 60 22 txt_DfwdHeight Forward height Side angle Aft height Planks 9 6 Plank 6 3 5 Chine angle Sweep angle Plank angle Aft height Forward height 0 0 0 0 110 22 100 0 0 0 0 60 22 0 0 0 0 60 22 0 0 0 0 60 22 0 0 0 0 110 22 Plank 5 3 5 Chine angle Sweep angle Plank angle Aft height Forward height 0 0 0 0 110 22 100 0 0 0 0 60 22 0 0 0 0 60 22 0 0 0 0 60 22 0 0 0 0 110 22 Plank 4 3 5 Chine angle Sweep angle Plank angle Aft height Forward height 0 0 0 0 110 22 100 0 0 0 0 60 22 0 0 0 0 60 22 0 0 0 0 60 22 0 0 0 0 110 22 Plank 3 3 5 Chine angle Sweep angle Plank angle Aft height Forward height 0 0 0 0 110 22 100 0 0 0 0 60 22 0 0 0 0 60 22 0 0 0 0 60 22 0 0 0 0 110 22 Plank 1 3 5 Chine angle Sweep angle Plank angle Aft height Forward height 0 0 0 0 110 22 100 0 0 0 0 60 22 0 0 0 0 60 22 0 0 0 0 60 22 0 0 0 0 110 22 Plank 2 3 5 0 0 0 0 110 22 0 0 0 0 60 22 0 0 0 0 60 21 0 0 0 0 60 22 0 0 0 0 110 22 100 Forward height Aft height Plank angle Sweep angle Chine angle Qt::Vertical 20 20 0 0 0 0 620 25 75 true QFrame::StyledPanel QFrame::Raised Dimensions are in millimeters and angles in degrees measured from horizontal Qt::AlignCenter 4 tabWidget txt_HullID txt_BLWL txt_DfwdHeight txt_DaftHeight txt_BBW spinBox_BBWPos txt_BaftW spinBox_StemA txt_BfwdHeight txt_BaftHeight spinBox_BDeadriseA spinBox_BSweepA spinBox_NBPlank checkBox_AutoPlank spinBox_TopPlankA spinBox_LowPlankA btnOK btnCancel spinBox_1_1 spinBox_1_2 spinBox_1_3 spinBox_1_4 spinBox_1_5 spinBox_1_6 spinBox_1_10 spinBox_1_9 spinBox_1_8 spinBox_1_7 spinBox_1_11 spinBox_1_15 spinBox_1_14 spinBox_1_13 spinBox_1_12 spinBox_1_16 spinBox_1_20 spinBox_1_19 spinBox_1_18 spinBox_1_17 spinBox_1_21 spinBox_1_25 spinBox_1_24 spinBox_1_23 spinBox_1_22 spinBox_1_26 spinBox_1_30 spinBox_1_29 spinBox_1_28 spinBox_1_27 sailcut-1.5.0/src/formmain.cpp000066400000000000000000000236331477005247400163050ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "app.h" #include "formmain.h" #include "formsail.h" #include "formhull.h" #include "formrig.h" #include "formpanelgroup.h" #include "formboat.h" #include "sailcut.xpm" /** * Constructs Sailcut CAD's main window. * * @param parent the parent widget */ CFormMain::CFormMain(QWidget *parent) : QMainWindow(parent) { app = qobject_cast(qApp); setMinimumSize( QSize( 400, 400 ) ); setWindowIcon( QPixmap( (const char **)sailcut_xpm ) ); // create status bar statusbar = new QStatusBar(this); setStatusBar(statusbar); // create menu bar setupMenuBar(); // set language connect(qApp, SIGNAL(languageChanged()), this, SLOT(languageChange())); languageChange(); // set recent documents connect(qApp, SIGNAL(recentDocumentsChanged()), this, SLOT(recentDocumentsChanged())); recentDocumentsChanged(); // resize to preferred size resize(app->windowSize().expandedTo(minimumSizeHint())); } void CFormMain::addFileMenu(QMenu *menu) { menuFile->insertMenu(actionFileSep, menu); } void CFormMain::addViewAction(QAction *action) { menuView->insertAction(menuLanguage->menuAction(), action); } /** * This event is received when the user closes the dialog. */ void CFormMain::closeEvent(QCloseEvent *e) { app->setWindowSize(size()); QMainWindow::closeEvent(e); } /** * Sets the strings of the subwidgets using the current * language. */ void CFormMain::languageChange() { setWindowTitle( "Sailcut CAD" ); menuFile->setTitle( tr("&File") ); menuFileNew->setTitle( tr("&New") ); actionNewSail->setText( tr("sail") ); actionNewHull->setText( tr("hull") ); actionNewRig->setText( tr("rig") ); actionNewBoat->setText( tr("boat") ); actionOpen->setText( tr("&Open") ); menuRecent->setTitle( tr("Open &recent") ); actionSave->setText( tr("&Save") ); actionSaveAs->setText( tr("Save &As") ); actionQuit->setText( tr("&Quit") ); // View menu menuView->setTitle( tr("&View") ); menuLanguage->setTitle( tr("Language") ); // Help menu menuHelp->setTitle( tr("&Help") ); actionHandbook->setText( tr("Sailcut CAD &Handbook") ); actionAboutQt->setText( tr("About &Qt") ); actionAbout->setText( tr("About &Sailcut CAD") ); } bool CFormMain::load(const QString &filename) { if (read(filename)) { statusbar->showMessage(tr("loaded '%1'").arg(filename)); app->addRecentDocument(filename); this->filename = filename; return true; } else { statusbar->showMessage( tr("error loading '%1'").arg(filename) ); app->removeRecentDocument(filename); return false; } } /** * Creates the "Open Recent" menu from the Most Recently Used files list. */ void CFormMain::recentDocumentsChanged() { menuRecent->clear(); foreach (const QString &document, app->recentDocuments()) menuRecent->addAction(document, this, SLOT(slotOpenRecent()))->setData(document); } /** * Creates the menu bar */ void CFormMain::setupMenuBar() { // File menu menuFile = menuBar()->addMenu(""); menuFileNew = menuFile->addMenu(""); actionNewSail = menuFileNew->addAction("", app, SLOT(createSail())); actionNewHull = menuFileNew->addAction("", app, SLOT(createHull())); actionNewRig = menuFileNew->addAction("", app, SLOT(createRig())); actionNewBoat = menuFileNew->addAction("", app, SLOT(createBoat())); actionOpen = menuFile->addAction("", this, SLOT( slotOpen() ) ); menuRecent = menuFile->addMenu(""); menuFile->addSeparator(); actionSave = menuFile->addAction("", this, SLOT( slotSave() ) ); actionSaveAs = menuFile->addAction("", this, SLOT( slotSaveAs() ) ); actionFileSep = menuFile->addSeparator(); actionQuit = menuFile->addAction( "", this, SLOT( close() ) ); // View menu menuView = menuBar()->addMenu(""); menuLanguage = menuView->addMenu(""); // language text is not to be translated menuLanguage->addAction( "English", this, SLOT( slotLanguage() ) )->setData("en"); menuLanguage->addAction( QString::fromUtf8("Français"), this, SLOT( slotLanguage() ) )->setData("fr"); menuLanguage->addAction( "Nederlands", this, SLOT( slotLanguage() ) )->setData("nl"); menuLanguage->addAction( "Deutsch", this, SLOT( slotLanguage() ) )->setData("de"); menuLanguage->addAction( "Italiano", this, SLOT( slotLanguage() ) )->setData("it"); menuLanguage->addAction( "Norsk", this, SLOT( slotLanguage() ) )->setData("no"); menuLanguage->addAction( "Dansk", this, SLOT( slotLanguage() ) )->setData("dk"); // menuLanguage->addAction( "Svenska", this, SLOT( slotLanguage() ) )->setData("sv"); menuLanguage->addAction( QString::fromUtf8("Portugês"), this, SLOT( slotLanguage() ) )->setData("pt"); // menuLanguage->addAction( QString::fromUtf8("Español"), this, SLOT( slotLanguage() ) )->setData("es"); menuLanguage->addAction( "Russian", this, SLOT( slotLanguage() ) )->setData("ru"); //menuLanguage->addAction( "Polish", this, SLOT( slotLanguage() ) )->setData("pl"); // Help menu menuHelp = menuBar()->addMenu(""); actionHandbook = menuHelp->addAction( "", app, SLOT( showHandbook() ) ); actionAboutQt = menuHelp->addAction( "", this, SLOT( slotAboutQt() ) ); actionAbout = menuHelp->addAction( "", this, SLOT( slotAbout() ) ); } /** * Displays the "About Sailcut CAD" dialog box */ void CFormMain::slotAbout() { QMessageBox::about( this, tr("About Sailcut CAD"), "

Sailcut CAD " SAILCUT_VERSION "

" "

Sailcut is a software for designing boat sails
" "Copyright (C) Robert Lainé & Jeremy Lainé" "

For more information, visit the project's page at http://www.sailcut.com/.

" "

Sailcut is a trademark registered by Robert Lainé

" "
" "This program is free software; you can redistribute it and/or modify " "it under the terms of the GNU General Public License as published by " "the Free Software Foundation; either version 2 of the License, or " "(at your option) any later version.

" "This program is distributed in the hope that it will be useful, " "but WITHOUT ANY WARRANTY; without even the implied warranty of " "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " "GNU General Public License for more details.

" "You should have received a copy of the GNU General Public License " "along with this program; if not, write to the Free Software " "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA" "
" ); } /** * Displays the "About Qt" dialog box */ void CFormMain::slotAboutQt() { QMessageBox::aboutQt( this ); } /** * Switches the current language. */ void CFormMain::slotLanguage() { QAction *a = qobject_cast(sender()); if (a) app->setLanguage(a->data().toString()); } /** * Displays a dialog box to open an XML sail definition. */ void CFormMain::slotOpen() { QString filter = "Sailcut CAD files ("; filter += QString("*") + CSailDefXmlWriter().fileExtension(); filter += QString(" *") + CHullDefXmlWriter().fileExtension(); filter += QString(" *") + CRigDefXmlWriter().fileExtension(); filter += QString(" *") + CBoatDefXmlWriter().fileExtension(); filter += QString(" *") + CPanelGroupXmlWriter().fileExtension(); filter += ")"; QString newfile = QFileDialog::getOpenFileName(0, tr("Open"), "", filter); if ( !newfile.isNull() ) app->open(newfile); } /** * Opens a recently used sail definition. */ void CFormMain::slotOpenRecent() { QAction *a = qobject_cast(sender()); if (a) app->open(a->data().toString()); } /** * Saves the current sail definition to an XML file. */ void CFormMain::slotSave() { if (filename.isEmpty()) { slotSaveAs(); return; } if (write(filename)) { statusbar->showMessage(tr("wrote '%1'").arg(filename)); app->addRecentDocument(filename); } else { QMessageBox::information(0, tr("error"), tr("There was an error writing to the selected file.")); } } /** * Opens a dialog to select the XML to which the sail definition should be saved. */ void CFormMain::slotSaveAs() { const QString newfilename = getSaveFileName(filename); if (newfilename.isNull()) return; if (write(newfilename)) { filename = newfilename; statusbar->showMessage(tr("wrote '%1'").arg(filename)); app->addRecentDocument(filename); } else { QMessageBox::information(0, tr("error"), tr("There was an error writing to the selected file.")); } } sailcut-1.5.0/src/formmain.h000066400000000000000000000065771477005247400157620ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FORMMAIN_H #define FORMMAIN_H #include #include #include "sailviewer-tabs.h" // forward definitions class QAction; class QMenu; class QMenuBar; class QStatusBar; class CSailApp; /** The main dialog of the Sailcut application. */ class CFormMain : public QMainWindow { Q_OBJECT public: CFormMain(QWidget *parent = 0); bool load(const QString &filename); protected: virtual QString getSaveFileName(const QString &filename) = 0; virtual bool read(const QString &filename) = 0; virtual bool write(const QString &filename) = 0; void addFileMenu(QMenu *menu); void addViewAction(QAction *action); void closeEvent(QCloseEvent *e); private slots: void slotAbout(); void slotAboutQt(); void slotOpen(); void slotOpenRecent(); void slotSave(); void slotSaveAs(); void slotLanguage(); void languageChange(); void recentDocumentsChanged(); protected: CSailViewerTabs *tabs; private: void setupMenuBar(); /** The application */ CSailApp *app; /** The current filename. */ QString filename; /** The status bar */ QStatusBar* statusbar; /** The File menu */ QMenu *menuFile; /** The New submenu */ QMenu *menuFileNew; /** The Help menu */ QMenu *menuHelp; /** The View menu */ QMenu *menuView; /** The Language menu */ QMenu *menuLanguage; /** The Most Recently Used files menu */ QMenu *menuRecent; /** Display information about sailcut */ QAction *actionAbout; /** Display information about Qt */ QAction *actionAboutQt; /** Display the handbook */ QAction *actionHandbook; /** Create a new boat */ QAction *actionNewBoat; /** Create a new hull */ QAction *actionNewHull; /** Create a new rig */ QAction *actionNewRig; /** Create a new sail */ QAction *actionNewSail; /** Open an existing sail definition */ QAction *actionOpen; /** Save the sail definition to a file */ QAction *actionSave; /** Prompt for a filename then write the sail definition to a file */ QAction *actionSaveAs; /** Final separator in the 'File' menu before 'Quit' */ QAction *actionFileSep; /** View the sail definition */ QAction *actionViewDef; /** View the sail mould */ QAction *actionViewMould; /** View the sail patches definition */ QAction *actionViewPatch; /** View the sail rig */ QAction *actionViewRig; /** Separator in the 'Window' menu */ QAction *actionWindowSep; /** Quit */ QAction *actionQuit; }; #endif sailcut-1.5.0/src/formmould.cpp000066400000000000000000000065441477005247400165030ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "formmould.h" #include "widgetprofile.h" #include "widgetprofilevert.h" #include "sailcpp/sailmould.h" #include #include #include #include #include #include /** The constructor. * * @param parent the parent dialog * @param mouldptr pointer to the CSailMould */ CFormMould::CFormMould( QWidget *parent, CSailMould *mouldptr ) : QDialog(parent) { setModal(true); setWindowTitle( tr( "Sail mould" ) ); // we store the pointer to the CSailMould so we can update it when // the user clicks OK sailmould = mouldptr; setSizeGripEnabled( true ); QGridLayout* CFormMouldLayout = new QGridLayout( this ); // Add the buttons at the bottom of the screen QHBoxLayout* buttonsLayout = new QHBoxLayout(); buttonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); buttonOk = new QPushButton( tr("&OK"), this ); buttonOk->setDefault( true ); buttonsLayout->addWidget( buttonOk ); buttonCancel = new QPushButton( tr("&Cancel"), this ); buttonsLayout->addWidget( buttonCancel ); CFormMouldLayout->addLayout( buttonsLayout, 1, 1 ); // add vertical repartition widgetVert = new CWidgetProfileVert( this, sailmould, tr("Vertical repartition") ); CFormMouldLayout->addWidget( widgetVert, 0, 0 ); // add 3 profile areas and bind them to their respective profiles QFrame* frmProfile = new QFrame( this ); frmProfile->setFrameShape( QFrame::NoFrame ); frmProfile->setFrameShadow( QFrame::Raised ); QGridLayout* frmProfileLayout = new QGridLayout( frmProfile ); CFormMouldLayout->addWidget( frmProfile, 0, 1 ); prfTop = new CWidgetProfile( frmProfile, &sailmould->profile[2], tr("Top profile"), widgetVert ); prfMiddle = new CWidgetProfile( frmProfile, &sailmould->profile[1], tr("Middle profile"), widgetVert ); prfBottom = new CWidgetProfile( frmProfile, &sailmould->profile[0], tr("Bottom profile"), widgetVert ); frmProfileLayout->addWidget( prfTop, 0, 0 ); frmProfileLayout->addWidget( prfMiddle, 1, 0 ); frmProfileLayout->addWidget( prfBottom, 2, 0 ); // init //languageChange(); resize( QSize(487, 555).expandedTo(minimumSizeHint()) ); // setting the range for profile spin boxes is done in widgetprofile.cpp prfBottom->spinDepth->setMinimum( 0 ); // signals and slots connections connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) ); connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); } sailcut-1.5.0/src/formmould.h000066400000000000000000000031561477005247400161440ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FORMMOULD_H #define FORMMOULD_H #include class QPushButton; class QGroupBox; class QLabel; class QSlider; class CWidgetProfile; class CWidgetProfileVert; class CSailMould; /** The sail mould definition dialog. */ class CFormMould : public QDialog { Q_OBJECT public: CFormMould( QWidget* , CSailMould* ); protected: /** the CSailMould */ CSailMould *sailmould; /** OK button */ QPushButton* buttonOk; /** Cancel button */ QPushButton* buttonCancel; /** the vertical repartition widget */ CWidgetProfileVert * widgetVert; /** the top CWidgetProfile */ CWidgetProfile * prfTop; /** the middle CWidgetProfile */ CWidgetProfile * prfMiddle; /** the bottom CWidgetProfile */ CWidgetProfile * prfBottom; }; #endif // FORMMOULD_H sailcut-1.5.0/src/formpanelgroup.cpp000066400000000000000000000050051477005247400175260ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "formpanelgroup.h" #include "sailtreemodel.h" #include #include #include #include /** * Constructs a window to display a collection of panels. * * @param parent the parent widget */ CFormPanelGroup::CFormPanelGroup(QWidget *parent) : CFormMain(parent) { // create main widget setupMainWidget(); // set language connect(qApp, SIGNAL(languageChanged()), this, SLOT(languageChange())); languageChange(); // set initial definition setDef(def); } /** * Sets the strings of the subwidgets using the current * language. */ void CFormPanelGroup::languageChange() { setWindowTitle( tr("panels") ); } bool CFormPanelGroup::read(const QString &filename) { try { setDef(writer.read(filename)); return true; } catch (read_error const&) { return false; } } bool CFormPanelGroup::write(const QString &filename) { try { writer.write(def, filename); return true; } catch (write_error const&) { return false; } } /** * Replaces the current sail definition. * * @param newdef */ void CFormPanelGroup::setDef(const CPanelGroup& newdef) { def = newdef; tabs->setObject(def); treeview->setModel(new CSailTreeModel(def, "panelgroup")); #if QT_VERSION >= 0x040200 treeview->expandAll(); #endif // treeview->resizeColumnToContents(0); } /** * Creates the main widget */ void CFormPanelGroup::setupMainWidget() { tabs = new CSailViewerTabs(this); treeview = new QTreeView(this); QSplitter *splitter = new QSplitter(this); splitter->addWidget(tabs); splitter->addWidget(treeview); setCentralWidget(splitter); } sailcut-1.5.0/src/formpanelgroup.h000066400000000000000000000030141477005247400171710ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FORMPANELGROUP_H #define FORMPANELGROUP_H #include "formmain.h" #include "sailwriter-xml.h" // forward definitions class QTreeView; /** Dialog holding a sail. */ class CFormPanelGroup : public CFormMain { Q_OBJECT public: CFormPanelGroup(QWidget *parent = 0); protected: QString getSaveFileName(const QString &filename) { return writer.getSaveFileName(filename); }; bool read(const QString &filename); bool write(const QString &filename); private slots: void languageChange(); private: void setDef(const CPanelGroup& newdef); void setupMainWidget(); CPanelGroup def; CPanelGroupXmlWriter writer; /** the tree view */ QTreeView *treeview; }; #endif sailcut-1.5.0/src/formprint.cpp000066400000000000000000000144371477005247400165170ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "formprint.h" #include "sailpainter.h" #include "sailprinter.h" #include #include #include #include #include #include #include #include /** Construct a new print preview label. * * @param frm the parent print form */ CPrintLabel::CPrintLabel(CFormPrint *frm) : form(frm), resizing(false) { QPalette pal = palette(); pal.setColor( QPalette::Window, Qt::white ); setPalette( pal ); // set the initial size if (form->printDevice.pageLayout().orientation() == QPageLayout::Landscape) { setMinimumSize( QSize( 375, 250 ) ); } else { setMinimumSize( QSize( 250, 375 ) ); } } /** Print the current page. */ void CPrintLabel::paintEvent(QPaintEvent *) { // erase viewport CTextPainter painter(this); QRect rect = painter.viewport(); painter.eraseRect(rect); // draw print preview real viewScale = real(heightMM()) / real(form->printDevice.heightMM()); form->printEngine->print(&painter, page, scale * viewScale, form->printFontSize * viewScale); } /** Receive a resize event. */ void CPrintLabel::resizeEvent (QResizeEvent *) { QRectF print = form->printDevice.pageRect(QPrinter::Millimeter); if (resizing || !print.width() || !print.height() || !widthMM() || !heightMM()) return; resizing = true; real rprint = real(print.width()) / real(print.height()); real rview = real(widthMM()) / real(heightMM()); if (rview > rprint) { resize(int(real(width()) / real(widthMM()) * real(heightMM()) * rprint), height()); } else { resize(width(), int(real(height()) / real(heightMM()) * real(widthMM()) / rprint)); } resizing = false; } /** Set the current page. * * @param p new the page */ void CPrintLabel::setPage(int p) { if ((p >= 0) && (p < form->printEngine->pages())) { page = p; update(); form->labelPage->setText(QString::number(p+1) + " / " + QString::number(form->printEngine->pages())); } } /** Display the previous page. */ void CPrintLabel::slotPagePrev() { setPage(page - 1); } /** Display the next page. */ void CPrintLabel::slotPageNext() { setPage(page + 1); } /** Set the printing scale. */ void CPrintLabel::slotScale(double value) { scale = value; update(); } /** Construct a new print preview dialog. * * @param engine * @param orientation */ CFormPrint::CFormPrint(const CPrinter *engine, QPageLayout::Orientation orientation) : printEngine(engine), printFontSize(10) { // initialise printer printDevice.setPageOrientation(orientation); printDevice.setFullPage(false); QVBoxLayout *layout = new QVBoxLayout(this); // create main widget label = new CPrintLabel(this); layout->addWidget(label); QHBoxLayout* buttons = new QHBoxLayout(); // add scale spinbox if applicable double scale = engine->scaleToFit(&printDevice); if (scale > 0) { labelScale = new QLabel(tr("Scale")); buttons->addWidget(labelScale); spinScale = new QDoubleSpinBox(); spinScale->setDecimals(3); spinScale->setSingleStep(0.001); buttons->addWidget(spinScale); connect( spinScale, SIGNAL( valueChanged(double) ), label, SLOT( slotScale(double) ) ); spinScale->setValue(scale); } // add the buttons buttonLeft = new QToolButton(); buttonLeft->setArrowType(Qt::LeftArrow); buttons->addWidget(buttonLeft); labelPage = new QLabel(); buttons->addWidget(labelPage); buttonRight = new QToolButton(); buttonRight->setArrowType(Qt::RightArrow); buttons->addWidget(buttonRight); buttons->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); buttonOk = new QPushButton( tr("&Print"), this ); buttonOk->setDefault( true ); buttons->addWidget( buttonOk ); buttonCancel = new QPushButton( tr("&Cancel"), this ); buttons->addWidget( buttonCancel ); layout->addLayout(buttons); // connect signals and slots connect( buttonLeft, SIGNAL( clicked() ), label, SLOT( slotPagePrev() ) ); connect( buttonRight, SIGNAL( clicked() ), label, SLOT( slotPageNext() ) ); connect( buttonOk, SIGNAL( clicked() ), this, SLOT( slotPrint() ) ); connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); label->setPage(0); // resize resize(minimumSizeHint()); } /** Print out the current data. */ void CFormPrint::slotPrint() { QPrintDialog printDialog(&printDevice); printDialog.setMinMax(1, printEngine->pages()); if ( printDialog.exec() == QDialog::Accepted ) { // determine which pages need to be printed int minPage, maxPage; switch (printDialog.printRange()) { case QAbstractPrintDialog::PageRange: minPage = printDialog.fromPage(); maxPage = printDialog.toPage(); break; default: minPage = 1; maxPage = printEngine->pages(); break; } // print the requested pages CTextPainter painter(&printDevice); for (int i = minPage - 1; i < maxPage; i ++) { if ( i >= 0 && i < printEngine->pages()) { if ( i > minPage - 1 ) printDevice.newPage(); printEngine->print(&painter, i, label->getScale(), printFontSize); } } } accept(); } sailcut-1.5.0/src/formprint.h000066400000000000000000000050121477005247400161510ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FORMPRINT_H #define FORMPRINT_H #include #include #include #include class CFormPrint; class CPrinter; class QDoubleSpinBox; class QToolButton; /** A print preview label. */ class CPrintLabel : public QLabel { Q_OBJECT public: CPrintLabel(CFormPrint *form); /** Get the current page. */ int getPage() { return page; }; double getScale() { return scale; }; void setPage(int page); public slots: void slotPagePrev(); void slotPageNext(); void slotScale(double scale); protected: void resizeEvent(QResizeEvent * event); void paintEvent(QPaintEvent *event); /** scale */ double scale; /** the current page number */ int page; /** the print preview form */ CFormPrint *form; /** is the label currently being resized? */ bool resizing; }; /** A print preview dialog. */ class CFormPrint : public QDialog { Q_OBJECT public: CFormPrint(const CPrinter *printer, QPageLayout::Orientation orientation); public slots: void slotPrint(); protected: /** display label */ CPrintLabel *label; /** scale label */ QLabel *labelScale; /** scale edit */ QDoubleSpinBox *spinScale; /** left button */ QToolButton *buttonLeft; /** page label */ QLabel *labelPage; /** right button */ QToolButton *buttonRight; /** OK button */ QPushButton *buttonOk; /** Cancel button */ QPushButton *buttonCancel; /** the printer device */ QPrinter printDevice; /** the print engine */ const CPrinter *printEngine; /** the print font size */ int printFontSize; friend class CPrintLabel; }; #endif sailcut-1.5.0/src/formrig.cpp000066400000000000000000000051361477005247400161400ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "formrig.h" #include "formrigdef.h" #include "sailcpp/rigworker.h" #include #include /** * Constructs a window to display a rig. * * @param parent the parent widget */ CFormRig::CFormRig(QWidget *parent) : CFormMain(parent) { // create menu bar setupMenuBar(); // create main widget tabs = new CSailViewerTabs(this); setCentralWidget(tabs); // set language connect(qApp, SIGNAL(languageChanged()), this, SLOT(languageChange())); languageChange(); // set initial definition setDef(def); } /** * Sets the strings of the subwidgets using the current * language. */ void CFormRig::languageChange() { setWindowTitle( tr("rig") ); actionViewDef->setText( tr("&Dimensions") ); } bool CFormRig::read(const QString &filename) { try { setDef(writer.read(filename)); return true; } catch (read_error const&) { return false; } } bool CFormRig::write(const QString &filename) { try { writer.write(def, filename); return true; } catch (write_error const&) { return false; } } /** * Replaces the current sail definition. * * @param newdef */ void CFormRig::setDef(const CRigDef& newdef) { def = newdef; tabs->setObject(CRigWorker(def).makeRig()); } /** * Creates the menu bar */ void CFormRig::setupMenuBar() { // view actions actionViewDef = new QAction(this); connect( actionViewDef, SIGNAL( triggered() ), this, SLOT( slotDef() ) ); addViewAction(actionViewDef); } /** * Displays the CFormRigDef rig definition dialog. */ void CFormRig::slotDef() { CRigDef defcopy = def; if ( CFormRigDef(this, &defcopy).exec() ) { // we returned from the dialog with an 'OK', setDef(defcopy); } } sailcut-1.5.0/src/formrig.h000066400000000000000000000027251477005247400156060ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FORMRIG_H #define FORMRIG_H #include "formmain.h" #include "sailwriter-xml.h" /** Dialog holding a rig. */ class CFormRig : public CFormMain { Q_OBJECT public: CFormRig(QWidget *parent = 0); protected: QString getSaveFileName(const QString &filename) { return writer.getSaveFileName(filename); }; bool read(const QString &filename); bool write(const QString &filename); private slots: void languageChange(); void slotDef(); private: void setDef(const CRigDef& newdef); void setupMenuBar(); CRigDef def; CRigDefXmlWriter writer; /** view hull definition */ QAction *actionViewDef; }; #endif sailcut-1.5.0/src/formrigdef.cpp000066400000000000000000000464361477005247400166270ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "formrigdef.h" #include "sailcpp/rigworker.h" /** The constructor. * * @param parent the parent window * @param rigptr pointer to the CRigDef */ CFormRigDef::CFormRigDef( QWidget* parent, CRigDef * rigptr ) : QDialog(parent) { setupUi(this); setModal(true); /* we store the pointer to the CRigDef so we can update it when the user clicks OK */ rigdef = rigptr; connect( btnOK, SIGNAL( clicked() ), this, SLOT( accept() ) ); connect( btnCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); connect( btnCheck, SIGNAL( clicked() ), this, SLOT( slotChanged() ) ); connect( txt_foreI, SIGNAL( textEdited(QString) ), this, SLOT( slotChanged() ) ); connect( txt_foreJ, SIGNAL( textEdited(QString) ), this, SLOT( slotChanged() ) ); connect( txt_CSH, SIGNAL( textEdited(QString) ), this, SLOT( slotChanged() ) ); connect( txt_CSB, SIGNAL( textEdited(QString) ), this, SLOT( slotChanged() ) ); connect( txt_LSB, SIGNAL( textEdited(QString) ), this, SLOT( slotChanged() ) ); connect( txt_MH, SIGNAL( textEdited(QString) ), this, SLOT( slotChanged() ) ); connect( txt_MRnd, SIGNAL( textEdited(QString) ), this, SLOT( slotChanged() ) ); connect( txt_MRkM, SIGNAL( textEdited(QString) ), this, SLOT( slotChanged() ) ); connect( txt_MC, SIGNAL( textEdited(QString) ), this, SLOT( slotChanged() ) ); connect( txt_MW, SIGNAL( textEdited(QString) ), this, SLOT( slotChanged() ) ); connect( spinBox_MRndPos, SIGNAL( valueChanged(int) ), this, SLOT( slotChanged() ) ); connect( spinBox_SPNB, SIGNAL( valueChanged(int) ), this, SLOT( slotChanged() ) ); connect( txt_HAD, SIGNAL( textEdited(QString) ), this, SLOT( slotChanged() ) ); connect( txt_BAD, SIGNAL( textEdited(QString) ), this, SLOT( slotChanged() ) ); txt_RigID->setText(QString::fromStdString(rigdef->rigID) ); txt_foreI->setText(QString::number(rigdef->foreI) ); txt_foreJ->setText(QString::number(rigdef->foreJ) ); txt_MH->setText(QString::number(rigdef->MHeight) ); txt_MC->setText(QString::number(rigdef->MCord) ); txt_MW->setText(QString::number(rigdef->MWidth) ); txt_MRnd->setText(QString::number(rigdef->MRnd) ); txt_MRkM->setText(QString::number(rigdef->MRakeM) ); spinBox_MRndPos->setValue(rigdef->MRndPos); txt_CSH->setText(QString::number(rigdef->CSH) ); txt_CSB->setText(QString::number(rigdef->CSB) ); txt_LSB->setText(QString::number(rigdef->LSB) ); txt_SPH1->setText(QString::number(rigdef->SPH[1]) ); txt_SPH2->setText(QString::number(rigdef->SPH[2]) ); txt_SPH3->setText(QString::number(rigdef->SPH[3]) ); txt_SPW1->setText(QString::number(rigdef->SPW[1]) ); txt_SPW2->setText(QString::number(rigdef->SPW[2]) ); txt_SPW3->setText(QString::number(rigdef->SPW[3]) ); // display lbl_MRkD->setText(QString::number(rigdef->MRakeD) ); spinBox_SPNB->setValue(rigdef->SPNB); // variable changes triggering a check txt_HAD->setText(QString::number(rigdef->HAD) ); txt_BAD->setText(QString::number(rigdef->BAD) ); // resize resize(minimumSizeHint()); } /** Save the parameters entered by the user in the CRigDef. * slot connected to OK button */ void CFormRigDef::accept() { // return data if everything is OK if (check() ==true) QDialog::accept(); } /** Sets the strings of the subwidgets using the current * language. */ void CFormRigDef::languageChange() { /* FIXME use proper labels lbl_RigID->setText( tr("Rig identification") ); lbl_foreJ->setText( tr("Fore triangle base") ); lbl_foreI->setText( tr("Fore triangle height") ); lbl_MastWidth->setText( tr("Mast width") ); lbl_MastCord->setText( tr("Mast cord") ); lbl_MastRakeAngle->setText( tr("Mast rake angle") ); lbl_MastRake->setText( tr("Mast rake") ); lbl_MastHeight->setText( tr("Mast height") ); lbl_MastRound->setText( tr("Mast round") ); lbl_MastRoundPos->setText( tr("Mast round position") ); lbl_CapShroudHeight->setText( tr("Cap shroud height") ); lbl_CapShroudBase->setText( tr("Cap shroud base width") ); lbl_LowerShroudBase->setText( tr("Lower shroud base width") ); lbl_SpreaderHeight1->setText( tr("Spreader height") ); lbl_SpreaderHeight2->setText( tr("Spreader height") ); lbl_SpreaderHeight3->setText( tr("Spreader height") ); lbl_SpreaderWidth1->setText( tr("Spreader width") ); lbl_SpreaderWidth2->setText( tr("Spreader width") ); lbl_SpreaderWidth3->setText( tr("Spreader width") ); label_SpreaderNumber->setText( tr("Number of spreaders") ); lbl_BAD->setText( tr("Mainsail tack height") ); lbl_HAD->setText( tr("Mainsail head height") ); lbl_Luff_Round->setText( tr("Luff round") ); lbl_Luff->setText( tr("Luff length") ); */ } /** Called when one of the values changes. * it triggers a check of all data */ void CFormRigDef::slotChanged() { /* if ( active == false ) return; */ check(); } /** Check all dimensions entered in order to * make sure that the rig is possible and reasonable. * This will also trigger ancillary data computation * for mainsail luff parameters. */ bool CFormRigDef::check() { long I = 1, J = 1, L1 = 1, L2 = 1; bool flag = true; unsigned int j, n; QString txt; /// create four palettes QPalette palStd, palHi, palLo, palRel; palStd = txt_RigID->palette(); palLo = palHi = palRel = palStd; palLo.setColor( QPalette::Text, Qt::magenta); // too low value palHi.setColor( QPalette::Text, Qt::red ); // too high value palRel.setColor( QPalette::Text, Qt::blue ); // related value to be checked // start collecting data /// check the rig ID text txt = txt_RigID->text(); txt = txt.simplified(); if (txt.length() > 40) { txt.truncate(40); flag = false; txt_RigID->setPalette(palHi); txt_RigID->setText(QString(txt)); } else { txt_RigID->setPalette(palStd); txt_RigID->setText(QString(txt)); } rigdef->rigID = txt.toStdString(); /// checking fore triangle rigdef->foreI = txt_foreI->text().toDouble(); if (rigdef->foreI < 100) // height too small { flag = false; rigdef->foreI = 100; txt_foreI->setPalette(palLo); txt_foreI->setText(QString::number(rigdef->foreI)); return flag; } else { txt_foreI->setPalette(palStd); txt_foreI->setText(QString::number(rigdef->foreI)); } rigdef->foreJ = txt_foreJ->text().toDouble(); I = (long)(rigdef->foreI); J = (long)(rigdef->foreJ); if (( I / J )> 10) { flag = false; txt_foreI->setPalette(palHi); txt_foreJ->setPalette(palLo); txt_foreI->setText(QString::number(rigdef->foreI)); txt_foreJ->setText(QString::number(rigdef->foreJ)); return flag; } else if (( J / I )> 2) { flag = false; txt_foreJ->setPalette(palHi); txt_foreI->setPalette(palLo); txt_foreI->setText(QString::number(rigdef->foreI)); txt_foreJ->setText(QString::number(rigdef->foreJ)); return flag; } else { txt_foreJ->setPalette(palStd); txt_foreI->setPalette(palStd); txt_foreI->setText(QString::number(rigdef->foreI)); txt_foreJ->setText(QString::number(rigdef->foreJ)); } /// checking mast height rigdef->MHeight = txt_MH->text().toDouble(); L1 = (long)(rigdef->MHeight); if ( L1 < I ) { flag = false; txt_foreI->setPalette(palRel); txt_MH->setPalette(palLo); rigdef->MHeight = I; return flag; } else if ( L1 > (1.8 * I)) { flag = false; txt_foreI->setPalette(palRel); txt_MH->setPalette(palHi); rigdef->MHeight = ceil (1.8 * I); return flag; } else { txt_foreI->setPalette(palStd); txt_MH->setPalette(palStd); } txt_MH->setText(QString::number(rigdef->MHeight)); L1 = (long)(rigdef->MHeight); /// checking mast cord rigdef->MCord = txt_MC->text().toDouble(); if (rigdef->MCord > (L1 / 10)) { flag = false; txt_MC->setPalette(palHi); rigdef->MCord = floor(L1 / 10); } else if (rigdef->MCord < (L1 / 200)) { flag = false; txt_MC->setPalette(palLo); rigdef->MCord = ceil(L1 / 200); } else { txt_MC->setPalette(palStd); } txt_MC->setText(QString::number(rigdef->MCord)); /// checking mast width rigdef->MWidth = txt_MW->text().toDouble(); if (rigdef->MWidth > rigdef->MCord) { flag = false; txt_MC->setPalette(palRel); txt_MW->setPalette(palHi); rigdef->MWidth = rigdef->MCord; } else if (rigdef->MWidth < (rigdef->MCord /5)) { flag = false; txt_MC->setPalette(palRel); txt_MW->setPalette(palLo); rigdef->MWidth = ceil(rigdef->MCord /5); } else { txt_MC->setPalette(palStd); txt_MW->setPalette(palStd); } txt_MW->setText(QString::number(rigdef->MWidth)); /// checking mast rake rigdef->MRakeM = txt_MRkM->text().toDouble(); if ( rigdef->MRakeM > L1 / 5) { flag = false; rigdef->MRakeM = floor( L1 / 5 ); txt_MH->setPalette(palRel); txt_MRkM->setPalette(palHi); } else if ( rigdef->MRakeM < -L1 / 5) { flag = false; rigdef->MRakeM = -floor( L1 / 5 ); txt_MH->setPalette(palRel); txt_MRkM->setPalette(palLo); } else { txt_MH->setPalette(palStd); txt_MRkM->setPalette(palStd); } txt_MRkM->setText(QString::number(rigdef->MRakeM)); /// computing mast rake in degree rigdef->MRakeD = radiansToDegrees(atan2(rigdef->MRakeM ,rigdef->MHeight)); lbl_MRkD->setText(QString::number(rigdef->MRakeD)); /// computing mast base distance to stem rigdef->MBase = rigdef->foreJ - rigdef->MRakeM * (rigdef->foreI / rigdef->MHeight); /// checking mast round rigdef->MRnd = txt_MRnd->text().toDouble(); rigdef->MRndPos = spinBox_MRndPos->value(); if ( rigdef->MRnd > L1/10 ) { flag = false; rigdef->MRnd = floor( L1/10 ); txt_MRnd->setPalette(palHi); txt_MRnd->setPalette(palHi); } else { txt_MH->setPalette(palStd); txt_MRnd->setPalette(palStd); } txt_MRnd->setText(QString::number(rigdef->MRnd)); /// checking mainsail tack height rigdef->BAD = txt_BAD->text().toDouble(); if (rigdef->BAD < 0 ) { flag = false; rigdef->BAD = 0; txt_BAD->setPalette(palLo); } else if ( rigdef->BAD > L1 / 2 ) { flag = false; rigdef->BAD = int(L1 / 2); txt_BAD->setPalette(palHi); txt_MH->setPalette(palRel); } else { txt_BAD->setPalette(palStd); txt_MH->setPalette(palStd); } txt_BAD->setText(QString::number(rigdef->BAD)); /// checking mainsail head height rigdef->HAD = txt_HAD->text().toDouble(); if (rigdef->HAD < rigdef->BAD +10 ) { flag = false; rigdef->HAD = rigdef->BAD +10; txt_HAD->setPalette(palLo); txt_BAD->setPalette(palRel); } else if ( rigdef->HAD > L1 ) { flag = false; rigdef->HAD = L1; txt_HAD->setPalette(palHi); txt_MH->setPalette(palRel); } else { txt_HAD->setPalette(palStd); txt_BAD->setPalette(palStd); txt_MH->setPalette(palStd); } txt_HAD->setText(QString::number(rigdef->HAD)); ///computing and display main sail tack and luff data CRigWorker worker(*rigdef); rigdef->MStack = worker.mastCenter( rigdef->BAD ) + CVector3d(rigdef->MCord /2, 0, 0); rigdef->MShead = worker.mastCenter( rigdef->HAD ) + CVector3d(rigdef->MCord /2, 0, 0); CVector3d MSluff = CVector3d(rigdef->MShead - rigdef->MStack); // compute mainsail luff round and its position CPoint3d p1, p2; real h=0, rd1 = 0, rd2 = 0; unsigned int rdPos = 49; j = 5; do { j++; p1 = rigdef->MStack + MSluff*(real( j ) / 50); h = p1.y(); p2 = worker.mastCenter( h ) + CVector3d(rigdef->MCord /2, 0, 0); rd2 = CVector3d(p1-p2).x(); if (fabs(rd2) < fabs(rd1) ) rdPos = (j - 1) * 2; else rd1 = rd2; } while ( rd1 == rd2 && j < 45); // display mainsail data lbl_MS_TackX->setText( QString::number( int(round(rigdef->MStack.x()) ) ) ); lbl_MS_TackY->setText( QString::number( int(rigdef->MStack.y()) )); lbl_MS_LuffL->setText( QString::number( int(round(MSluff.length()) ) ) ); lbl_MS_Rake->setText( QString::number( int(round(MSluff.x()) ) ) ); lbl_MS_LuffR->setText( QString::number( round(rd1) ) ); lbl_MS_LuffRP->setText( QString::number( rdPos ) +" %" ); /// reading number of spreaders rigdef->SPNB = spinBox_SPNB->value(); n = rigdef->SPNB; /// checking shrouds height and shroud base width rigdef->CSH = txt_CSH->text().toDouble(); if ( rigdef->CSH > L1) // cap shroud above mast head { flag = false; txt_CSH->setPalette(palHi); txt_MH->setPalette(palRel); rigdef->CSH = L1; return flag; } else if ( rigdef->CSH < (0.75 * I)) { flag = false; txt_CSH->setPalette(palLo); txt_foreI->setPalette(palRel); rigdef->CSH = ceil(0.75 * I); return flag; } else { txt_MH->setPalette(palStd); txt_foreI->setPalette(palStd); txt_CSH->setPalette(palStd); } txt_CSH->setText( QString::number(rigdef->CSH) ); rigdef->LSB = txt_LSB->text().toDouble(); if ( rigdef->LSB < rigdef->CSH / ( 10 * (1 + real(n)) ) ) { flag = false; txt_LSB->setPalette(palLo); txt_CSH->setPalette(palRel); rigdef->LSB = ceil( rigdef->CSH / ( 10 * (1 + real(n)) ) ); } else if ( rigdef->LSB > rigdef->CSH / (2 + real(n)) ) { flag = false; txt_LSB->setPalette(palHi); txt_CSH->setPalette(palRel); rigdef->LSB = floor( rigdef->CSH / (2 + real(n)) ); } else { txt_CSH->setPalette(palStd); txt_LSB->setPalette(palStd); } txt_LSB->setText( QString::number(rigdef->LSB) ); rigdef->CSB = txt_CSB->text().toDouble(); if ( n == 0 ) { rigdef->CSB = rigdef->LSB; } else if (rigdef->CSB < rigdef->LSB ) { flag = false; txt_CSB->setPalette(palLo); txt_LSB->setPalette(palRel); rigdef->CSB = ceil( rigdef->LSB ); } else if (rigdef->CSB > (2 * rigdef->LSB)) { flag = false; txt_CSB->setPalette(palHi); txt_LSB->setPalette(palRel); rigdef->CSB = floor(2 * rigdef->LSB); } else { txt_CSB->setPalette(palStd); txt_LSB->setPalette(palStd); } txt_CSB->setText( QString::number(rigdef->CSB) ); /// checking spreaders rigdef->SPH[0] = 0; rigdef->SPW[0] = rigdef->LSB; rigdef->SPH[1] = txt_SPH1->text().toDouble(); rigdef->SPH[2] = txt_SPH2->text().toDouble(); rigdef->SPH[3] = txt_SPH3->text().toDouble(); rigdef->SPW[1] = txt_SPW1->text().toDouble(); rigdef->SPW[2] = txt_SPW2->text().toDouble(); rigdef->SPW[3] = txt_SPW3->text().toDouble(); if ( n < 1 ) { // no spreaders then reset to base of shrouds for (j = 1; j < 4; j++) { rigdef->SPH[j] = rigdef->SPH[0]; rigdef->SPW[j] = rigdef->SPW[0]; } txt_SPH1->setText( QString::number(rigdef->SPH[1]) ); txt_SPH2->setText( QString::number(rigdef->SPH[2]) ); txt_SPH3->setText( QString::number(rigdef->SPH[3]) ); txt_SPW1->setText( QString::number(rigdef->SPW[1]) ); txt_SPW2->setText( QString::number(rigdef->SPW[2]) ); txt_SPW3->setText( QString::number(rigdef->SPW[3]) ); } else { if ( rigdef->SPH[1] < rigdef->CSH / (2 + real(n)) ) { flag = false; txt_CSH->setPalette(palRel); txt_SPH1->setPalette(palLo); rigdef->SPH[1] = ceil( rigdef->CSH / (2 + real(n)) ); } else if ( rigdef->SPH[1] > ( rigdef->CSH / (0.5 + real(n)) ) ) { flag = false; txt_CSH->setPalette(palRel); txt_SPH1->setPalette(palHi); rigdef->SPH[1] = floor( rigdef->CSH / (0.5 + real(n)) ); } else { txt_CSH->setPalette(palStd); txt_SPH1->setPalette(palStd); } txt_SPH1->setText( QString::number(rigdef->SPH[1]) ); L2 = (long) (rigdef->CSH - rigdef->SPH[1]); if ( n > 1 ) { if ( rigdef->SPH[2] < ( rigdef->SPH[1] + L2 / (1 + real(n)) ) ) { flag = false; txt_SPH1->setPalette(palRel); txt_SPH2->setPalette(palLo); rigdef->SPH[2] = ceil( rigdef->SPH[1] + L2 /(1 + real(n) ) ); } else if ( rigdef->SPNB>1 && rigdef->SPH[2] > (rigdef->SPH[1] + L2 / (real(n) -.5)) ) { flag = false; txt_SPH1->setPalette(palRel); txt_SPH2->setPalette(palHi); rigdef->SPH[2] = floor(rigdef->SPH[1] + L2 /(real(n) -.5) ); } else { txt_SPH1->setPalette(palStd); txt_SPH2->setPalette(palStd); } txt_SPH2->setText( QString::number(rigdef->SPH[2]) ); L2 = (long)(rigdef->CSH - rigdef->SPH[2]); if ( n > 2 ) { if ( rigdef->SPH[3] < ( rigdef->SPH[2] + L2 / real(n) ) ) { flag = false; txt_SPH2->setPalette(palRel); txt_SPH3->setPalette(palLo); rigdef->SPH[3] = ceil( rigdef->SPH[2] + L2 / real(n) ); } else if ( rigdef->SPH[3] > ( rigdef->CSH + L2 / (real(n) -1.5) ) ) { flag = false; txt_SPH2->setPalette(palRel); txt_SPH3->setPalette(palHi); rigdef->SPH[3] = floor( rigdef->CSH + L2/(real(n) -1.5) ); } else { txt_SPH2->setPalette(palStd); txt_SPH3->setPalette(palStd); } txt_SPH3->setText( QString::number(rigdef->SPH[3]) ); } } } // return flag = true IF everything is OK return flag; } sailcut-1.5.0/src/formrigdef.h000066400000000000000000000025711477005247400162640ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FORMRIGDEF_H #define FORMRIGDEF_H #include "ui_formrigdefbase.h" #include "sailcpp/rigdef.h" /** The rig definition dialog, where the user enters * the parameters of the rig. * * @see CRigDef default values */ class CFormRigDef : public QDialog, private Ui::CFormRigDefBase { Q_OBJECT public: CFormRigDef( QWidget *, CRigDef* ); bool check(); virtual void accept(); protected slots: void slotChanged(); private slots: void languageChange(); protected: /** a pointer to the rig definion */ CRigDef *rigdef; }; #endif sailcut-1.5.0/src/formrigdefbase.ui000066400000000000000000001337311477005247400173100ustar00rootroot00000000000000 sailcuter CFormRigDefBase 0 0 700 550 0 0 700 550 Rig dimensions 4 4 Check 0 0 OK 0 0 Cancel Qt::Horizontal 321 31 0 0 Shrouds 4 4 0 0 155 22 Cap shroud base width 0 0 40 22 = CSH 0 0 155 22 Lower shroud base width 0 0 60 22 txt_LSB Qt::AlignHCenter 0 0 60 22 txt_CSH Qt::AlignHCenter 0 0 40 22 = CSB 0 0 155 22 Cap shroud height 0 0 60 22 txt_CSB Qt::AlignHCenter 0 0 40 22 = LSB 0 0 Spreaders 4 4 Qt::Horizontal 21 20 50 21 Qt::AlignHCenter 3 3 = SPNB Number of spreaders Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Spreader height 6 6 0 0 0 22 txt_SPH2 Qt::AlignHCenter 0 0 0 22 txt_SPH1 Qt::AlignHCenter 0 0 70 22 txt_SPH3 Qt::AlignHCenter 30 22 SPH2 40 22 SPH3 30 22 SPH1 0 0 Spreader length 6 6 40 22 SPW3 70 22 txt_SPW3 Qt::AlignHCenter 0 22 SPW1 0 22 txt_SPW1 Qt::AlignHCenter 0 22 SPW2 0 22 txt_SPW2 Qt::AlignHCenter 0 0 0 0 Mainsail 4 4 0 0 60 22 QFrame::Box lbl_MS_LuffRP Qt::AlignCenter 0 0 20 22 @ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 60 22 QFrame::Box lbl_MS_LuffR Qt::AlignCenter 0 0 70 22 QFrame::Box lbl_MS_TackY Qt::AlignCenter 0 0 20 22 Y = Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 70 22 QFrame::Box lbl_MS_TackX Qt::AlignCenter 0 0 X = Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Tack Qt::Horizontal QSizePolicy::Minimum 61 22 0 0 60 22 QFrame::Box lbl_MS_LuffL Qt::AlignCenter 0 0 = MSL 0 0 60 22 Luff length 0 0 0 22 Luff round 0 0 60 22 QFrame::Box lbl_MS_Rake Qt::AlignCenter 0 0 = MSR 0 0 60 22 Luff rake Qt::Horizontal QSizePolicy::Minimum 51 25 0 0 60 22 Tack height 0 0 60 0 txt_BAD Qt::AlignHCenter 0 0 0 0 = BAD Qt::Horizontal 0 0 Head height 0 0 = HAD 0 0 60 0 txt_HAD Qt::AlignHCenter Qt::Horizontal 40 20 0 0 Mast 4 4 Mast width = MW 70 0 txt_MW Qt::AlignHCenter 70 0 txt_MC Qt::AlignHCenter = MC Mast cord QFrame::Box lbl_MRkD Qt::AlignCenter = MRkD Mast rake angle 0 0 70 0 txt_MH Qt::AlignHCenter txt_MRnd Qt::AlignHCenter Qt::Horizontal QSizePolicy::Expanding 20 20 Mast rake = MRkM 0 0 70 0 txt_MRkM Qt::AlignHCenter 0 0 60 22 Mast height = MH = MRnd 0 0 60 22 Mast round = MRndPos 0 0 60 22 Mast round position Qt::Horizontal Qt::AlignHCenter 20 80 50 0 0 Fore triangle 4 4 Qt::Horizontal 40 20 0 0 70 0 txt_foreI Qt::AlignHCenter = I 0 0 70 0 txt_foreJ Qt::AlignHCenter = J Fore triangle base Fore triangle hoist 400 22 Description of rig 0 0 60 20 Rig name Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 600 24 650 160 10 75 true All dimensions are in millimeter and angles in degrees Qt::AlignHCenter|Qt::AlignTop 1 0 Qt::Horizontal 60 25 btnOK btnCancel txt_RigID txt_foreI txt_foreJ txt_CSH txt_CSB txt_LSB txt_MH txt_MRnd spinBox_MRndPos txt_MRkM txt_MC txt_MW txt_BAD spinBox_SPNB txt_SPH3 txt_SPW3 txt_SPH2 txt_SPW2 txt_SPH1 txt_SPW1 sailcut-1.5.0/src/formsail.cpp000066400000000000000000000230601477005247400163030ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "formprint.h" #include "formsail.h" #include "formsaildef.h" #include "formmould.h" #include "sailprinter.h" #include "sailcpp/sailworker.h" #include "sailwriter-carlson.h" #include "sailwriter-dxf.h" #include "sailwriter-hand.h" #include "sailwriter-svg.h" #include "sailwriter-txt.h" #include #include #include #include #include /** * Constructs a window to display a sail. * * @param parent the parent widget */ CFormSail::CFormSail(QWidget *parent) : CFormMain(parent) { // create menu bar setupMenuBar(); // create main widget setupMainWidget(); // set language connect(qApp, SIGNAL(languageChanged()), this, SLOT(languageChange())); languageChange(); // set initial definition setDef(def); } /** * Sets the strings of the subwidgets using the current * language. */ void CFormSail::languageChange() { setWindowTitle( tr("sail") ); // print submenu menuPrint->setTitle( tr("&Print") ); actionPrintData->setText( tr("data") ); actionPrintDwg->setText( tr("drawing") ); actionPrintDev->setText( tr("development") ); // export 3d submenu menuExport3d->setTitle( tr("E&xport 3D sail") ); actionExport3dDXF->setText( tr("to &DXF") ); actionExport3dDXFSplit->setText( tr("to DXF (split)") ); actionExport3dSVG->setText( tr("to &SVG") ); actionExport3dTXT->setText( tr("to &TXT sail") ); actionExport3dXML->setText( tr("to &XML sail") ); // export flat submenu menuExportFlat->setTitle( tr("Export &development") ); actionExportFlatCarlson->setText( tr("to &Carlson plotter") ); actionExportFlatDXF->setText( tr("to &DXF") ); actionExportFlatDXFSplit->setText( tr("to DXF (split)") ); //actionExportFlatDXFBlocks->setText( tr("to &DXF-BLOCKS") ); actionExportFlatHand->setText( tr("to &Hand-plotting format") ); actionExportFlatSVG->setText( tr("to &SVG") ); actionExportFlatTXT->setText( tr("to &TXT sail") ); actionExportFlatXML->setText( tr("to &XML sail") ); // view menu actionViewDef->setText( tr("&Dimensions") ); actionViewMould->setText( tr("&Mould") ); actionViewPatch->setText( tr("&Patches") ); // tabs tabs->setTabText(tabs->panel.size()-1, tr("development")); } bool CFormSail::read(const QString &filename) { try { setDef(writer.read(filename)); return true; } catch (read_error const&) { return false; } } bool CFormSail::write(const QString &filename) { try { writer.write(def, filename); return true; } catch (write_error const&) { return false; } } /** * Replaces the current sail definition. * * @param newdef */ void CFormSail::setDef(const CSailDef& newdef) { def = newdef; sail = CSailWorker(def).makeSail(flatsail,dispsail); tabs->setObject(sail); tabs->panel[tabs->panel.size()-1]->setObject(dispsail); } /** * Creates the menu bar */ void CFormSail::setupMenuBar() { // File sub menus // // print submenu menuPrint = new QMenu(this); actionPrintData = menuPrint->addAction("", this, SLOT( slotPrintData() )); actionPrintDwg = menuPrint->addAction("", this, SLOT( slotPrintDwg() )); actionPrintDev = menuPrint->addAction("", this, SLOT( slotPrintDev() )); addFileMenu(menuPrint); // export 3d submenu menuExport3d = new QMenu(this); actionExport3dDXF = menuExport3d->addAction("", this, SLOT( slotExportDXF() ) ); actionExport3dDXFSplit = menuExport3d->addAction("", this, SLOT( slotExportDXFSplit() ) ); actionExport3dSVG = menuExport3d->addAction("", this, SLOT( slotExportSVG() ) ); actionExport3dTXT = menuExport3d->addAction("", this, SLOT( slotExportTXT() ) ); actionExport3dXML = menuExport3d->addAction("", this, SLOT( slotExportXML() ) ); addFileMenu(menuExport3d); // export flat submenu menuExportFlat = new QMenu(this); //menuFile->addMenu(""); actionExportFlatCarlson = menuExportFlat->addAction("", this, SLOT( slotExportFlatCarlson() ) ); actionExportFlatDXF = menuExportFlat->addAction("", this, SLOT( slotExportFlatDXF() ) ); actionExportFlatDXFSplit = menuExportFlat->addAction("", this, SLOT( slotExportFlatDXFSplit() ) ); //actionExportFlatDXFBlocks = menuExportFlat->addAction("", this, SLOT( slotExportFlatDXFBlocks() ) ); actionExportFlatHand = menuExportFlat->addAction("", this, SLOT( slotExportFlatHand() ) ); actionExportFlatSVG = menuExportFlat->addAction("", this, SLOT( slotExportFlatSVG() ) ); actionExportFlatTXT = menuExportFlat->addAction("", this, SLOT( slotExportFlatTXT() ) ); actionExportFlatXML = menuExportFlat->addAction("", this, SLOT( slotExportFlatXML() ) ); addFileMenu(menuExportFlat); // View actions actionViewDef = new QAction(this); connect( actionViewDef, SIGNAL( triggered() ), this, SLOT( slotDef() ) ); addViewAction(actionViewDef); actionViewMould = new QAction(this); connect( actionViewMould, SIGNAL( triggered() ), this, SLOT ( slotMould() ) ); addViewAction(actionViewMould); // TODO : enable the following action when the patch viewer is ready actionViewPatch = new QAction(this); actionViewPatch->setEnabled(false); addViewAction(actionViewPatch); } /** * Creates the main widget */ void CFormSail::setupMainWidget() { tabs = new CSailViewerTabs(this); tabs->addViewer(new CSailViewerPanel(NULL, WIREFRAME, false)); setCentralWidget(tabs); } /** * Displays the sail CFormSailDef sail definition dialog. */ void CFormSail::slotDef() { // we pass the CFormSailDef a pointer to a copy of the sail definition so // that it can update it if necessary CSailDef defcopy = def; if ( CFormSailDef(this , &defcopy).exec() ) { // we returned from the dialog with an 'OK', setDef(defcopy); } } /** * Export the 3D sail to a DXF file. */ void CFormSail::slotExportDXF() { CSailDxfWriter3d(CSailDxfWriter3d::NORMAL).writeDialog(sail); } /** * Export the 3D sail to several DXF files (one per panel). */ void CFormSail::slotExportDXFSplit() { CSailDxfWriter3d(CSailDxfWriter3d::SPLIT).writeDialog(sail); } /** * Exports the 3D sail to an SVG file. */ void CFormSail::slotExportSVG() { CSailSvgWriter().writeDialog(sail); } /** * Exports the 3D sail to a TXT file. */ void CFormSail::slotExportTXT() { CSailTxtWriter().writeDialog(sail); } /** * Exports the 3D sail to an XML file. */ void CFormSail::slotExportXML() { CPanelGroupXmlWriter().writeDialog(sail); } /** * Exports the flat sail to a Carlson plotter file */ void CFormSail::slotExportFlatCarlson() { CSailCarlsonWriter().writeDialog(flatsail); } /** * Exports the flat sail with panels staggered as displayed to a DXF file */ void CFormSail::slotExportFlatDXF() { CSailDxfWriter2d(CSailDxfWriter2d::NORMAL).writeDialog(dispsail); } /** * Export the flat sail to several DXF files (one per panel). */ void CFormSail::slotExportFlatDXFSplit() { CSailDxfWriter2d(CSailDxfWriter2d::SPLIT).writeDialog(flatsail); } /** * Exports the flat sail with panels superimposed to a DXF file with blocks */ void CFormSail::slotExportFlatDXFBlocks() { // FIXME: shouldn't this be BLOCKS ? CSailDxfWriter2d(CSailDxfWriter2d::NORMAL).writeDialog(flatsail); } /** * Exports the flat sail to a "hand" sail file. */ void CFormSail::slotExportFlatHand() { CSailHandWriter().writeDialog(flatsail); } /** * Exports the flat sail to an SVG file. */ void CFormSail::slotExportFlatSVG() { CSailSvgWriter().writeDialog(dispsail); } /** * Exports the flat sail to a TXT sail file. */ void CFormSail::slotExportFlatTXT() { CSailTxtWriter().writeDialog(flatsail); } /** * Exports the flat sail to an XML sail file */ void CFormSail::slotExportFlatXML() { CPanelGroupXmlWriter().writeDialog(flatsail); } /** * Displays the CFormMould sail mould definition dialog. */ void CFormSail::slotMould() { // we pass the CFormMould a pointer to a copy of the sail mould so // that it can update it if necessary CSailDef defcopy = def; if ( CFormMould(this , &defcopy.mould).exec() ) { // we returned from the dialog with an 'OK' setDef(defcopy); } } /** * Print the current sail data. */ void CFormSail::slotPrintData() { CSailDataPrinter prt(def); CFormPrint(&prt, QPageLayout::Portrait).exec(); } /** * Print the current developed sail drawings one panel per page * with coordinates of key points for handplotting. */ void CFormSail::slotPrintDev() { CSailDevelPrinter prt(flatsail); CFormPrint(&prt, QPageLayout::Landscape).exec(); } /** * Print the current sail drawing. */ void CFormSail::slotPrintDwg() { CSailDrawingPrinter prt(sail); CFormPrint(&prt, QPageLayout::Portrait).exec(); } sailcut-1.5.0/src/formsail.h000066400000000000000000000072471477005247400157610ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FORMSAIL_H #define FORMSAIL_H #include "formmain.h" #include "sailwriter-xml.h" /** Dialog holding a sail. * * @see CFormSailDef for data input and checking, CSailWorker, CSailDef */ class CFormSail : public CFormMain { Q_OBJECT public: CFormSail(QWidget *parent = 0); protected: QString getSaveFileName(const QString &filename) { return writer.getSaveFileName(filename); }; bool read(const QString &filename); bool write(const QString &filename); private slots: void slotDef(); void slotExportDXF(); void slotExportDXFSplit(); void slotExportSVG(); void slotExportTXT(); void slotExportXML(); void slotExportFlatCarlson(); void slotExportFlatDXF(); void slotExportFlatDXFSplit(); void slotExportFlatDXFBlocks(); void slotExportFlatHand(); void slotExportFlatSVG(); void slotExportFlatTXT(); void slotExportFlatXML(); void slotMould(); void slotPrintData(); void slotPrintDwg(); void slotPrintDev(); void languageChange(); private: void setDef(const CSailDef& newdef); void setupMenuBar(); void setupMainWidget(); CSailDef def; CSailDefXmlWriter writer; /** The sail */ CPanelGroup sail; /** The developed sail */ CPanelGroup flatsail; /** The display version of the flat sail */ CPanelGroup dispsail; // menus and action /** The Print submenu */ QMenu *menuPrint; /** Export 3d submenu */ QMenu *menuExport3d; /** Export flat panels submenu */ QMenu *menuExportFlat; /** Export 3D sail to DXF */ QAction *actionExport3dDXF; /** Export 3D sail to DXF (one file per file) */ QAction *actionExport3dDXFSplit; /** Export 3D sail to SVG (2D reduction) */ QAction *actionExport3dSVG; /** Export 3D sail to text */ QAction *actionExport3dTXT; /** Export 3D sail to XML */ QAction *actionExport3dXML; /** Export flat sail to Carlson plotter format */ QAction *actionExportFlatCarlson; /** Export flat sail to hand format */ QAction *actionExportFlatHand; /** Export flat sail to DXF */ QAction *actionExportFlatDXF; /** Export flat sail to DXF (one file per file) */ QAction *actionExportFlatDXFSplit; /** Export flat sail to DXF blocks */ QAction *actionExportFlatDXFBlocks; /** Export flat sail to SVG */ QAction *actionExportFlatSVG; /** Export flat sail to TXT */ QAction *actionExportFlatTXT; /** Export flat sail to XML */ QAction *actionExportFlatXML; /** Print sail data */ QAction *actionPrintData; /** Print sail development */ QAction *actionPrintDev; /** Print sail drawing */ QAction *actionPrintDwg; /** View sail definition */ QAction *actionViewDef; /** View sail mould */ QAction *actionViewMould; /** View sail definition */ QAction *actionViewPatch; }; #endif sailcut-1.5.0/src/formsaildef.cpp000066400000000000000000001053551477005247400167720ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include "formsaildef.h" #include "sailcpp/sailworker.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// /** The constructor. * * @param parent the parent window * @param sailptr pointer to the CSailDef */ CFormSailDef::CFormSailDef( QWidget* parent, CSailDef * sailptr ) : QDialog(parent) { setupUi(this); setModal(true); // we store the pointer to the CSailDef so we can update it when // the user clicks OK saildef = sailptr; // Write all the sail data to the screen dimensions of sail. setSailCut( saildef->sailCut ); setSailType( saildef->sailType ); txtSailID->setText(QString::fromStdString(saildef->sailID)); txtLOA->setText( QString::number(saildef->LOA ) ); txtTriangBase->setText( QString::number(saildef->foreJ ) ); txtTriangHoist->setText( QString::number(saildef->foreI ) ); txtClothWidth->setText( QString::number( saildef->clothW ) ); txtSeamWidth->setText( QString::number( saildef->seamW ) ); txtLeechHemWidth->setText( QString::number( saildef->leechHemW ) ); txtFootHemWidth->setText( QString::number( saildef->footHemW ) ); txtHemsWidth->setText( QString::number( saildef->hemsW ) ); txtTackDist->setText( QString::number( saildef->tackX ) ); txtTackHeight->setText( QString::number( saildef->tackY ) ); txtRake->setText( QString::number( saildef->rake ) ); txtLuffLen->setText( QString::number( saildef->luffL ) ); txtLuffRound->setText( QString::number( saildef->luffR ) ); txtLuffRoundPos->setText( QString::number( saildef->luffRP ) ); txtGaffAngle->setText( QString::number( saildef->gaffDeg ) ); txtGaffLen->setText( QString::number( saildef->gaffL ) ); txtGaffRound->setText( QString::number( saildef->gaffR ) ); txtLeechLen->setText( QString::number( saildef->leechL ) ); txtLeechRound->setText( QString::number( saildef->leechR ) ); txtLeechRoundPos->setText( QString::number( saildef->leechRP ) ); txtFootLen->setText( QString::number( saildef->footL ) ); txtFootRound->setText( QString::number( saildef->footR ) ); txtTopDepth->setText ( QString::number( saildef->mould.profile[2].getDepth()*100 ) ); txtMidDepth->setText ( QString::number( saildef->mould.profile[1].getDepth()*100 ) ); txtFootDepth->setText ( QString::number( saildef->mould.profile[0].getDepth()*100 ) ); txtTwistAngle->setText ( QString::number( saildef->twistDeg ) ); txtSheetAngle->setText ( QString::number( saildef->sheetDeg ) ); txtSections->setText ( QString::number( saildef->nbSections ) ); txtGores->setText ( QString::number( saildef->nbGores ) ); txtLuffGores->setText (QString::number( saildef->nbLuffGores ) ); txtDihedral->setText ( QString::number( saildef->dihedralDeg ) ); // Create button group for sail type. QButtonGroup *bgrpSailType = new QButtonGroup( this ); bgrpSailType->addButton( radioMainSail ); bgrpSailType->addButton( radioJib ); bgrpSailType->addButton( radioWing ); // Create button group for sail cut. QButtonGroup *bgrpSailCut = new QButtonGroup( this ); bgrpSailCut->addButton( radioCross ); bgrpSailCut->addButton( radioTwist ); bgrpSailCut->addButton( radioHorizontal ); bgrpSailCut->addButton( radioVertical ); bgrpSailCut->addButton( radioMitre ); bgrpSailCut->addButton( radioMitre2 ); bgrpSailCut->addButton( radioRadial ); // Set signals and slots connections connect( btnOK, SIGNAL( clicked() ), this, SLOT( accept() ) ); connect( btnCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); connect( btnCompute, SIGNAL( pressed() ), this, SLOT( slotCompute() ) ); connect( bgrpSailType, SIGNAL( buttonClicked(QAbstractButton *) ), this, SLOT( slotSailType() ) ); connect( bgrpSailCut, SIGNAL( buttonClicked(QAbstractButton *) ), this, SLOT( slotSailCut() ) ); // Activate "compute" to calculate sail area and diagonal and display them. compute(); // resize resize(minimumSizeHint()); } // member functions /** * Compute and Display ancillary data of the sail computation */ void CFormSailDef::compute() { CSailWorker worker(*saildef); lblSailArea->setText ( QString::number( worker.Area() ) ); lblDiagonal->setText ( QString::number( worker.Diagonal() ) ); } /** * Returns the sail cut layout from the form. */ enumSailCut CFormSailDef::getSailCut() { if ( radioHorizontal->isChecked() ) return HORIZONTAL; else if ( radioMitre->isChecked() ) return MITRE; else if ( radioMitre2->isChecked() ) return MITRE2; else if ( radioRadial->isChecked() ) return RADIAL; else if ( radioTwist->isChecked() ) return TWIST; else if ( radioVertical->isChecked() ) return VERTICAL; else /* default */ return CROSS; } /** * Returns the sail type from the form. */ enumSailType CFormSailDef::getSailType() { if ( radioJib->isChecked() ) return JIB; else if ( radioWing->isChecked() ) return WING; else /* default */ return MAINSAIL; } /** * Enables or disables appropriate controls depending * on the sail cut. */ void CFormSailDef::setSailCut( enumSailCut cut ) { switch ( cut ) { case CROSS: radioCross->setChecked( true ); break; case HORIZONTAL: radioHorizontal->setChecked( true ); break; case RADIAL: radioRadial->setChecked( true ); break; case TWIST: radioTwist->setChecked( true ); break; case VERTICAL: radioVertical->setChecked( true ); break; case MITRE: radioMitre->setChecked( true ); break; case MITRE2: radioMitre2->setChecked( true ); break; } } /** * Enables or disables appropriate controls depending * on the sail type. */ void CFormSailDef::setSailType( enumSailType type ) { switch ( type ) { case MAINSAIL: #ifdef DEBUG std::cout << "setSailType( MAINSAIL )" << std::endl; #endif radioMainSail->setChecked( true ); txtTackDist->setEnabled( true ); txtTackHeight->setEnabled( true ); txtRake->setEnabled( true ); txtTriangBase->setEnabled( true ); txtTriangHoist->setEnabled( true ); txtGaffLen->setEnabled( true ); txtGaffRound->setEnabled( true ); txtGaffAngle->setEnabled( true ); txtDihedral->setEnabled( false ); radioCross->setEnabled( true ); radioHorizontal->setEnabled( true ); radioRadial->setEnabled( true ); radioTwist->setEnabled( true ); radioVertical->setEnabled( true ); radioMitre->setEnabled( true ); radioMitre2->setEnabled( true ); break; case JIB: #ifdef DEBUG std::cout << "setSailType( JIB )" << std::endl; #endif radioJib->setChecked( true ); txtTackDist->setEnabled( false ); txtTackHeight->setEnabled( true ); txtRake->setEnabled( false ); txtTriangBase->setEnabled( true ); txtTriangHoist->setEnabled( true ); txtGaffLen->setEnabled( true ); txtGaffRound->setEnabled( true ); txtGaffAngle->setEnabled( true ); txtDihedral->setEnabled( false ); radioCross->setEnabled( true ); radioHorizontal->setEnabled( true ); radioRadial->setEnabled( true ); radioTwist->setEnabled( true ); radioVertical->setEnabled( true ); radioMitre->setEnabled( true ); radioMitre2->setEnabled( true ); break; case WING: #ifdef DEBUG std::cout << "setSailType( WING )" << std::endl; #endif radioWing->setChecked( true ); txtTackDist->setEnabled( true ); txtTackHeight->setEnabled( true ); txtRake->setEnabled( true ); txtTriangBase->setEnabled( true ); txtTriangHoist->setEnabled( true ); txtGaffLen->setEnabled( false ); txtGaffRound->setEnabled( false ); txtGaffAngle->setEnabled( false ); txtDihedral->setEnabled( true ); radioHorizontal->setChecked( true ); radioCross->setEnabled( false ); //radioHorizontal->setEnabled( true ); radioRadial->setEnabled( false ); radioTwist->setEnabled( false ); radioVertical->setEnabled( false ); radioMitre->setEnabled( false ); radioMitre2->setEnabled( false ); break; } } // Qt overrides /** * Saves the parameters entered by the user in the CSailDef. * Slot connected to OK button */ void CFormSailDef::accept() { /** Return data if everything is OK. */ if (check() == true) QDialog::accept(); } /** * Check all dimensions entered in order to make * sure that the sail is possible and reasonable */ bool CFormSailDef::check() { long L1=1, L2=1; real A1=0, A2=0; bool flag = true; QString txt; /** Create four palettes for levels of warning. */ QPalette palStd, palHi, palLo, palRel; palStd = txtLuffLen->palette(); palLo = palHi = palRel = palStd; // normal value palLo.setColor( QPalette::Text, Qt::magenta); // too low value palHi.setColor( QPalette::Text, Qt::red ); // too high value palRel.setColor( QPalette::Text, Qt::blue ); // related value to be checked /** Get sail type and cut. */ saildef->sailCut = getSailCut(); saildef->sailType = getSailType(); /** Get and the sail ID text length. */ txt = txtSailID->text(); txt = txt.simplified(); if (txt.length() > 40) { txt.truncate(40); flag = false; txtSailID->setPalette(palHi); txtSailID->setText(QString(txt)); } else { txtSailID->setPalette(palStd); txtSailID->setText(QString(txt)); } saildef->sailID = txt.toStdString(); /** Get and check length of boat. */ saildef->LOA = txtLOA->text().toDouble(); if (saildef->LOA < 100) { flag = false; txtLOA->setPalette(palLo); saildef->LOA = 100; } else if (saildef->LOA > 100000) { flag = false; txtLOA->setPalette(palHi); saildef->LOA = 100000; } else { txtLOA->setPalette(palStd); } txtLOA->setText(QString::number(saildef->LOA)); L1 = (long)(saildef->LOA); /** Get and check foretriangle base against boat length. */ saildef->foreJ = txtTriangBase->text().toDouble(); if (saildef->foreJ > 0.9* L1) { flag = false; txtTriangBase->setPalette(palHi); txtLOA->setPalette(palRel); saildef->foreJ = floor(0.9*L1); } else if (saildef->foreJ < 0.05* L1) { flag = false; txtTriangBase->setPalette(palLo); txtLOA->setPalette(palRel); saildef->foreJ = ceil(0.05*L1); } else { txtTriangBase->setPalette(palStd); txtLOA->setPalette(palStd); } txtTriangBase->setText(QString::number(saildef->foreJ)); /** Get and check foretriangle hoist against boat length */ saildef->foreI = txtTriangHoist->text().toDouble(); if (saildef->foreI > 4*L1) { flag = false; txtTriangHoist->setPalette(palHi); txtLOA->setPalette(palRel); saildef->foreI = 4*L1; } else if (saildef->foreI < 0.1*L1) { flag = false; txtTriangHoist->setPalette(palLo); txtLOA->setPalette(palRel); saildef->foreI = ceil( 0.1*L1); } else { txtTriangBase->setPalette(palStd); txtLOA->setPalette(palStd); } txtTriangHoist->setText(QString::number(saildef->foreI)); /** Check tack position function of boat length. */ L1 = (long)(saildef->LOA); saildef->tackX = txtTackDist->text().toDouble(); if (saildef->tackX > 0.9*L1) { flag = false; txtTackDist->setPalette(palHi); txtLOA->setPalette(palRel); saildef->tackX = floor(0.9*L1); } else { txtTackDist->setPalette(palStd); txtLOA->setPalette(palStd); } txtTackDist->setText(QString::number(saildef->tackX)); saildef->tackY = txtTackHeight->text().toDouble(); L1 = (long)(saildef->foreI); saildef->tackY = txtTackHeight->text().toDouble(); if (saildef->tackY > 0.5*L1) { flag = false; txtTackHeight->setPalette(palHi); txtTriangHoist->setPalette(palRel); saildef->tackY = floor(0.5*L1); } else { txtTackHeight->setPalette(palStd); txtTriangHoist->setPalette(palStd); } txtTackHeight->setText(QString::number(saildef->tackY)); /** Get length and round data of the 4 sides of sail. */ saildef->luffL = txtLuffLen->text().toDouble(); saildef->luffR = txtLuffRound->text().toDouble(); saildef->luffRP = txtLuffRoundPos->text().toInt(); saildef->gaffDeg = txtGaffAngle->text().toDouble(); saildef->gaffL = txtGaffLen->text().toDouble(); saildef->gaffR = txtGaffRound->text().toDouble(); saildef->leechL = txtLeechLen->text().toDouble(); saildef->leechR = txtLeechRound->text().toDouble(); saildef->leechRP = txtLeechRoundPos->text().toInt(); saildef->footL = txtFootLen->text().toDouble(); saildef->footR = txtFootRound->text().toDouble(); saildef->footRP = 50; // imposed value /** Check luff rake. */ saildef->rake = txtRake->text().toDouble(); switch (saildef->sailType ) { case WING: L1 = (long)(saildef->luffL); if (saildef->rake > L1) { flag = false; txtRake->setPalette(palHi); saildef->rake =L1 - 1; } else if (saildef->rake < 0) { flag = false; txtRake->setPalette(palHi); saildef->rake =0; } else { txtRake->setPalette(palStd); } txtRake->setText(QString::number(saildef->rake)); break; default: L1 = (long)(saildef->foreI); if (saildef->rake > 0.3*L1) { flag = false; txtRake->setPalette(palHi); txtTriangHoist->setPalette(palRel); saildef->rake = floor(0.3*L1 - 1); } else if (saildef->rake < -0.3*L1) { flag = false; txtRake->setPalette(palHi); txtTriangHoist->setPalette(palRel); saildef->rake =-floor(0.3*L1); } else { txtRake->setPalette(palStd); txtTriangHoist->setPalette(palStd); } txtRake->setText(QString::number(saildef->rake)); break; } /** Check luff length and round, gaff length */ L1 = (long)(saildef->LOA); switch (saildef->sailType ) { case MAINSAIL: /** Check luff against fore triangle */ L1 = (long) (saildef->foreI); if (saildef->luffL > 3*L1) { flag=false; txtTriangHoist->setPalette(palRel); txtLuffLen->setPalette(palHi); saildef->luffL = 3*L1; } else if (saildef->luffL < 0.1*L1) { flag=false; txtTriangHoist->setPalette(palRel); txtLuffLen->setPalette(palLo); saildef->luffL = 1 + 0.1*L1; } else { txtTriangHoist->setPalette(palStd); txtLuffLen->setPalette(palStd); } txtLuffLen->setText(QString::number(saildef->luffL)); /** check luff round against luff length */ L2 =(long) ((saildef->luffL ) / 10); // luff round limit if (saildef->luffR > L2) { flag=false; txtLuffRound->setPalette(palHi); saildef->luffR = L2; } else if (saildef->luffR <- L2 ) { flag=false; txtLuffRound->setPalette(palLo); saildef->luffR = - L2 ; } else { txtLuffRound->setPalette(palStd); } txtLuffRound->setText(QString::number(saildef->luffR) ); /** check main sail foot length against Luff*/ L2 = (long)(saildef->luffL); if (saildef->footL > L2) { flag = false; saildef->footL = L2; txtFootLen->setPalette(palHi); } else if (saildef->footL < int(L2/10)) { flag = false; saildef->footL = 1+ int(L2/10); txtFootLen->setPalette(palLo); } else { txtFootLen->setPalette(palStd); } txtFootLen->setText(QString::number(saildef->footL)); /** Check main sail gaff length against foot */ L1 =(long) (5); L2 =(long) (saildef->footL); if (saildef->gaffL < L1) { txtGaffLen->setPalette(palLo); saildef->gaffL= L1; flag = false; } else if (saildef->gaffL > L2) { txtGaffLen->setPalette(palHi); saildef->gaffL= L2; flag = false; } else { txtGaffLen->setPalette(palStd); } txtGaffLen->setText(QString::number(saildef->gaffL) ); /** Check main sail gaff round. */ L1 = (long) ((saildef->gaffL )/ 8); if (saildef->gaffR > L1) { flag=false; txtGaffRound->setPalette(palHi); saildef->gaffR = L1; } else if (saildef->gaffR <0) { flag=false; txtGaffRound->setPalette(palLo); saildef->gaffR = 0; } else { txtGaffRound->setPalette(palStd); } txtGaffRound->setText(QString::number(saildef->gaffR) ); break; case JIB: /** check luff against fore triangle */ L1 =( long) (sqrt(((saildef->foreI - saildef->tackY) * (saildef->foreI - saildef->tackY)) + (saildef->foreJ * saildef->foreJ ))-1); if (saildef->luffL > L1) { flag=false; txtTriangHoist->setPalette(palRel); txtTackHeight->setPalette(palRel); txtLuffLen->setPalette(palHi); saildef->luffL = int (L1); } else if (saildef->luffL < (L1 / 10) ) { flag=false; txtLuffLen->setPalette(palLo); saildef->luffL = int(1 + real(L1) / 10); } else { txtTriangHoist->setPalette(palStd); txtTackHeight->setPalette(palStd); txtLuffLen->setPalette(palStd); } txtLuffLen->setText(QString::number(saildef->luffL) ); L2 = (long) ((saildef->luffL )/ 10); // round limit /** To accommodate code zero jib the positive luff round limit is twice negative round limit */ if (saildef->luffR > 2*L2) { flag=false; txtLuffRound->setPalette(palHi); saildef->luffR = 2*L2-1; } else if (saildef->luffR <-L2) { flag=false; txtLuffRound->setPalette(palLo); saildef->luffR = -L2+1; } else { txtLuffRound->setPalette(palStd); } txtLuffRound->setText(QString::number(saildef->luffR) ); /** Check jib gaff length. */ L1 =(long) (1); L2 =(long) (100); if (saildef->gaffL < L1) { txtGaffLen->setPalette(palLo); saildef->gaffL = L1; flag = false; } else if (saildef->gaffL > L2) { txtGaffLen->setPalette(palHi); saildef->gaffL = L2; flag = false; } else { txtGaffLen->setPalette(palStd); } txtGaffLen->setText(QString::number(saildef->gaffL) ); // reset gaff round txtGaffRound->setPalette(palStd); txtGaffRound->setText(QString::number(0) ); break; case WING: /** For a wing set gaff length to minimum. */ saildef->gaffL = 2; txtGaffLen->setText(QString::number(saildef->gaffL) ); saildef->gaffR = 0; txtGaffRound->setText(QString::number(saildef->gaffR) ); // check gaff angle and set it to be horizontal A1 = saildef->rake / saildef->luffL; saildef->gaffDeg = radiansToDegrees(acos(A1)); txtGaffAngle->setText(QString::number(floor(saildef->gaffDeg)) ); // adjust leech length such that foot is horizontal A1 = saildef->rake + saildef->gaffL - saildef->footL; A2 = saildef->luffL * sin(degreesToRadians(saildef->gaffDeg)); saildef->leechL = floor(sqrt( A1*A1 + A2*A2 ) ); txtLeechLen->setText(QString::number(saildef->leechL) ); L2 =(long) ((saildef->luffL )/ 4); // wing luff round limit if (saildef->luffR > L2) { flag=false; txtLuffRound->setPalette(palHi); saildef->luffR = L2; } else if (saildef->luffR <0) { flag=false; txtLuffRound->setPalette(palLo); saildef->luffR = 0; } else { txtLuffRound->setPalette(palStd); } txtLuffRound->setText(QString::number(saildef->luffR) ); break; } /** Check leech length. */ L1 = (long) saildef->luffL + (long) saildef->gaffL; L2 = (long) (int(0.5 * saildef->footL)); if (saildef->leechL > L1+L2) { flag = false; txtLuffLen->setPalette(palLo); txtGaffLen->setPalette(palLo); txtFootLen->setPalette(palLo); txtLeechLen->setPalette(palHi); saildef->leechL = L1+L2; } /** leech old check else if (saildef->leechL > 1.5*L1) { flag = false; txtLuffLen->setPalette(palRel); txtLeechLen->setPalette(palHi); saildef->leechL = 1.5*L1 -1; } */ else if (saildef->leechL < int(0.5*L1)) { flag = false; txtLuffLen->setPalette(palRel); txtLeechLen->setPalette(palLo); saildef->leechL = 1+ int(0.5*L1); } else { txtLuffLen->setPalette(palStd); txtLeechLen->setPalette(palStd); } txtLeechLen->setText(QString::number(saildef->leechL)); /** Check leech round. */ L1 = (long) int(saildef->leechL / 10); L2 = (long) int(saildef->footL /5); if (saildef->leechR > 3*L1) { flag = false; txtLeechRound->setPalette(palHi); txtLeechRound->setText(QString::number(3*L1) ); } else if (saildef->leechR <-L2) { flag = false; txtLeechRound->setPalette(palLo); txtLeechRound->setText(QString::number(1-L2) ); } if (saildef->leechR <-L1) { flag = false; txtLeechRound->setPalette(palLo); txtLeechRound->setText(QString::number(-L1) ); } else txtLeechRound->setPalette(palStd); /** Check foot length. */ switch (saildef->sailType ) { case MAINSAIL: L2 = (long)(saildef->luffL + saildef->gaffL - saildef->leechL); if (L2 < (long)(0.1*(saildef->luffL))) L2=(long)(1+ 0.1*(saildef->luffL)); break; case JIB: L2 = (long)(saildef->luffL - saildef->leechL); if (L2 < (long)(0.1*(saildef->luffL))) L2=(long)(1 +0.1*(saildef->luffL)); break; case WING: L2 = (long)(saildef->luffL - saildef->leechL); if (L2 < (long)(0.1*(saildef->luffL))) L2=(long)(1+0.1*(saildef->luffL)); break; } if (saildef->footL > saildef->leechL) { flag=false; txtLeechLen->setPalette( palRel ); txtFootLen->setPalette( palHi ); saildef->footL = (saildef->leechL) -1; } else if (saildef->footL < L2) { flag=false; txtLuffLen->setPalette( palRel ); txtLeechLen->setPalette( palHi ); txtFootLen->setPalette( palLo ); saildef->footL = L2 +1; } else { txtLuffLen->setPalette( palStd ); txtLeechLen->setPalette( palStd ); txtFootLen->setPalette( palStd ); } txtFootLen->setText( QString::number( saildef->footL ) ); /** Check foot round value. */ L1 = (long)(saildef->footL / 5); switch (saildef->sailType) { case WING: saildef->footR = 0; txtFootRound->setText(QString::number(saildef->footR)); break; default: if (saildef->footR > L1) { flag=false; txtFootLen->setPalette( palRel ); txtFootRound->setPalette(palHi); saildef->footR = L1; } else if (saildef->footR <-L1) { flag=false; txtFootLen->setPalette( palRel ); txtFootRound->setPalette(palLo); saildef->footR = 1-L1; } else { txtFootLen->setPalette( palStd ); txtFootRound->setPalette(palStd ); } txtFootRound->setText(QString::number(saildef->footR)); break; } /** Get cloth, seams and hems width. */ saildef->clothW = txtClothWidth->text().toDouble(); saildef->seamW = txtSeamWidth->text().toDouble(); saildef->leechHemW = txtLeechHemWidth->text().toDouble(); saildef->footHemW = txtFootHemWidth->text().toDouble(); saildef->hemsW = txtHemsWidth->text().toDouble(); /** Check cloth width against Leech length to ensure min/max number of panels. */ if (saildef->clothW < saildef->leechL /100) // max 100 panels { saildef->clothW = 1+ int(saildef->leechL /100); flag = false; txtClothWidth->setPalette(palLo); } else if (saildef->clothW > saildef->leechL /3) // min 3 panels { saildef->clothW = int(saildef->leechL /3 -1); flag = false; txtClothWidth->setPalette(palHi); } else { txtClothWidth->setPalette(palStd); } txtClothWidth->setText( QString::number(saildef->clothW)); L1 = (long)(5+ int(saildef->clothW / 10)); /** Check seams width function of cloth width. */ if (saildef->seamW > L1) { flag=false; txtSeamWidth->setPalette( palHi); saildef->seamW = L1; } else if (saildef->seamW < 0) { flag=false; txtSeamWidth->setPalette( palLo); saildef->seamW = 0; } else { txtSeamWidth->setPalette( palStd); } txtSeamWidth->setText( QString::number(saildef->seamW)); /** Check leech hem width function of cloth width. */ if (saildef->leechHemW > L1*2) { flag=false; txtLeechHemWidth->setPalette( palHi); saildef->leechHemW = L1*2; } else if (saildef->leechHemW < 0) { flag=false; txtLeechHemWidth->setPalette( palLo); saildef->leechHemW = 0; } else { txtLeechHemWidth->setPalette( palStd); } txtLeechHemWidth->setText( QString::number(saildef->leechHemW)); /** Check foot hem width function of cloth width. */ if (saildef->footHemW > L1*2) { flag=false; txtFootHemWidth->setPalette( palHi); saildef->footHemW = L1*2; } else if (saildef->footHemW < 0) { flag=false; txtFootHemWidth->setPalette( palLo); saildef->footHemW = 0; } else { txtFootHemWidth->setPalette( palStd); } txtFootHemWidth->setText( QString::number(saildef->footHemW)); /** Check other luff and gaff hem width function of cloth width. */ if (saildef->hemsW > L1) { flag=false; txtHemsWidth->setPalette( palHi); saildef->hemsW = L1; } else if (saildef->hemsW < 0) { flag=false; txtHemsWidth->setPalette( palLo); saildef->hemsW = 0; } else { txtHemsWidth->setPalette( palStd); } txtHemsWidth->setText( QString::number(saildef->hemsW)); /** Get the mould data. */ saildef->mould.profile[2].setDepth( real(txtTopDepth->text().toInt())/100 ); saildef->mould.profile[1].setDepth( real(txtMidDepth->text().toInt())/100 ); saildef->mould.profile[0].setDepth( real(txtFootDepth->text().toInt())/100 ); /** Get and check dihedral angle for a wing. */ saildef->dihedralDeg = txtDihedral->text().toInt(); if (saildef->dihedralDeg<90) { flag = false; txtDihedral->setPalette( palLo ); saildef->dihedralDeg = 90; } else if (saildef->dihedralDeg > 180) { flag = false; txtDihedral->setPalette( palHi ); saildef->dihedralDeg = 180; } else { txtDihedral->setPalette( palStd ); } txtDihedral->setText(QString::number(saildef->dihedralDeg)); /** Get and check twist of the sail. */ saildef->twistDeg = txtTwistAngle->text().toInt(); if (saildef->twistDeg > 45) { flag = false; txtTwistAngle->setPalette( palHi ); saildef->twistDeg = 45; } else if (saildef->twistDeg < 0) { flag = false; txtTwistAngle->setPalette( palLo ); saildef->twistDeg = 0; } else { txtTwistAngle->setPalette( palStd ); } txtTwistAngle->setText(QString::number(saildef->twistDeg)); /** Get and check sheeting angle of the sail. */ saildef->sheetDeg = txtSheetAngle->text().toInt(); if (saildef->sheetDeg > 45) { flag=false; txtSheetAngle->setPalette( palHi); saildef->sheetDeg = 45; } else if (saildef->sheetDeg < 0) { flag=false; txtSheetAngle->setPalette( palLo); saildef->sheetDeg = 0; } else { txtSheetAngle->setPalette( palStd); } txtSheetAngle->setText(QString::number(saildef->sheetDeg)); /** Get and check radial sections and gores number. */ if (saildef->sailCut == RADIAL) { saildef->nbGores = txtGores->text().toInt(); if (saildef->nbGores < 3) { flag=false; txtGores->setPalette( palLo); txtGores->setText(QString::number(3)); } else if (saildef->nbGores > 12) { flag=false; txtGores->setPalette( palHi); txtGores->setText(QString::number(12)); } else { txtGores->setPalette( palStd); } saildef->nbGores = txtGores->text().toInt(); saildef->nbSections = txtSections->text().toInt(); if (saildef->nbSections < 3) { flag=false; txtSections->setPalette( palLo); txtSections->setText(QString::number(3)); } else if (saildef->nbSections > 8) { flag=false; txtSections->setPalette( palHi); txtSections->setText(QString::number(8)); } else { txtSections->setPalette( palStd); } saildef->nbSections = txtSections->text().toInt(); saildef->nbLuffGores = txtLuffGores->text().toInt(); if (saildef->nbLuffGores < 1) { flag=false; txtLuffGores->setPalette( palLo); txtLuffGores->setText(QString::number(1)); } else if (saildef->nbLuffGores > saildef->nbGores -2) { flag=false; txtLuffGores->setPalette( palHi); txtLuffGores->setText(QString::number(saildef->nbGores -2)); } else { txtLuffGores->setPalette( palStd); } saildef->nbLuffGores = txtLuffGores->text().toInt(); } // return true IF everything is OK return flag; } /** * Enable/disable appropriate controls when the user * changes the sail cut. **/ void CFormSailDef::slotSailCut() { setSailCut( getSailCut() ); } /** * Saves the parameters entered by the user in the CSailDef. * compute and display ancillary sail data * * slot connected to Compute button */ void CFormSailDef::slotCompute() { real h=0, w=0, w1=0; QString txta, txtb, txtc, txtd, txte; // warning if flag returned from check is NOK if (check()) txte = "\n Dimensions OK"; else txte = "\n SOME DIMENSIONS ARE OUT OF LIMITS, PLEASE FIX THEM"; // calculate sail area and diagonal compute(); CSailWorker worker(*saildef); txta = tr("Sail corners coordinates"); txta = txta+"\n "+tr("tack")+" \t x = "+QString::number(int(worker.tack.x())) +"\n\t y = "+QString::number(int(worker.tack.y())) +" mm"; txta = txta+"\n "+tr("clew")+" \t x = "+QString::number(int(worker.clew.x())) +"\n\t y = "+QString::number(int(worker.clew.y())) +" mm"; txta = txta+"\n "+tr("head")+" \t x = "+QString::number(int(worker.head.x())) +"\n\t y = "+QString::number(int(worker.head.y())) +" mm"; txta = txta+"\n "+tr("peak")+" \t x = "+QString::number(int(worker.peak.x())) +"\n\t y = "+QString::number(int(worker.peak.y())) +" mm"; w = worker.SailLP(); txtb = "\nLP = " +QString::number(int(w)) +" mm "; txtc = "\n" + tr("Sail width measurements "); h=0.875; w = worker.IRCwidth(h); w1 = worker.SailWidth(h); // printf ("h=%f IRC width=%f IOR width=%f \n", h, w, w1); txtc = txtc +"\n h= " +QString::number(h)+"\t IRC w= " +QString::number(int(w)) +" mm \t IOR w= " +QString::number(int(w1)) +" mm"; h=0.75; w = worker.IRCwidth(h); w1 = worker.SailWidth(h); // printf ("h=%f IRC width=%f IOR width=%f \n", h, w, w1); txtc = txtc+ "\n h= " +QString::number(h)+"\t IRC w= " +QString::number(int(w)) +" mm \t IOR w= " +QString::number(int(w1)) +" mm"; h=0.5; w = worker.IRCwidth(h); w1 = worker.SailWidth(h); txtc = txtc + "\n h= "+QString::number(h)+"\t IRC w= "+QString::number(int(w)) +" mm \t IOR w= " +QString::number(int(w1)) +" mm"; h=0.25; w = worker.IRCwidth(h); w1 = worker.SailWidth(h); txtc = txtc + "\n h= "+QString::number(h)+"\t IRC w= "+QString::number(int(w)) +" mm \t IOR w= " +QString::number(int(w1)) +" mm"; // Display ancillary data in a message box. QMessageBox::information(this, "Sailcut", txta + "\n" + txtb + "\n" + txtc + "\n" + txtd + "\n" + txte); } /** * Enable/disable appropriate controls when the user * changes the sail type. **/ void CFormSailDef::slotSailType() { setSailType( getSailType() ); } sailcut-1.5.0/src/formsaildef.h000066400000000000000000000032321477005247400164260ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FORMSAILDEF_H #define FORMSAILDEF_H #include "ui_formsaildefbase.h" #include "sailcpp/saildef.h" /** This class is for sail definition dialog where, * The user enters the parameters of the sail * Checking the input data * Computing and displaying ancillary data. * * @see also CsailDef for definition and default values */ class CFormSailDef : public QDialog, private Ui::CFormSailDefBase { Q_OBJECT public: CFormSailDef( QWidget *, CSailDef* ); bool check(); void compute(); enumSailCut getSailCut(); enumSailType getSailType(); void setSailCut( enumSailCut ); void setSailType( enumSailType ); virtual void accept(); protected slots: void slotSailCut(); void slotSailType(); void slotCompute(); protected: /** A pointer to the sail definion */ CSailDef *saildef; }; #endif sailcut-1.5.0/src/formsaildefbase.ui000066400000000000000000001003741477005247400174540ustar00rootroot00000000000000 CFormSailDefBase 740 550 Sail definition 5 4 4 4 4 Sail identifier Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter Sail name Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::AlignLeading Rig geometry Qt::AlignLeading 4 4 4 4 5 Wing Qt::AlignHCenter Qt::AlignHCenter Main sail deg Fore triangle hoist I Dihedral angle Jib Fore triangle base J Boat length LOA Tack height Luff rake mm Qt::AlignHCenter mm mm Qt::AlignHCenter Qt::AlignHCenter mm Qt::Horizontal QSizePolicy::MinimumExpanding 20 20 Qt::AlignHCenter mm QFrame::VLine QFrame::Sunken Qt::Vertical mm Distance tack to stem Sail dimensions 4 4 4 4 5 mm Gaff length Sail area Round position Qt::Horizontal QSizePolicy::MinimumExpanding 20 20 mm Qt::Horizontal QSizePolicy::MinimumExpanding 20 20 Luff length % Round position Qt::AlignHCenter Leech round Qt::AlignHCenter QFrame::Box QFrame::Raised Qt::AlignCenter mm Qt::AlignHCenter Leech length mm Qt::AlignHCenter Qt::AlignHCenter mm Gaff angle from luff Qt::AlignHCenter Diagonal Qt::AlignHCenter mm Foot round Gaff round QFrame::HLine QFrame::Sunken 2 1 Qt::Horizontal Qt::AlignHCenter QFrame::Box QFrame::Raised Qt::AlignCenter Qt::AlignHCenter deg m2 mm Qt::AlignHCenter Qt::AlignHCenter % Luff round mm mm Foot length Layout 4 4 4 4 5 Cross cut Twist foot Number of sections Qt::AlignHCenter Qt::AlignHCenter Number of radial gores Number of luff gores Horizontal cut Vertical cut QFrame::VLine QFrame::Sunken 2 Qt::Vertical Radial cut Qt::AlignHCenter Mitre cut Mitre cut 2 Qt::Vertical 20 20 Sail shape 4 4 4 4 5 % % Qt::AlignHCenter Qt::AlignHCenter % Qt::AlignHCenter Top depth Mid depth Foot depth Qt::AlignHCenter Qt::AlignHCenter Twist angle Sheeting angle deg deg Cloth 4 4 4 4 5 Qt::AlignHCenter Qt::AlignHCenter Other hems Foot hem mm mm mm Qt::AlignHCenter Cloth width Leech hem Seam width Qt::AlignHCenter Qt::AlignHCenter mm mm Qt::Horizontal QSizePolicy::Expanding 20 20 Compute Qt::StrongFocus OK Cancel radioMainSail radioJib txtLOA txtTriangBase txtTriangHoist txtTackDist txtTackHeight txtRake txtSailID txtLuffLen txtFootLen txtLeechLen txtGaffLen txtLuffRound txtFootRound txtLeechRound txtGaffRound txtLuffRoundPos txtLeechRoundPos txtGaffAngle btnCompute radioCross radioTwist radioHorizontal radioVertical radioMitre radioRadial txtSections txtGores txtLuffGores txtTopDepth txtMidDepth txtFootDepth txtTwistAngle txtSheetAngle txtClothWidth txtSeamWidth txtLeechHemWidth txtHemsWidth btnOK btnCancel sailcut-1.5.0/src/geocpp/000077500000000000000000000000001477005247400152375ustar00rootroot00000000000000sailcut-1.5.0/src/geocpp/geocpp.h000066400000000000000000000022251477005247400166660ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef GEOCPP_GEOCPP_H #define GEOCPP_GEOCPP_H /** @defgroup GeoCpp Linear algebra library * * GeoCpp is a small linear algebra library that can be used * as a basis for geometry computations. * * @relates SailCpp */ #include #include #include #include #endif sailcut-1.5.0/src/geocpp/matrix.cpp000066400000000000000000000323221477005247400172510ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include /******************************************************* Static functions ********************************************************/ /** Returns the (square) identity matrix for a given dimension. * * @param n the dimension of the identity matrix. */ CMatrix CMatrix::id(const size_t& n) { CMatrix m = CMatrix(n,n); for (size_t i = 0; i < n; i++) m(i,i) = 1; return m; } /** Returns a random matrix of specified dimension. * * @param nrow number of rows for the matrix * @param ncol number of columns for the matrix */ CMatrix CMatrix::rnd(const size_t& nrow, const size_t& ncol) { CMatrix m(nrow,ncol); for (size_t i=0; i < nrow; i++) { for (size_t j=0; j < ncol; j++) { m(i,j) = (100 * real(rand()) / RAND_MAX)-50; } } return m; } /** Return a rotation matrix about specified axis. * * @param axis the index (0,1,..) of the axis * @param angle rotation angle in radians */ CMatrix CMatrix::rot3d(const size_t& axis, const real& angle) { CMatrix m(3,3); // build rotation matrix around x axis m( axis, axis ) = 1; m( (axis+1)%3, (axis+1)%3 ) = cos(angle); m( (axis+2)%3, (axis+2)%3 ) = cos(angle); m( (axis+1)%3, (axis+2)%3 ) = -sin(angle); m( (axis+2)%3, (axis+1)%3 ) = sin(angle); return m; } /******************************************************* Member functions ********************************************************/ /** Extracts the vector for the specified column. * * @param index the index of the column to return */ std::vector CMatrix::col(size_t index) const { if (index >= m_ncol) throw std::range_error("CMatrix::col : index out of bounds!"); std::vector ret(m_nrow); for (size_t i = 0; i < m_nrow; i++) ret[i] = m_data[i*m_ncol + index]; return ret; } /** Extracts part of a CMatrix. * * @param nr row to start at * @param nc column to start at * @param nrz number of rows to extract * @param ncz number of columns to extract */ CMatrix CMatrix::crop(const size_t& nr, const size_t& nc, const size_t& nrz, const size_t& ncz) const { CMatrix ret(nr,nc); size_t nrm,ncm; if (nr < (m_nrow - nrz)) nrm = nr; else nrm = m_nrow - nrz; if (nc < (m_ncol - ncz)) ncm = nc; else ncm = m_ncol - ncz; for (size_t i=0; i < nrm; i++) for (size_t j=0; j < ncm; j++) ret(i,j) = (*this)(i,j+ncz); return ret; } /** Returns the determinant of a CMatrix. The matrix must be square! */ real CMatrix::determinant() const { if (m_nrow != m_ncol) throw std::invalid_argument("CMatrix::det : matrix is not square!"); real ret=0; // if we have a scalar matrix return its only coefficient if (m_nrow == 1) return (*this)(0,0); // develop relative to first row for (size_t j=0; j < m_ncol; j++) { if (j%2) ret -= (*this)(0,j) * dev(0,j).determinant(); else ret += (*this)(0,j) * dev(0,j).determinant(); } return ret; } /** Returns a square Matrix with the specified rows and lines removed. * The matrix must be square! * * @param i the index of the row to remove * @param j the index of the column to remove */ CMatrix CMatrix::dev(const size_t& i, const size_t& j) const { if ((i >= m_nrow) || (j >= m_ncol)) throw std::range_error("CMatrix::dev : index out of bounds"); if (m_nrow != m_ncol) throw std::invalid_argument("CMatrix::dev : matrix is not square!"); size_t dx=0,dy=0; if (empty()) return CMatrix(); CMatrix m(m_nrow - 1, m_ncol - 1); for (size_t x=0; x < m_nrow; x++) { if (x!=i) { dy = 0; for (size_t y=0; y < m_ncol; y++) { if (y!=j) { m(dx,dy) =(*this)(x,y); dy++; } } dx++; } } return m; } /** Diagonalises matrix by Gauss-Jordan method with full pivoting * optionally returns the inverse matrix. */ CMatrix CMatrix::gaussjordan(bool *is_inv, CMatrix *inv, soltype_t * soltype, std::vector *bb, CMatrix *tkern) const { // check dimensions CMatrix b(m_nrow, 1); if (bb != NULL) { if (bb->size() != m_nrow) throw std::invalid_argument("CMatrix::solve : matrix <=> right-hand side dimensions incompatible"); for (size_t i = 0; i < m_nrow; ++i) b(i, 0) = (*bb)[i]; } real p_value; real p_avalue, avalue; size_t p_i, p_j; size_t i,j,k; size_t n; // copy over the matrix CMatrix m = *this; CMatrix t; // left-hand operations (row ops) CMatrix lops = CMatrix::id(m_nrow); // CMatrix rswap = CMatrix::id(getnrow()); // right-hand operations (col ops) CMatrix cswap = CMatrix::id(m_ncol); // determine minimum dimension if (m_ncol < m_nrow) n = m_ncol; else n = m_nrow; //////////////////////////////// // DIAGONALISATION // //////////////////////////////// for (k=0; k < n; k++) { // find pivot p_value = p_avalue = 0; p_i = p_j = 0; for (i = k; i < m_nrow; i++) { for (j = k; j < m_ncol; j++) { avalue = fabs(m(i,j)); if (avalue > p_avalue) { p_value = m(i,j); p_avalue = avalue; p_i = i; p_j = j; } } } // if pivot is smaller than epsillon we cannot continue diagonalisation if ( p_avalue <= EPS ) break; // exchange rows k and p_i // swapping m.swap_row(k,p_i); lops.swap_row(k,p_i); //rswap.swap_row(k,p_i); b.swap_row(k,p_i); // swapping cols k and p_j m.swap_col(k,p_j); cswap.swap_col(k,p_j); // modify rows t = CMatrix::id(m_nrow); for (i =0; i < m_nrow; i++) { if ( i !=k ) t(i,k) = -m(i,k) / p_value; else t(k,k) = 1 / p_value; } m = t * m; b = t * b; lops = t * lops; } ///////////////////////////////////// // HANDLE REQUEST FOR INVERSION // ///////////////////////////////////// if ((is_inv != NULL) && (inv != NULL)) { if ((m_nrow == m_ncol)&&(m_ncol == k)) { // matrix is square and invertible *inv = cswap*lops; *is_inv = true; } } ///////////////////////////////////// // HANDLE REQUEST FOR SOLUTION // ///////////////////////////////////// if ((bb != NULL)&&(soltype != NULL)) { *soltype = ONE; for (i = k; i < b.m_nrow; i++) if (b(i,0) > EPS) { *soltype = NONE; break; } if (*soltype==NONE) { // incompatible system *bb = std::vector(0); } else { // system compatible one or infinity of solutions *bb = (cswap * b.crop(m_ncol,1)).col(0); if (m_ncol == k) { // complete diagonalisation, one solution *soltype=ONE; } else { *soltype=INF; } } } ///////////////////////////////////// // HANDLE REQUEST FOR KERNEL // ///////////////////////////////////// if (tkern != NULL) { if (k < m_ncol) { CMatrix pk = - m.crop(m_ncol-k+1,m_ncol-k,0,k); pk = pk.crop(m_ncol,m_ncol-k); for (i=0; i + k < m_ncol; i++) pk(i+k,i) = 1; *tkern = cswap* pk; } else { // matrix is inversible *tkern = CMatrix(); } } // clean matrix for (i = 0; i < m_nrow; i++) for (j = 0; j < m_ncol; j++) if (fabs(m(i,j)) <= EPS) m(i,j) = 0; return m.crop(k,m_ncol); } /** Returns the kernel of the linear application. * associated with the matrix. */ CMatrix CMatrix::kern(const size_t& vsize) const { if (empty()) { std::cout << "REQUEST FOR KER(o)" << std::endl; return CMatrix::id(vsize); } CMatrix ret; gaussjordan(NULL,NULL,NULL,NULL,&ret); return ret; } /** Retrieves a row of the matrix in vector form. */ std::vector CMatrix::row(size_t index) const { if (index >= m_nrow) throw std::range_error("CMatrix::row : index out of bounds!"); std::vector ret(m_ncol); for (size_t i = 0; i < m_ncol; i++) ret[i] = m_data[index*m_ncol + i]; return ret; } /** Swaps two rows of a matrix. */ void CMatrix::swap_row(size_t i1, size_t i2) { if ((i1>=m_nrow)||(i2>=m_nrow)) throw std::range_error("CMatrix:swap_row : index out of bounds"); if (i1==i2) return; real temp; size_t pos1 = i1 * m_ncol; size_t pos2 = i2 * m_ncol; for (size_t j = 0; j < m_ncol; j++) { temp = m_data[pos1+j]; m_data[pos1+j] = m_data[pos2+j]; m_data[pos2+j] = temp; } } /** Swap two columns of a matrix. */ void CMatrix::swap_col(size_t j1, size_t j2) { if ((j1>=m_ncol)||(j2>=m_ncol)) throw std::range_error("CMatrix:swap_col : index out of bounds"); if (j1==j2) return; real temp; size_t pos = 0; for (size_t i = 0; i < m_nrow; i++) { temp = m_data[pos+j1]; m_data[pos+j1] = m_data[pos+j2]; m_data[pos+j2] = temp; pos += m_ncol; } } /** Transposes ('tilts') matrix */ CMatrix CMatrix::transposed() const { CMatrix ret(m_ncol,m_nrow); for (size_t i=0; i < m_ncol; i++) for (size_t j=0; j< m_nrow; j++) ret.m_data[i*ret.m_ncol + j] = m_data[j*m_ncol + i]; return ret; } /******************************************************* Operators ********************************************************/ /** Performs an assignment. */ CMatrix & CMatrix::operator=(const CMatrix &m) { if (&m == this) return *this; if ( (m_nrow != m.m_nrow) || (m_ncol != m.m_ncol) ) { if (m_data) delete [] m_data; m_nrow = m.m_nrow; m_ncol = m.m_ncol; if (m.m_data) m_data = new real[m_nrow * m_ncol]; else m_data = NULL; } if (m_data) memcpy(m_data, m.m_data, sizeof(real) * m_nrow * m_ncol); return *this; } /** Tests two matrices for equality. */ bool CMatrix::operator==(const CMatrix &m) const { if ( (m_nrow != m.m_nrow) || (m_ncol != m.m_ncol) ) return false; for (size_t i=0; i < m_nrow; i++) for (size_t j=0; j < m_ncol; j++) if ( (*this)(i,j) != m(i,j) ) return false; return true; } /** Tests two matrices for non-equality. */ bool CMatrix::operator!=(const CMatrix &m) const { return !(*this == m); } /** Return the opposite of a matrix. */ CMatrix CMatrix::operator-() const { CMatrix ret(m_nrow,m_ncol); for (size_t pos = 0; pos < m_nrow * m_ncol; pos++) ret.m_data[pos] = - m_data[pos]; return ret; } /** Matrix product */ CMatrix CMatrix::operator*(const CMatrix &m2) const { if (m_ncol != m2.m_nrow) throw std::invalid_argument("CMatrix::operator*: dimension mismatch!"); CMatrix p(m_nrow, m2.m_ncol); size_t pos = 0; for (size_t i = 0; i < p.m_nrow; i++) for (size_t j = 0; j < p.m_ncol; j++) { for (size_t k=0; k < m_ncol; k++) p.m_data[pos] += m2.m_data[m2.m_ncol * k + j] * m_data[m_ncol * i + k]; pos++; } return p; } /** Multiplies a matrix by a vector. */ std::vector CMatrix::operator*(const std::vector &v) const { if (m_ncol != v.size()) throw std::invalid_argument("CMatrix::operator*: dimension mismatch!"); // result is initialised to zero std::vector p(m_nrow); size_t pos = 0; for (size_t i = 0; i < m_nrow; i++) { for (size_t k=0; k < m_ncol; k++) { p[i] += m_data[pos] * v[k]; pos++; } } return p; } sailcut-1.5.0/src/geocpp/matrix.h000066400000000000000000000102701477005247400167140ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef GEOCPP_MATRIX_H #define GEOCPP_MATRIX_H #include #include #include enum soltype_t { NONE, ONE, INF }; /** Class for describing matrices. * * @ingroup GeoCpp */ class CMatrix { public: /** Constructs a CMatrix with the given number of rows and columns. */ CMatrix(const size_t &nrow = 0, const size_t &ncol = 0) : m_nrow(nrow), m_ncol(ncol) { if (!empty()) { m_data = new real[m_nrow * m_ncol]; memset(m_data, 0, sizeof(real) * m_nrow * m_ncol); } else { m_data = NULL; } }; /** Copy constructor. */ CMatrix(const CMatrix &m) : m_nrow(m.m_nrow), m_ncol(m.m_ncol) { if (!empty()) { m_data = new real[m_nrow * m_ncol]; memcpy(m_data, m.m_data, sizeof(real) * m_nrow * m_ncol); } else { m_data = NULL; } }; /** The destructor. */ ~CMatrix() { if (!empty()) delete [] m_data; }; // static functions static CMatrix id(const size_t&); static CMatrix rnd(const size_t&, const size_t&); static CMatrix rot3d(const size_t&, const real&); // member functions CMatrix crop(const size_t& nr, const size_t& nc, const size_t& nrz=0, const size_t& ncz=0) const; real determinant() const; CMatrix dev(const size_t&, const size_t&) const; /** Accessor for the number of columns. */ size_t columns() const { return m_ncol; } /** Accessor for the number of rows. */ size_t rows() const { return m_nrow; } /** Is the matrixan empty (0x0) matrix? */ bool empty() const { return ! (m_ncol && m_nrow); } CMatrix gaussjordan(bool *is_inv=NULL, CMatrix *inv=NULL, soltype_t *soltype=NULL, std::vector *bb=NULL, CMatrix *tkern=NULL) const; CMatrix kern(const size_t& vsize) const; CMatrix transposed() const; // operators real& operator() ( const size_t& row, const size_t& col ); real operator() ( const size_t& row, const size_t& col ) const; CMatrix& operator=(const CMatrix &); bool operator==(const CMatrix &) const; bool operator!=(const CMatrix &) const; CMatrix operator-() const; CMatrix operator*(const CMatrix &) const; std::vector operator*(const std::vector &) const; private: std::vector col(size_t) const; std::vector row(size_t) const; void swap_row(size_t, size_t); void swap_col(size_t, size_t); /** the matrix's data */ real* m_data; /** number of rows */ size_t m_nrow; /** number of columns */ size_t m_ncol; }; // inlines /** Returns the selected element of the matrix. */ inline real& CMatrix::operator() (const size_t& row, const size_t& col) { #ifdef CHECK_DIMENSIONS if (row >= m_nrow || col >= m_ncol) throw std::range_error("CMatrix::operator() : index out of bounds"); #endif return m_data[m_ncol * row + col]; } /** Returns the selected element of the matrix. */ inline real CMatrix::operator() (const size_t& row, const size_t& col) const { #ifdef CHECK_DIMENSIONS if (row >= m_nrow || col >= m_ncol) throw std::range_error("CMatrix::operator() : index out of bounds"); #endif return m_data[m_ncol * row + col]; } #endif sailcut-1.5.0/src/geocpp/matrix4x4.cpp000066400000000000000000000121161477005247400176100ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include CMatrix4x4::CMatrix4x4() { m[0][0] = 1.0f; m[0][1] = 0.0f; m[0][2] = 0.0f; m[0][3] = 0.0f; m[1][0] = 0.0f; m[1][1] = 1.0f; m[1][2] = 0.0f; m[1][3] = 0.0f; m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = 1.0f; m[2][3] = 0.0f; m[3][0] = 0.0f; m[3][1] = 0.0f; m[3][2] = 0.0f; m[3][3] = 1.0f; } void CMatrix4x4::rotate(real angle, const CVector3d &vector) { if (angle == 0.0) return; const real c = std::cos(angle); const real s = std::sin(angle); const real ic = 1.0 - c; const CVector3d n = vector.normalized(); const real x = n.x(); const real y = n.y(); const real z = n.z(); CMatrix4x4 rot; rot.m[0][0] = x * x * ic + c; rot.m[1][0] = x * y * ic - z * s; rot.m[2][0] = x * z * ic + y * s; rot.m[3][0] = 0.0f; rot.m[0][1] = y * x * ic + z * s; rot.m[1][1] = y * y * ic + c; rot.m[2][1] = y * z * ic - x * s; rot.m[3][1] = 0.0f; rot.m[0][2] = x * z * ic - y * s; rot.m[1][2] = y * z * ic + x * s; rot.m[2][2] = z * z * ic + c; rot.m[3][2] = 0.0f; rot.m[0][3] = 0.0f; rot.m[1][3] = 0.0f; rot.m[2][3] = 0.0f; rot.m[3][3] = 1.0f; *this *= rot; } void CMatrix4x4::translate(const CVector3d& vector) { const real vx = vector.x(); const real vy = vector.y(); const real vz = vector.z(); m[3][0] += m[0][0] * vx + m[1][0] * vy + m[2][0] * vz; m[3][1] += m[0][1] * vx + m[1][1] * vy + m[2][1] * vz; m[3][2] += m[0][2] * vx + m[1][2] * vy + m[2][2] * vz; m[3][3] += m[0][3] * vx + m[1][3] * vy + m[2][3] * vz; } CMatrix4x4& CMatrix4x4::operator*=(const CMatrix4x4& other) { float m0, m1, m2; m0 = m[0][0] * other.m[0][0] + m[1][0] * other.m[0][1] + m[2][0] * other.m[0][2] + m[3][0] * other.m[0][3]; m1 = m[0][0] * other.m[1][0] + m[1][0] * other.m[1][1] + m[2][0] * other.m[1][2] + m[3][0] * other.m[1][3]; m2 = m[0][0] * other.m[2][0] + m[1][0] * other.m[2][1] + m[2][0] * other.m[2][2] + m[3][0] * other.m[2][3]; m[3][0] = m[0][0] * other.m[3][0] + m[1][0] * other.m[3][1] + m[2][0] * other.m[3][2] + m[3][0] * other.m[3][3]; m[0][0] = m0; m[1][0] = m1; m[2][0] = m2; m0 = m[0][1] * other.m[0][0] + m[1][1] * other.m[0][1] + m[2][1] * other.m[0][2] + m[3][1] * other.m[0][3]; m1 = m[0][1] * other.m[1][0] + m[1][1] * other.m[1][1] + m[2][1] * other.m[1][2] + m[3][1] * other.m[1][3]; m2 = m[0][1] * other.m[2][0] + m[1][1] * other.m[2][1] + m[2][1] * other.m[2][2] + m[3][1] * other.m[2][3]; m[3][1] = m[0][1] * other.m[3][0] + m[1][1] * other.m[3][1] + m[2][1] * other.m[3][2] + m[3][1] * other.m[3][3]; m[0][1] = m0; m[1][1] = m1; m[2][1] = m2; m0 = m[0][2] * other.m[0][0] + m[1][2] * other.m[0][1] + m[2][2] * other.m[0][2] + m[3][2] * other.m[0][3]; m1 = m[0][2] * other.m[1][0] + m[1][2] * other.m[1][1] + m[2][2] * other.m[1][2] + m[3][2] * other.m[1][3]; m2 = m[0][2] * other.m[2][0] + m[1][2] * other.m[2][1] + m[2][2] * other.m[2][2] + m[3][2] * other.m[2][3]; m[3][2] = m[0][2] * other.m[3][0] + m[1][2] * other.m[3][1] + m[2][2] * other.m[3][2] + m[3][2] * other.m[3][3]; m[0][2] = m0; m[1][2] = m1; m[2][2] = m2; m0 = m[0][3] * other.m[0][0] + m[1][3] * other.m[0][1] + m[2][3] * other.m[0][2] + m[3][3] * other.m[0][3]; m1 = m[0][3] * other.m[1][0] + m[1][3] * other.m[1][1] + m[2][3] * other.m[1][2] + m[3][3] * other.m[1][3]; m2 = m[0][3] * other.m[2][0] + m[1][3] * other.m[2][1] + m[2][3] * other.m[2][2] + m[3][3] * other.m[2][3]; m[3][3] = m[0][3] * other.m[3][0] + m[1][3] * other.m[3][1] + m[2][3] * other.m[3][2] + m[3][3] * other.m[3][3]; m[0][3] = m0; m[1][3] = m1; m[2][3] = m2; return *this; } sailcut-1.5.0/src/geocpp/matrix4x4.h000066400000000000000000000037211477005247400172570ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef GEOCPP_MATRIX4X4_H #define GEOCPP_MATRIX4X4_H #include class CMatrix4x4 { public: CMatrix4x4(); void rotate(real angle, const CVector3d &vector); void translate(const CVector3d &vector); private: real m[4][4]; CMatrix4x4& operator*=(const CMatrix4x4 &other); friend CVector3d operator*(const CMatrix4x4 &matrix, const CVector3d &vector); }; inline CVector3d operator*(const CMatrix4x4 &matrix, const CVector3d &vector) { real x, y, z, w; x = vector.x() * matrix.m[0][0] + vector.y() * matrix.m[1][0] + vector.z() * matrix.m[2][0] + matrix.m[3][0]; y = vector.x() * matrix.m[0][1] + vector.y() * matrix.m[1][1] + vector.z() * matrix.m[2][1] + matrix.m[3][1]; z = vector.x() * matrix.m[0][2] + vector.y() * matrix.m[1][2] + vector.z() * matrix.m[2][2] + matrix.m[3][2]; w = vector.x() * matrix.m[0][3] + vector.y() * matrix.m[1][3] + vector.z() * matrix.m[2][3] + matrix.m[3][3]; if (w == 1.0) return CVector3d(x, y, z); else return CVector3d(x / w, y / w, z / w); } #endif sailcut-1.5.0/src/geocpp/rect.cpp000066400000000000000000000051721477005247400167050ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include /** Translate box by a vector. * * @param transl translation vector */ CRect3d CRect3d::operator+ (const CVector3d &transl) const { CRect3d ret; ret.min = min + transl; ret.max = max + transl; return ret; } /** Expand/shrink box by a coefficient, keeping the same center. * * @param r coefficient */ CRect3d CRect3d::operator* (const real r) const { CRect3d ret; CVector3d off = (r-1) * 0.5 * (max - min); ret.min = min - off; ret.max = max + off; return ret; } /** Return the minimum rectangle containing the current rectangle * with the given aspect ratio (width / height). */ CRect3d CRect3d::expandToRatio(const real ratio) const { CRect3d lRect(*this); const real w = width(); const real h = height(); if (!w || !h) return lRect; const real objAspect = w / h; if (objAspect > ratio) { const real extrah = 0.5 * h * (objAspect/ratio - 1); // we are limited by the width of the window, grow logical viewport's height lRect.min.setY(lRect.min.y() - extrah); lRect.max.setY(lRect.max.y() + extrah); } else { real extraw = 0.5 * w * (ratio/objAspect - 1); // we are limited by the height of the window, grow logical viewport's width lRect.min.setX(lRect.min.x() - extraw); lRect.max.setX(lRect.max.x() + extraw); } return lRect; } /** Return the minimum rectangle containing the current rectangle * and the one given as an argument. * * @param rect */ CRect3d CRect3d::join(const CRect3d& rect) const { CRect3d ret = *this; for (size_t j = 0; j < 3; j++) { if (rect.min[j] < ret.min[j]) ret.min[j] = rect.min[j]; if (rect.max[j] > ret.max[j]) ret.max[j] = rect.max[j]; } return ret; } sailcut-1.5.0/src/geocpp/rect.h000066400000000000000000000035401477005247400163470ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef GEOCPP_RECT_H #define GEOCPP_RECT_H #include /** Three dimensional box. * * @ingroup GeoCpp */ class CRect3d { public: /** Construct a new 3D box. */ CRect3d() {} ; /** Construct a new 3D box given its corners. * * @param pmin * @param pmax */ CRect3d(const CPoint3d &pmin, const CPoint3d &pmax) : min(pmin), max(pmax) {} ; // operators CRect3d operator+ (const CVector3d &transl) const; CRect3d operator* (const real r) const; /** Return the box's center. */ CPoint3d center() const { return 0.5 * (min + max); }; CRect3d expandToRatio(const real ratio) const; /** Return the box's width. */ real width() const { return max.x()-min.x(); }; /** Return the box's height. */ real height() const { return max.y()-min.y(); }; CRect3d join(const CRect3d& rect) const; /** lower-left corner */ CPoint3d min; /** top-right corner */ CPoint3d max; }; #endif sailcut-1.5.0/src/geocpp/subspace.cpp000066400000000000000000000164611477005247400175600ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define SIZE 3 #include "subspace.h" static CVector3d fromRealVector(const std::vector &vv) { CVector3d v; for (size_t i = 0; i < std::min(size_t(3), vv.size()); ++i) v[i] = vv[i]; return v; } static std::vector toRealVector(const CVector3d &v) { std::vector vv(3); vv[0] = v.x(); vv[1] = v.y(); vv[2] = v.z(); return vv; } /******************************************************* Construction / destruction ********************************************************/ /** Constructs an empty CSubSpace. */ CSubSpace::CSubSpace() : isEmpty(true) { } /** Constructs a CSubSpace from a point and either the equations or * a base of the subspace. * * @param pi a point in the subspace * @param mi a matrix containing the equations or the base of the subspace * @param createflags specifies whether we were given the equations or the base of the subspace */ CSubSpace::CSubSpace(const CVector3d &pi, const CMatrix &mi, subspaceflags_t createflags) : isEmpty(false) , p(pi) { switch ( createflags ) { case GEOCPP_FROM_EQS: // equations are given in lines if ( (mi.rows() > 0) && (mi.columns() != SIZE) ) throw std::invalid_argument("CSubSpace::CSubSpace(p,m,GEOCPP_FROM_EQS) : dimension mismatch between p and m"); m = mi; break; case GEOCPP_FROM_BASE: // base is given in column format if ( (mi.columns() > 0) && (mi.rows() != SIZE) ) throw std::invalid_argument("CSubSpace::CSubSpace(p,m,GEOCPP_FROM_BASE) : dimension mismatch between p and m"); m = mi.transposed().kern(SIZE).transposed(); break; default: throw std::invalid_argument("CSubSpace::CSubspace(p,m,createflags) : unknown creation flags"); } } /** Test whether the CSubSpace contains a given point. */ bool CSubSpace::contains(const CVector3d &point) const { std::vector prod = m * toRealVector(point-p); real lengthSquared = 0; for (size_t i = 0; i < prod.size(); ++i) lengthSquared += prod[i] * prod[i]; return sqrt(lengthSquared) <= EPS; } /** Return the subspace's dimension. */ int CSubSpace::getdim() const { if (isEmpty) return -1; else return SIZE - m.rows(); } /** Performs the intersection of two CSubSpace objects. */ CSubSpace CSubSpace::intersect(const CSubSpace &h2) const { if (isEmpty || h2.isEmpty) return CSubSpace(); std::vector b1 = m * toRealVector(p); std::vector b2 = h2.m * toRealVector(h2.p); std::vector bb( m.rows() + h2.m.rows() ); CMatrix mm( m.rows() + h2.m.rows(), SIZE ); for (size_t i = 0 ; i < mm.rows() ; i++) { if ( i < m.rows() ) { for (size_t j = 0 ; j < mm.columns() ; j++) mm(i,j) = m(i,j); bb[i] = b1[i]; } else { for (size_t j = 0 ; j < mm.columns() ; j++) mm(i,j) = h2.m(i - m.rows(), j); bb[i] = b2[i - m.rows()]; } } soltype_t soltype = NONE; CMatrix k; mm.gaussjordan(NULL, NULL, &soltype, &bb, &k); CVector3d s = fromRealVector(bb); switch (soltype) { case ONE: // system has unique solution return CSubSpace(s, CMatrix::id(SIZE), GEOCPP_FROM_EQS); case INF: // system has an infinity of solutions return CSubSpace(s, k, GEOCPP_FROM_BASE); case NONE: // system has no solution break; } return CSubSpace(); } CVector3d CSubSpace::intersectionPoint(const CSubSpace &h2, const std::string &name) const { CSubSpace i = intersect(h2); if (i.getdim() != 0) throw std::runtime_error("CSubSpace::intersectionPoint : intersection " + name + " is not a point"); return i.getp(); } /** Create a CSubSpace representing a 3D line from a point and a vector. * * @param p a point of the line * @param v a vector along the line */ CSubSpace CSubSpace::line(const CPoint3d &p, const CVector3d &v) { if (!v.length()) { std::cout << "CSubSpace::line : Crash point = " << p << std::endl; throw std::invalid_argument("CSubSpace::line : Input vector cannot be zero point "); } CMatrix m(3, 1); for (int i = 0; i < 3; ++i) m(i, 0) = v[i]; return CSubSpace(p, m, GEOCPP_FROM_BASE); } /** Create a CSubSpace representing a 3D plane from a point and two vectors. * * @param p a point of the plane * @param v1 a vector in the plane * @param v2 a second vector in the plane, not colinear with v1 */ CSubSpace CSubSpace::plane(const CPoint3d &p, const CVector3d &v1, const CVector3d& v2) { if (!CVector3d::crossProduct(v1, v2).length()) { std::cout << "CSubSpace::plane : Crash point = " << p << std::endl; throw std::invalid_argument("CSubSpace::plane : 2 Vectors cannot be colinear"); } CMatrix m(3,2); for (int i = 0; i < 3; i++) { m(i, 0) = v1[i]; m(i, 1) = v2[i]; } return CSubSpace(p, m, GEOCPP_FROM_BASE); } #if 0 /******************************************************* Other functions ********************************************************/ /** Outputs a CMatrix to a stream. */ ostream& operator<< (ostream &o, const CMatrix &m) { o << "["; for (size_t i = 0 ; i < m.rows() ; i++) { o << m.row(i); if ( i != m.rows() - 1 ) o << std::endl; } o << "]"; return o; } /** Outputs the definition of a CSubSpace to a stream. */ ostream& operator<< (ostream &o, const CSubSpace &h) { o << "--------------------------------" << std::endl; o << " subspace : "; switch (h.getdim()) { case -1: o << "empty" << std::endl; break; case 0: o << "point" << std::endl; break; case 1: o << "line" << std::endl; break; case 2: o << "plane" << std::endl; break; default: o << "dim=" << h.getdim() << std::endl; } o << "--------------------------------" << std::endl; if ( h.getdim() >= 0 ) { o << "point:" << std::endl << h.getp() << std::endl; if (h.getdim()>0) { o << "------" << std::endl; o << "base vectors (in columns): " << std::endl << h.getm().kern(h.getp().size()) << std::endl << "------" << std::endl; o << "equations (coeffs in lines): " << std::endl << h.getm() << std::endl; } o << "--------------------------------" << std::endl; } return o; } #endif sailcut-1.5.0/src/geocpp/subspace.h000066400000000000000000000035251477005247400172220ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef GEOCPP_SUBSPACE_H #define GEOCPP_SUBSPACE_H #include enum subspaceflags_t { GEOCPP_FROM_BASE, GEOCPP_FROM_EQS }; /** Class for describing subspaces of an euclidian vector space, * for example the empty space, points, lines and planes. * * @ingroup GeoCpp */ class CSubSpace { public: CSubSpace(); CSubSpace(const CVector3d &pi, const CMatrix &mi, subspaceflags_t createflags); CSubSpace intersect(const CSubSpace &) const; CVector3d intersectionPoint(const CSubSpace &, const std::string &name) const; bool contains(const CVector3d &) const; int getdim() const; /** Accessor for the matrix. */ const CMatrix& getm() const { return m; } /** Accessor for the point. */ const CVector3d& getp() const { return p; } static CSubSpace line(const CPoint3d& p, const CVector3d& v); static CSubSpace plane(const CPoint3d& p, const CVector3d& v1, const CVector3d& v2); private: bool isEmpty; CMatrix m; CVector3d p; }; #endif sailcut-1.5.0/src/geocpp/vector.cpp000066400000000000000000000042311477005247400172450ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include /** * Returns true if v1 and v2 are equal, allowing for a small fuzziness factor * for floating-point comparisons; false otherwise. */ bool qFuzzyCompare(const CVector3d &v1, const CVector3d &v2) { for (size_t i = 0; i < 3; i++) if (fabs(v1[i] - v2[i]) > EPS) return false; return true; } /** Returns the vector's length. */ real CVector3d::length() const { return sqrt(m_x * m_x + m_y * m_y + m_z * m_z); } /** Returns corresponding unit length vector for non-zero vectors * and zero vector otherwise. */ CVector3d CVector3d::normalized() const { const real n = length(); if (n #include #include // types and constants typedef double real; const real EPS = 1E-14; /** 3d real-valued vector. * * @ingroup GeoCpp */ class CVector3d { public: /** Constructor. */ CVector3d(const real &x = 0, const real &y = 0, const real &z = 0) : m_x(x) , m_y(y) , m_z(z) { }; // access to coords /** Returns the first coordinate. */ real x() const { return m_x; }; /** Sets the first coordinate. */ void setX(real x) { m_x = x; }; /** Returns the second coordinate. */ real y(void) const { return m_y; }; /** Sets the second coordinate. */ void setY(real y) { m_y = y; }; /** Returns the third coordinate. */ real z(void) const { return m_z; }; /** Sets the third coordinate. */ void setZ(real z) { m_z = z; }; real length() const; CVector3d normalized() const; static CVector3d crossProduct(const CVector3d &v1, const CVector3d &v2); static real dotProduct(const CVector3d &v1, const CVector3d &v2); real &operator[](size_t idx) { return *(&m_x + idx); }; real operator[](size_t idx) const { return *(&m_x + idx); }; bool operator==(const CVector3d &v2) const { return m_x == v2.m_x && m_y == v2.m_y && m_z == v2.m_z; } /** Binary '+' operator (addition) */ CVector3d operator+(const CVector3d& v2) const { return CVector3d( m_x + v2.m_x, m_y + v2.m_y, m_z + v2.m_z); }; /** Unary '-' operator (return opposite) */ CVector3d operator-() const { return CVector3d(-m_x, -m_y, -m_z); }; /** Binary '-' operator (return difference) */ CVector3d operator-(const CVector3d &v2) const { return CVector3d( m_x - v2.m_x, m_y - v2.m_y, m_z - v2.m_z); }; /** Binary '* (multiply a vector by a real) */ CVector3d operator*(const real& lambda) const { return CVector3d( m_x * lambda, m_y * lambda, m_z * lambda); }; private: real m_x; real m_y; real m_z; }; /** 3d real-valued point * * @ingroup GeoCpp */ typedef CVector3d CPoint3d; inline real degreesToRadians(real degrees) { return degrees * (M_PI / 180); } inline real radiansToDegrees(real radians) { return radians * (180 / M_PI); } bool qFuzzyCompare(const CVector3d &v1, const CVector3d &v2); /** Binary '*' (multiply a scalar by a vector) */ inline CVector3d operator*(const real& lambda, const CVector3d &v) { return v * lambda; } std::ostream& operator<<(std::ostream &o, const CVector3d &v); #endif sailcut-1.5.0/src/main.cpp000066400000000000000000000025321477005247400154140ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "app.h" /** @mainpage * This is the documentation for Sailcut CAD's code. * * It is intended mainly for programmers, to learn more about Sailcut CAD * please visit http://www.sailcut.com/ */ /** * Sailcut CAD's main routine. * it calls CFormmain */ int main( int argc, char* argv[] ) { int retCode; CSailApp app( argc, argv ); app.readPrefs(); if (argc > 1) { app.open(argv[1]); } else { app.createSail(); } retCode = app.exec(); app.writePrefs(); return retCode; } sailcut-1.5.0/src/prefs.cpp000066400000000000000000000017341477005247400156120ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "prefs.h" /** * Constructs a class holding the user's preferences. */ CPrefs::CPrefs() : mainWindowWidth(800) , mainWindowHeight(600) { } sailcut-1.5.0/src/prefs.h000066400000000000000000000024001477005247400152460ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PREFS_H #define PREFS_H #include #include /** * A class used to store a user's preferences. */ class CPrefs { public: CPrefs(); /** The most recently used documents. */ std::vector mruDocuments; /** The width of the main window */ int mainWindowWidth; /** The height of the main window */ int mainWindowHeight; /** The preferred language. */ QString language; }; #endif sailcut-1.5.0/src/sailcpp/000077500000000000000000000000001477005247400154155ustar00rootroot00000000000000sailcut-1.5.0/src/sailcpp/boatdef.cpp000066400000000000000000000023331477005247400175260ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "boatdef.h" /** The constructor. */ CBoatDef::CBoatDef() {} /** Produce the combined panel group made up of all the panels */ CPanelGroup CBoatDef::makePanelGroup() const { CPanelGroup output; for (unsigned int i = 0; i < size(); i++) { CMatrix4x4 matrix; matrix.translate(at(i).origin); output.child.push_back(at(i).transformed(matrix)); } return output; } sailcut-1.5.0/src/sailcpp/boatdef.h000066400000000000000000000032331477005247400171730ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef BOATDEF_H #define BOATDEF_H #include "panelgroup.h" typedef enum { SAILDEF, HULLDEF, RIGDEF, PANELGROUP } enumBoatElementType; /** * A boat element. This class extends a CPanelGroup with information * about how to integrate it into a boat. * * @ingroup SailCpp * @see CBoatDef, CPanelGroup */ class CBoatElement : public CPanelGroup { public: /** the type of file this element was read from (sail, hull definition or 3D panels) */ enumBoatElementType type; /** the name of the file this element was read from */ std::string filename; /** the origin of the element */ CPoint3d origin; }; /** * A boat definition, which consists of a collection of boat elements. * * @see CBoatElement */ class CBoatDef : public std::vector { public: CBoatDef(); CPanelGroup makePanelGroup() const; }; #endif sailcut-1.5.0/src/sailcpp/hulldef.cpp000066400000000000000000000043361477005247400175520ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "hulldef.h" /** Constructs a CHullDef object from the default hull parameters * */ CHullDef::CHullDef() { // default values for hull member variables are set here hullID = "Test hull 1"; DLOA = 7500; // Deck length in millimetre DfwdHeight = 1000; // Deck height forward DaftHeight = 850; // Deck height aft DSlopeA = 6; // Deck side slope in degree from horizontal DBW = 2500; // Deck max beam width DBWPos = 50; // percent of deck length DaftW = 2000; // Deck aft width StemA = 65; // Stem inclination in degree from horizontal TransomA = 80; // Transom inclination BLWL = 7000; // Bottom length in millimetre BfwdHeight = 100; // Bottom chine forward height BaftHeight = 200; // Bottom chine aft height BSlopeA = 12; // Bottom chine plane side slope in degree from horizontal BBW = 2500; // Bottom max beam width BBWPos = 50; // Bottom chine max width position percent of deck length BaftW = 2000; // Bottom aft width BDeadriseA = 12; // Bottom plank dead rise from horizontal BSweepA = 30; // Bottom plank sweep angle in degree BfwdShape = 2; // forward coefficient power of X BaftShape = 3; // aft coefficient power of X NBPlank = 3; AutoPlank = true; TopPlankA = 75; // inclination in degree from horizontal LowPlankA = 30; } sailcut-1.5.0/src/sailcpp/hulldef.h000066400000000000000000000054031477005247400172130ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef HULLDEF_H #define HULLDEF_H #include #include /** This class holds the parameters that define a hull * and their default values. * * @ingroup SailCpp * @see CHullWorker */ class CHullDef { public: CHullDef(); /** hull ID name */ std::string hullID; //deck /** deck Length in millimeter */ real DLOA; /** deck forward height in millimeter */ real DfwdHeight; /** deck aft height in millimeter */ real DaftHeight; /** deck side slope angle in degree from horizontal */ int DSlopeA; /** deck max beam width in millimeter */ real DBW; /** deck aft width in millimeter */ real DaftW; /** deck max beam width position in percent of deck length */ int DBWPos; /** stem angle in degree from horizontal */ int StemA; /** transom angle in degree from horizontal */ int TransomA; // bottom data /** bottom chine Length in millimeter */ real BLWL; /** bottom forward height in millimeter */ real BfwdHeight; /** bottom aft height in millimeter */ real BaftHeight; /** bottom chine side slope angle in degree from horizontal */ int BSlopeA; /** bottom chine max beam width in millimeter */ real BBW; /** bottom chine aft width in millimeter */ real BaftW; /** bottom chine max beam width position in percent of deck length */ int BBWPos; /** bottom plank dead rise angle in degree from horizontal */ int BDeadriseA; /** bottom sweep angle in degree forward of transverse axis */ int BSweepA; /** Lower chine forward shape */ int BfwdShape; //* Lower chine aft shape */ int BaftShape; //planking data /** Number of side planks */ int NBPlank; /** auto planking chech box */ bool AutoPlank; /** top plank angle in degree from horizontal */ int TopPlankA; /** lower plank angle in degree from horizontal */ int LowPlankA; }; #endif sailcut-1.5.0/src/sailcpp/hullworker.cpp000066400000000000000000000210711477005247400203200ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "hullworker.h" /** The constructor does some preliminary calculations * to set internal variables, compute chine and deck plane, * and compute lower chine plane panel. */ CHullWorker::CHullWorker(const CHullDef &d) : CHullDef(d) { ptFwdChine = CPoint3d( 0 , BfwdHeight , 0 ); ptAftChine = CPoint3d( BLWL , BaftHeight , BaftW/2 ); // transom end of lower chine xBmax = real(DBWPos) * BLWL / 100; ptFwdDeck = CPoint3d( 0 , DfwdHeight , 0 ); CPoint3d p1, p2; /** compute the vertical central plane */ CVector3d v1 = CVector3d( 1 , 0 , 0 ); CVector3d v2 = CVector3d( 0 , 1 , 0 ); planeCentral = CSubSpace::plane( ptFwdChine , v1 , v2 ); /** compute the lower Chine plane */ // vector v1 is sideway tilt of chine v1 = CVector3d( 0 , -sin(degreesToRadians(BSlopeA)) , cos(degreesToRadians(BSlopeA)) ); // vector v2 is fore-aft slope of chine v2 = CVector3d( ptAftChine - ptFwdChine ); planeLowChine = CSubSpace::plane( ptFwdChine , v1 , v2 ); /** compute the Deck plane */ // vector v1 is sideway tilt of deck v1 = CVector3d( 0 , -sin(degreesToRadians(DSlopeA)) , cos(degreesToRadians(DSlopeA)) ); // vector v2 is fore-aft slope of deck v2 = CVector3d( BLWL , DaftHeight-DfwdHeight , 0 ); planeDeck = CSubSpace::plane( ptFwdDeck , v1 , v2 ); /** compute the transom plane */ // vector v1 is parallel to Z axis = perpendicular to central plane v1 = CVector3d( 0 , 0 , 1 ); // vector v2 is in inclined transom plane v2 = CVector3d( cos(degreesToRadians(TransomA)) , sin(degreesToRadians(TransomA)) , 0 ); planeTransom = CSubSpace::plane( ptAftChine , v1 , v2 ); // compute intersection line between lower chine plane and transom CSubSpace Line1 = planeLowChine.intersect(planeTransom); if (Line1.getdim() != 1) throw "ERROR in hullworker constructor = intersection chine plane and transom is not a line"; // compute intersection point of line1 with central plane located at aft width ptCentreChine = Line1.intersectionPoint(planeCentral, "low chine aft"); /** lay lower chine plane decking panel */ unsigned int j; //unsigned int npl = deck.right.size(); // number of right/left points unsigned int npb = chine.bottom.size(); // number of bottom/top points chine.top.fill( ptFwdChine , ptCentreChine ); // top edge at centre line chine.bottom.fill( ptFwdChine , ptAftChine ); // bottom edge at chine chine.left.fill( ptFwdChine , ptFwdChine ); // stem is left edge chine.right.fill( ptAftChine , ptCentreChine ); // transom is right edge for (j=0 ; j < npb ; j++) { // move bottom point to chine p1 = chine.bottom[j]; p2 = ptLowChine( p1.x() ); chine.bottom[j] = p2; } } /** Return the 3D point at the Lower chine edge function of x * x is the absisse of the point along the centre line * The chine edge curve is a power curve on either side of the maximum beam point */ CPoint3d CHullWorker::ptLowChine( const real &x ) { real x1 = 0 , y = 0 , z = 0; /* compute width z function of x */ if (x > xBmax) { // aft part of chine x1 = (x - xBmax) / (ptAftChine.x() - xBmax); z = (.5 * BBW) + .5* (BaftW - BBW)* pow(x1 , BaftShape); } else { // fwd part of chine x1 = 1 - ( x / xBmax ); z = (.5 * BBW) * (1- pow(x1 , BfwdShape) ); } /* create point with x input, y=0 and z computed */ CPoint3d pt = CPoint3d ( x , y , z ); /* compute y by projecting pt vertically on the chine plane */ return planeLowChine.intersectionPoint(CSubSpace::line(pt, CVector3d(0, 1, 0)), "low chine"); } /** Return the 3D point at the keel line function of x * x is the absisse of the corresponding point on the lower chine */ CPoint3d CHullWorker::ptKeel( const real &x ) { CPoint3d pt; CVector3d v1; // create point with x input and y, z computed pt = ptLowChine ( x ); /* Ruling vector with deadrise and sweep. */ v1 = CVector3d( tan(degreesToRadians(BSweepA)) , tan(degreesToRadians(BDeadriseA)) , 1 ); /* Project pt on central plane, get intersection with the ruling line passing through point pt. */ return planeCentral.intersectionPoint(CSubSpace::line(pt, v1), "keel"); } /** Creates the basic hull with bottom, deck * and only one top side plank. * * @return CPanelGroup */ CPanelGroup CHullWorker::makeHull() //const { CPanel deck1, deck2, plank1, plank2; unsigned int j; real x; CPoint3d pt , pt0 , p1 , p2 , p3 , p4; CVector3d v1 , v2 , v3 , vg; // create the hull type CPanelGroup hull; hull.type = HULL; // used for color scheme in saildispgl hull.title = hullID; /** NOTE: the code will have to be changed to build the full hull from the lower chine */ unsigned int npl = chine.right.size(); // number of right/left points unsigned int npb = chine.bottom.size(); // number of bottom/top points deck1 = chine; plank1 = chine; /** Lay the two bottom panels with top edge at centre plane */ for (j = 0 ; j < npb ; j++) { plank1.bottom[j] = chine.bottom[j]; x = chine.bottom[j].x(); plank1.top[j] = ptKeel( x ); } plank1.left.fill( plank1.bottom[0] , plank1.top[0] ); // NOTE: bottom right edge incomplete until code is added to cope with sweep plank1.right.fill( plank1.bottom[npb-1] , plank1.top[npb-1] ); plank2 = plank1; for (j = 0 ; j < npb ; j++) { // mirror points plank2.top[j].setZ(-plank1.top[j].z()); plank2.bottom[j].setZ(-plank1.bottom[j].z()); } for (j = 0 ; j < npl ; j++) { // mirror points plank2.left[j].setZ(-plank1.left[j].z()); plank2.right[j].setZ(-plank1.right[j].z()); } // add the bottom planks to the hull hull.push_back(plank1); hull.push_back(plank2); /** Lay a single top side plank on each side with bottom at chine */ v1 = CVector3d( -cos(degreesToRadians(StemA)) , sin(degreesToRadians(TopPlankA)) , cos(degreesToRadians(TopPlankA)) ); for (j = 0 ; j < npb ; j++) { plank1.bottom[j] = chine.bottom[j]; p1 = planeDeck.intersectionPoint(CSubSpace::line(plank1.bottom[j], v1), "top side"); // compute the vector vg which generate the side surface vg = CVector3d(p1 - pt); plank1.top[j] = p1; } plank1.left.fill( plank1.bottom[0] , plank1.top[0] ); plank1.right.fill( plank1.bottom[npb-1] , plank1.top[npb-1] ); plank2 = plank1; for (j = 0 ; j < npb ; j++) { // mirror points plank2.top[j].setZ(-plank1.top[j].z()); plank2.bottom[j].setZ(-plank1.bottom[j].z()); } for (j = 0 ; j < npl ; j++) { // mirror points plank2.left[j].setZ(-plank1.left[j].z()); plank2.right[j].setZ(-plank1.right[j].z()); } // add the top side planks to the hull hull.push_back(plank1); hull.push_back(plank2); /** Lay the two deck planks */ for (j = 0 ; j < npb ; j++) { deck1.bottom[j] = plank1.top[j]; deck1.top[j] = deck1.bottom[j]; deck1.top[j].setZ(0); deck1.left.fill(deck1.bottom[0] , deck1.top[0]); deck1.right.fill(deck1.bottom[npb-1] , deck1.top[npb-1]); deck2.bottom[j] = plank2.top[j]; deck2.top[j] = deck2.bottom[j]; deck2.top[j].setZ(0); deck2.left.fill(deck2.bottom[0] , deck2.top[0]); deck2.right.fill(deck2.bottom[npb-1] , deck2.top[npb-1]); } // add the deck planks to the hull hull.push_back(deck1); hull.push_back(deck2); // translate the hull such that stem is at x=O, y=0, z=0 /// j = hull.size() -1; pt0 = hull[j].top[0]; for (j = 0 ; j < hull.size() ; j++) { hull[j] = hull[j] + CVector3d(-pt0); } return hull; } sailcut-1.5.0/src/sailcpp/hullworker.h000066400000000000000000000043321477005247400177660ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef HULLWORKER_H #define HULLWORKER_H #include "panelgroup.h" #include "hulldef.h" /** The CHullWorker class does all the hull-related calculations. * It is used to create the hull from its definition. * * @ingroup SailCpp * @see CHullDef, CPanelGroup */ class CHullWorker : public CHullDef { public: CHullWorker(const CHullDef &d); CPanelGroup makeHull(); protected: /** abciss of Bmax point on chine */ real xBmax; /** function compute a point on Deck edge */ CPoint3d ptDeck( const real &x ); /** function compute a point on Keel line */ CPoint3d ptKeel( const real &x); /** function compute a point on chine n */ CPoint3d ptChine(const int &n, const real &x ); /** function compute a point on lower Chine */ CPoint3d ptLowChine( const real &x ); /** central plane longitudinal X-Y */ CSubSpace planeCentral; /** deck plane */ CSubSpace planeDeck; /** transom plane */ CSubSpace planeTransom; /** chine plane */ CSubSpace planeChine[5]; CSubSpace planeLowChine; /** Lower Chine point at stem/centre line */ CPoint3d ptFwdChine; /** Lower Chine point at transom/edge */ CPoint3d ptAftChine; /** Lower Chine point at transom/centre line */ CPoint3d ptCentreChine; /** Deck Forward Point */ CPoint3d ptFwdDeck; /** basic panels */ CPanel deck; CPanel plank; CPanel chine; }; #endif sailcut-1.5.0/src/sailcpp/panel.cpp000066400000000000000000000717751477005247400172410ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "panel.h" #include "sailcalc.h" /** Normalize the given vector then rotate it about the Z axis. */ CVector3d rotateNormalized(real angle, const CVector3d &v) { CMatrix4x4 matrix; matrix.rotate(angle, CVector3d(0, 0, 1)); return matrix * v.normalized(); } /***************************************************************************** CPanelLabel class *****************************************************************************/ /** Default constructor */ CPanelLabel::CPanelLabel() : name("new panel"), height(5), color(1), origin(CPoint3d(0,0,0)), direction(CVector3d(0,0,0)) {} /** Copy constructor. */ CPanelLabel::CPanelLabel( const CPanelLabel &lb ) : name(lb.name), height(lb.height), color(lb.color), origin(lb.origin), direction(lb.direction) {} /** Transforms a label. */ CPanelLabel CPanelLabel::transformed(const CMatrix4x4 &m) const { CPanelLabel lb; lb.name = name; lb.height = height; lb.color = color; lb.origin = m * origin; lb.direction = m * direction - m * CVector3d(0, 0, 0); return lb; } // operators /** Performs an assignment. */ CPanelLabel& CPanelLabel::operator= (const CPanelLabel &lb) { if (&lb == this) return *this; name = lb.name; height = lb.height; color = lb.color; origin = lb.origin; direction = lb.direction; return *this; } /***************************************************************************** CPanel class *****************************************************************************/ /** Default constructor */ CPanel::CPanel() : left(7), right(7), top(21), bottom(21), cutLeft(7), cutRight(7), cutTop(21), cutBottom(21), hasHems(false) {} /** Copy constructor. */ CPanel::CPanel( const CPanel &p ) : label(p.label), left(p.left), right(p.right), top(p.top), bottom(p.bottom), cutLeft(p.cutLeft), cutRight(p.cutRight), cutTop(p.cutTop), cutBottom(p.cutBottom), hasHems(p.hasHems) {} /** This routine returns the smallest 3D box that contains the panel. */ CRect3d CPanel::boundingRect() const { CRect3d rect; const CSide * sarray[4]; if (hasHems) { sarray[0]= &cutTop; sarray[1] = &cutBottom; sarray[2] = &cutLeft; sarray[3] = &cutRight; ; } else { sarray[0]= ⊤ sarray[1] = ⊥ sarray[2] = &left; sarray[3] = &right; ; } rect.min = rect.max = top[0]; for (unsigned int s = 0 ; s < 4 ; s++) { for (unsigned int i = 0 ; i < sarray[s]->size() ; i++) { CPoint3d curPoint = (*sarray[s])[i]; for (unsigned int j = 0 ; j < 3 ; j++) { if ( curPoint[j] < rect.min[j] ) rect.min[j] = curPoint[j]; if ( curPoint[j] > rect.max[j] ) rect.max[j] = curPoint[j]; } } } return rect; } /** This routine returns the arithmetic average of all the edge points of a panel. */ CPoint3d CPanel::centroid() const { const CSide * sarray[4] = { &top, &bottom, &left, &right }; CPoint3d p, prev, sum; unsigned int nbDiffPoints = 0; for (unsigned int s = 0; s < 4; s++) { for (unsigned int i = 0 ; i < sarray[s]->size() ; i++) { p = (*sarray[s])[i]; if (( nbDiffPoints == 0) || !qFuzzyCompare(p, prev) ) { // count only distinct points prev = p; sum = sum + p; nbDiffPoints++; } } } if ( nbDiffPoints > 0 ) { real coeff = 1.0 / real(nbDiffPoints); sum = sum * coeff; } return sum; } /** This routine returns the development of the panel. * The developed panel will be horizontal with its upper or lower edge * aligned to X axis depending on parameter "align"=ALIGN_TOP or ALIGN_BOTTOM */ CPanel CPanel::develop(enumDevelopAlign align) const { CPanel flatpanel; unsigned int npl = left.size(); // number of right/left points unsigned int npb = bottom.size(); // number of top/bottom points unsigned int i; real a = 0, b = 0, c = 0; // sides of triangle real CC = 0; // angle opposite to side c of triangle CVector3d v; CPoint3d p1, p2, p3, p4; // points for 2 triangular elements of panel to be developed CPoint3d d3(0,0,0); // point after development /** establish origine at bottom point 0 */ flatpanel.bottom[0] = d3; /** establish the baseline as (top point1 - bottom point1) */ p1= bottom[1]; p2 = top[1]; p3 = bottom[0]; a = ( p2 - p1 ).length(); // vertical side at point 1 b = ( p3 - p1 ).length(); // lower side of triangle c = ( p2 - p3 ).length(); CC = Atriangle( a , b , c ); // angle of bottom left corner = opposite to side a d3.setX(b); // set base of first triangle on X axis flatpanel.bottom[1] = d3; // set point at top of baseline d3 = flatpanel.bottom[0] + rotateNormalized(CC, CVector3d(1, 0, 0)) * c; flatpanel.top[1] = d3; // set baseline vector v = flatpanel.bottom[1] - flatpanel.top[1]; /** develop left side of panel by triangulation */ for (i = 0 ; i < npl ; i++) { p3 = left[i]; b = ( p3 - p1 ).length(); // lower side of triangle c = ( p3 - p2 ).length(); // upper side of triangle CC = Atriangle( c , a , b ); // angle of bottom corner = opposite to upper side // transpose corner of triangle in development plane d3 = flatpanel.bottom[1] + rotateNormalized(-M_PI + CC, v) * b; flatpanel.left[i] = d3; } // copy lower left point to bottom[0] to close the corner flatpanel.bottom[0] = flatpanel.left[0]; // copy upper left point to top[0] flatpanel.top[0] = flatpanel.left[npl-1]; /** develop body of panel by zig-zag triangulation */ // reset baseline vector for lower right point v = flatpanel.bottom[1] - flatpanel.top[1]; c = v.length(); for (i = 1 ; i < npb-2 ; i++) { // define the 4 points corners of 2 adjacent triangles p1 = bottom[i]; p2 = top[i]; p3 = bottom[i+1]; p4 = top[i+1]; // first triangle = lower right p1-p2-p3 a = c; b = ( p3 - p1 ).length(); c = ( p3 - p2 ).length(); CC = Atriangle( c , b , a ); // transpose corner of triangle in development plane d3 = flatpanel.bottom[i] + rotateNormalized(M_PI - CC, v) * b; flatpanel.bottom[i+1] = d3; // set baseline vector for upper right point v = flatpanel.top[i] - flatpanel.bottom[i+1]; // second triangle = upper right a = c; b = ( p4 - p2 ).length(); c = ( p4 - p3 ).length(); CC = Atriangle( c, b, a ); // transpose corner of triangle in development plane d3 = flatpanel.top[i] + rotateNormalized(-M_PI + CC, v) * b; flatpanel.top[i+1] = d3; // set next baseline vector v = flatpanel.bottom[i+1] - flatpanel.top[i+1]; } /** develop right side of panel */ a= c; // set baseline on last 2 points for (i = 0 ; i < npl ; i++) { p1 = right[i]; b = CVector3d(p3-p1).length(); // lower side of triangle c = CVector3d(p4-p1).length(); // upper side of triangle CC = Atriangle(c,a,b); // angle of bottom corner = opposite to upper side // transpose corner of triangle in development plane d3 = flatpanel.bottom[npb-2] + rotateNormalized(M_PI - CC, v) * b; flatpanel.right[i]= d3; } // copy lower right point to bottom end to close the corner flatpanel.bottom[npb-1]= flatpanel.right[0]; // copy upper right point to top end flatpanel.top[npb-1]= flatpanel.right[npl-1]; /** re-align panel with top or bottom edge along X axis */ CC = 0; if (align == ALIGN_TOP) { // align on top edge p1 = flatpanel.top[0]; p2 = flatpanel.top[npb-1]; CC = atan2( (p2.y()-p1.y()) , (p2.x()-p1.x()) ); } else { // align on bottom edge p1 = flatpanel.bottom[0]; p2 = flatpanel.bottom[npb-1]; CC = atan2( (p2.y()-p1.y()) , (p2.x()-p1.x()) ); } // align panel flatpanel = flatpanel.rotated(CPoint3d(0,0,0), -CC, Qt::ZAxis); flatpanel.hasHems = false; /** frame the developed panel to be X>0 and Y>0 */ flatpanel.reframe(); return flatpanel; } /** Place the label at the center of the panel */ void CPanel::placeLabel() { label.origin = centroid(); } /** Translate the panel so that the most left / bottom points * are at coordinates X=0, Y =0. */ void CPanel::reframe() { if (hasHems) { *this = *this + CVector3d(-cutLeft.left(), -cutBottom.bottom(), 0); } else { *this = *this + CVector3d(-left.left(), -bottom.bottom(), 0); } } /** Add the cloth for stitching to the 4 edges of the panel. * This create the panel to be cut (outside the basic panel) * lw = width to be added on left side * tw = width to be added on top side * rw = width to be added on right side * bw = width to be added on bottom side */ void CPanel::addHems( const real &lw, const real &tw, const real &rw, const real &bw ) { add6Hems( lw, lw, tw, rw, rw, bw ); } /** Add the cloth for stitching to the 6 edges of the panel. * This create the panel to be cut (outside the basic panel) * lolW, hilW = width to be added on lo-hi left side * topW = width to be added on top side * lorW, hirW = width to be added on lo-hi right side * botW = width to be added on bottom side */ void CPanel::add6Hems( const real &lolW, const real &hilW, const real &topW, const real &hirW, const real &lorW, const real &botW ) { hasHems = true; CPoint3d pt(0,0,0); CVector3d v(1,0,0); CVector3d v0(1,0,0); CSubSpace Line1, Line2; // two lines real minSize = 0.1; // used to avoid computation near zero width side unsigned int i = 0; unsigned int npl = left.size(), npb = bottom.size(); ///* compute basic edges vectors */ CVector3d v1 = left[npl/2] - left[0]; // if ( v1.length() == 0 ) std::cout << "CPanel::add6Hems v1=0 " << std::endl; CVector3d v2 = left[npl-1] - left[npl/2]; // if ( v2.length() == 0 ) std::cout << "CPanel::add6Hems v2=0 " << std::endl; CVector3d v3 = right[npl/2] - right[0]; // if ( v3.length() == 0 ) std::cout << "CPanel::add6Hems v3=0 " << std::endl; CVector3d v4 = right[npl-1] - right[npl/2]; // if ( v4.length() == 0 ) std::cout << "CPanel::add6Hems v4=0 " << std::endl; CVector3d v5 = bottom[npb-1] - bottom[0]; // if ( v5.length() == 0 ) std::cout << "CPanel::add6Hems v5=0 " << std::endl; CVector3d v6 = bottom[npb-1] - bottom[npb-2]; // if ( v6.length() == 0 ) std::cout << "CPanel::add6Hems v6=0 " << std::endl; CVector3d v7 = top[npb-1] - top[0]; // if ( v7.length() == 0 ) std::cout << "CPanel::add6Hems v7=0 " << std::endl; CVector3d v8 = top[npb-1] - top[npb-2]; // if ( v8.length() == 0 ) std::cout << "CPanel::add6Hems v8=0 " << std::endl < EPS ) { // width of material is not too small for (i = 0 ; i < npb ; i++) { if ( i == 0 ) v = bottom[1] - bottom[0]; else v = bottom[i] - bottom[i-1]; if ( v.length() <= EPS ) v = v5; cutBottom[i] = bottom[i] + rotateNormalized(-M_PI / 2, v) * botW; } } ///* Move the basic top edge points to the cut line */ if ( topW > EPS ) { // width of material is not too small for (i = 0 ; i < npb ; i++) { if ( i == 0 ) v = top[1] - top[0]; else v = top[i] - top[i-1]; if ( v.length() <= minSize ) v = v7; cutTop[i] = top[i] + rotateNormalized(M_PI / 2, v) * topW; } } ///* Move the basic left edge points to the cut line */ if ( v1.length() >= minSize ) { // lower left side is not a point for (i = 0 ; i < npl/2 ; i++) { if ( i == 0 ) v = left[1] - left[0]; else v = left[i] - left[i-1]; cutLeft[i] = left[i] + rotateNormalized(M_PI/2, v) * lolW; } v0 = left[npl/2] - left[npl/2 -1]; Line1 = CSubSpace::line( cutLeft[npl/2 -1] , v0 ); if ( v2.length() >= minSize ) { // upper left side is not a point for (i = npl/2 +1 ; i < npl ; i++) { v2 = left[i] - left[i-1]; cutLeft[i] = left[i] + rotateNormalized(M_PI/2, v2) * hilW; if ( i == npl/2 +1 ) { // compute mid side break point Line2 = CSubSpace::line( cutLeft[i] , v2 ); if ( Line1.intersect(Line2).getdim() == 0 ) cutLeft[npl/2] = Line1.intersect(Line2).getp(); // else std::cout << "CPanel::add6Hems = no mid left side intersection point" << std::endl; // check adjacent points relative to mid side point if (CVector3d::dotProduct(cutLeft[npl/2] - cutLeft[npl/2 -1], v0) <= 0) cutLeft[npl/2 -1] = cutLeft[npl/2 -2]; if (CVector3d::dotProduct(cutLeft[npl/2 +1] - cutLeft[npl/2], v0) <= 0) cutLeft[npl/2 +1] = cutLeft[npl/2 +2]; } else { // compute other uppr lft points cutLeft[i] = left[i] + rotateNormalized(M_PI/2, v2) * hilW; // check position relative to mid side point if (CVector3d::dotProduct(cutLeft[i] - cutLeft[npl/2], v0) <= 0) cutLeft[npl/2 +1] = cutLeft[npl/2]; } } } else { // upper left side is a point but not lower side v2 = left[npl/2] - left[npl/2 -1]; for (i = npl/2 +1 ; i < npl ; i++) cutLeft[i] = left[i] + rotateNormalized(M_PI/2, v2) * hilW; } } else if ( v2.length() >= minSize ) { // only lower left side is a point v1 = left[npl/2 +1] - left[npl/2]; for (i = 0 ; i < npl/2 ; i++) cutLeft[i] = left[i] + rotateNormalized(M_PI/2, v1) * lolW; for (i = npl/2 +1 ; i < npl -1 ; i++) { v2 = left[i] - left[i-1]; cutLeft[i] = left[i] + rotateNormalized(M_PI/2, v2) * hilW; } } else { // complete left side is a point if ( botW == 0 ) v = -v5; // extend the bottom edge else v = -( v5.normalized() + v7.normalized() ); // extend in bissectrice top-bottom for (i = 0 ; i< npl ; i++) cutLeft[i] = left[i] + v.normalized() * lolW; // if (v.length() == 0) std::cout << "CPanel::add6Hems 10 v=0 v5="<< v5.length()<< " v7="<< v7.length()<< std::endl; v1 = rotateNormalized(-M_PI/2, v); v2 = v1; } ///* Move the basic right edge points to the cut line */ if ( v3.length() >= minSize ) { // lower right side is not a point for (i = 0 ; i < npl/2 ; i++) { if ( i == 0 ) { if (!qFuzzyCompare(right[i+1], right[i])) v = right[i+1] - right[i]; else if (!qFuzzyCompare(right[i+2], right[i])) v = right[i+2] - right[i]; else if (!qFuzzyCompare(right[i+3], right[i])) v = right[i+3] - right[i]; else if (!qFuzzyCompare(right[i+4], right[i])) v = right[i+4] - right[i]; } else { if (!qFuzzyCompare(right[i], right[i-1])) v = right[i] - right[i-1]; else if (!qFuzzyCompare(right[i+1], right[i])) v = right[i+1] - right[i]; else if (!qFuzzyCompare(right[i+2], right[i])) v = right[i+2] - right[i]; } cutRight[i] = right[i] + rotateNormalized(-M_PI/2, v) * lorW; } v0 = right[npl/2] - right[npl/2 -1]; Line1 = CSubSpace::line( cutRight[npl/2 -1] , v0 ); if ( v4.length() >= minSize ) { // upper right side is not a point for (i = npl/2 +1 ; i < npl ; i++) { v4 = right[i] - right[i-1]; cutRight[i] = right[i] + rotateNormalized(-M_PI/2, v4) * hirW; if ( i == npl/2 +1 ) { // compute mid side break point Line2 = CSubSpace::line( cutRight[i] , v4 ); if (Line1.intersect(Line2).getdim() == 0) cutRight[npl/2] = Line1.intersect(Line2).getp(); // else std::cout << "CPanel::add6Hems = no mid right side intersection point" << std::endl; // check adjacent points relative to mid side point if (CVector3d::dotProduct(cutRight[npl/2] - cutRight[npl/2 -1], v0) <= 0) cutRight[npl/2 -1] = cutRight[npl/2 -2]; if (CVector3d::dotProduct(cutRight[npl/2 +1] - cutRight[npl/2], v0) <= 0) cutRight[npl/2 +1] = cutRight[npl/2 +2]; } else { // compute other points cutRight[i] = right[i] + rotateNormalized(-M_PI/2, v4) * hirW; } } } else { // upper right side is a point but not lower side v4 = right[npl-1] - right[npl-2]; for (i = npl/2 +1 ; i < npl ; i++) cutRight[i] = right[i] + rotateNormalized(-M_PI/2, v4) * hirW; } } else if ( v4.length() >= minSize ) { // only lower right side is a point v3 = v4; //v3 = right[npl-2] - right[npl/2]; /* if (v3.length() == 0) { std::cout << "AddHems v3=0 : about to crash 13" << std::endl; for (i = 0 ; i < npl ; i++) std::cout << "pt " << i << " xyz= " << right[i] << std::endl; } */ for (i = 0 ; i < npl/2 ; i++) cutRight[i] = right[i] + rotateNormalized(-M_PI/2, v4) * lorW; for (i = npl/2 +1 ; i < npl ; i++) cutRight[i] = right[i] + rotateNormalized(-M_PI/2, v4) * hirW; v4 = right[npl-1] - right[npl-2]; // if (v4.length() == 0) std::cout << "AddHems v4=0 about to crash 13" << std::endl; } else { // complete right side is a point if ( botW == 0 ) v = v6; else v = ( v6 + v8 ); if (v.length() == 0) std::cout << "CPanel::add6Hems v=v6=0 or v=v6+v8=0 about to crash 14" << std::endl; for (i = 0 ; i< npl ; i++) cutRight[i] = right[i] + v.normalized() * lorW; v3 = rotateNormalized(M_PI/2, v); v4 = v3; } ///* Rejoining the 4 corners of the cut panel */ // std::cout << "Rejoining 4 corners" << std::endl; /// lower left if (v5.length() == 0) std::cout << "CPanel::add6Hems v5=0 about to crash 15" << std::endl; Line1 = CSubSpace::line( cutBottom[0] , v5 ); if (v6.length() == 0) std::cout << "CPanel::add6Hems v6=0 about to crash 16" << std::endl; Line2 = CSubSpace::line( cutLeft[0] , v1 ); pt = Line1.intersectionPoint(Line2, "lower left corner"); /* Adjust the lower left point [0] to be at intersection */ cutBottom[0] = pt; cutLeft[0] = pt; /* Scan the first few points of the cut edges to make sure * that they are not on the wrong side of the point pt */ for (i = 0 ; i < npl/2 ; i++) { if (CVector3d::dotProduct(cutLeft[i] - pt, v1) <= 0) cutLeft[i] = pt; if (CVector3d::dotProduct(cutBottom[i] - pt, v5) <= 0) cutBottom[i] = pt; } /// lower right Line1 = CSubSpace::line( cutBottom[npb-1] , v6 ); Line2 = CSubSpace::line( cutRight[0] , v3 ); pt = Line1.intersectionPoint(Line2, "lower right corner"); /* Adjust the lower left point [0] to be at intersection */ cutBottom[npb-1] = pt; cutRight[0] = pt; /* Scan the first few points of the cut edges to make sure * that they are not on the wrong side of the point pt */ for (i = 1 ; i < npl/2 ; i++) { if (CVector3d::dotProduct(cutRight[i] - pt, v3) <= 0) cutRight[i] = pt; if (CVector3d::dotProduct(cutBottom[npb-1-i] - pt, v6) >= 0) cutBottom[npb-1-i] = pt; } /// upper left Line1 = CSubSpace::line( cutTop[0] , v7 ); Line2 = CSubSpace::line( cutLeft[npl-1] , v2 ); pt = Line1.intersectionPoint(Line2, "upper left corner"); /* Adjust the upper left point to be at intersection */ cutTop[0] = pt; cutLeft[npl-1] = pt; /* Scan the first few points of the cut edges to make sure * that they are not on the wrong side of the intersect point pt */ for (i = 0 ; i < npl/2 ; i++) { if (CVector3d::dotProduct(cutLeft[npl -1 -i] - pt, v2) >= 0) cutLeft[npl-1-i] = pt; if (CVector3d::dotProduct(cutTop[i] - pt, v7) <= 0) cutTop[i] = pt; } /// upper right Line1 = CSubSpace::line( cutTop[npb-1] , v8 ); Line2 = CSubSpace::line( cutRight[npl-1] , v4 ); pt = Line1.intersectionPoint(Line2, "upper right corner"); /* Adjust the upper right point to be at intersection */ cutTop[npb-1] = pt; cutRight[npl-1] = pt; /* Scan the first few points of the cut edges to make sure * that they are not on the wrong side of the intersect point pt */ // std::cout << "CPanel::add6Hems scan for overlap " << std::endl; for (i = 1 ; i < npl/2 ; i++) { if (CVector3d::dotProduct(cutRight[npl-1-i] - pt, v4) >= 0) cutRight[npl-1-i] = pt; if (CVector3d::dotProduct(cutTop[npb-1-i] - pt, v6) >= 0) cutTop[npb-1-i] = pt; } // std::cout << "End CPanel::add6Hems" << std::endl << std::endl; } /// end add6Hems //////////////////////////////////////// /** Rotates a panel around a point. * * p = centre of rotation * angle = angle in radians * axis = the axis around which to rotate */ CPanel CPanel::rotated(const CPoint3d &p, real angle, Qt::Axis axis) const { CVector3d v; v[axis] = 1; CMatrix4x4 matrix; matrix.translate(p); matrix.rotate(angle, v); matrix.translate(-p); return transformed(matrix); } /** Transform a panel. */ CPanel CPanel::transformed(const CMatrix4x4 &m) const { CPanel panel; panel.hasHems = hasHems; panel.label = label.transformed(m); panel.left = left.transformed(m); panel.right = right.transformed(m); panel.top = top.transformed(m); panel.bottom = bottom.transformed(m); panel.cutLeft = cutLeft.transformed(m); panel.cutRight = cutRight.transformed(m); panel.cutTop = cutTop.transformed(m); panel.cutBottom = cutBottom.transformed(m); return panel; } // operators /** Performs a 3D translation of the panel by a given vector. */ CPanel CPanel::operator+ (const CVector3d &transl) const { CMatrix4x4 matrix; matrix.translate(transl); return transformed(matrix); } /** Performs an assignment. */ CPanel& CPanel::operator= (const CPanel &p) { if (&p == this) return *this; label = p.label; left = p.left; right = p.right; top = p.top; bottom = p.bottom; cutLeft = p.cutLeft; cutRight = p.cutRight; cutTop = p.cutTop; cutBottom = p.cutBottom; hasHems = p.hasHems; return *this; } /***************************************************************************** CSide class *****************************************************************************/ /** Constructs a side with a given number of points. */ CSide::CSide( unsigned int nbpoints /* = 1 */) { resize(nbpoints); } /** Makes the side a straight line between two points. */ void CSide::fill( const CPoint3d &p1 , const CPoint3d &p2 ) { switch ( size() ) { case 0: return; case 1: at(0) = p1; return; } for (unsigned int i = 0 ; i < size() ; i++) at(i) = p1 + ( p2 - p1 ) * ( real(i) / (size() -1) ); } /** Makes the side a two-segment line between three points. */ void CSide::fill( const CPoint3d &p1 , const CPoint3d &p2 , const CPoint3d &p3 ) { switch ( size() ) { case 0: return; case 1: at(0) = p1; return; case 2: at(0) = p1; at(1) = p3; return; } unsigned int n1 = int( size() ) / 2; for (unsigned int i = 0 ; i < size() ; i++) { if ( i <= n1 ) at(i) = p1 + (p2 - p1) * (real(i) / n1); else at(i) = p2 + (p3 - p2) * (real(i - n1) / (size() -n1 -1) ); } } /** Returns the y-coordinate of the bottom-most point. */ real CSide::bottom() const { if (size()) { real y = at(0).y(); for (unsigned int i = 1; i < size(); i++) { y = std::min(y, at(i).y()); } return y; } else { return 0; } } /** Returns the x-coordinate of the left-most point. */ real CSide::left() const { if (size()) { real x = at(0).x(); for (unsigned int i = 1; i < size(); i++) { x = std::min(x, at(i).x()); } return x; } else { return 0; } } /** Transform a CSide. */ CSide CSide::transformed(const CMatrix4x4 &m) const { CSide s( size() ); for (unsigned int i = 0 ; i < size() ; i++) s[i] = m * at(i); return s; } /********************************************* Global functions *********************************************/ /** Outputs a CPanel to a stream. * exemple: std::cout << panel[i]; */ std::ostream& operator<<(std::ostream& o , const CPanel &p) { o << p.label; o << "== CSide : left ==" << std::endl << p.left; o << "== CSide : top ==" << std::endl << p.top; o << "== CSide : right ==" << std::endl << p.right; o << "== CSide : bottom ==" << std::endl << p.bottom; if ( p.hasHems ) { o << "== CSide : cutLeft ==" << std::endl << p.cutLeft; o << "== CSide : cutTop ==" << std::endl << p.cutTop; o << "== CSide : cutRight ==" << std::endl << p.cutRight; o << "== CSide : cutBottom ==" << std::endl << p.cutBottom; } return o; } /** Outputs a CPanelLabel to a stream. * exemple: std::cout << panel[i].label; */ std::ostream& operator<< (std::ostream &o , const CPanelLabel &lb) { o << "== CPanelLabel : name ==" << std::endl << lb.name << std::endl; o << "== CPanelLabel : height ==" << std::endl << lb.height << std::endl; o << "== CPanelLabel : color ==" << std::endl << lb.color << std::endl; o << "== CPanelLabel : origin ==" << std::endl << lb.origin << std::endl; o << "== CPanelLabel : direction ==" << std::endl << lb.direction << std::endl; return o; } /** Outputs a CSide to a stream. * exemple: std::cout << panel[i].left; */ std::ostream& operator<< (std::ostream &out, const CSide &s) { for (unsigned int i = 0 ; i < s.size() ; i++) { out << "#" << i << "\t" << s[i] << std::endl; } return out; } sailcut-1.5.0/src/sailcpp/panel.h000066400000000000000000000121101477005247400166600ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PANEL_H #define PANEL_H #include #include #include #include enum enumPointType { LUFF, FOOT, LEECH, GAFF }; enum enumDevelopAlign {ALIGN_TOP,ALIGN_BOTTOM }; class panel_error : public std::runtime_error { public: panel_error(const std::string &message) : std::runtime_error(message) { std::cout << "in panel: " << what() << std::endl; } }; /***************************************************************************** CPanelLabel class *****************************************************************************/ /** This class describe a label for a panel */ class CPanelLabel { public: CPanelLabel(); CPanelLabel( const CPanelLabel& ); /** label name of the panel */ std::string name; /** label text height (default : 5) */ int height; /** label text color (default : 1) */ int color; /** origin of the label */ CPoint3d origin; /** direction for writing the label */ CVector3d direction; CPanelLabel transformed(const CMatrix4x4 &m) const; /** operator to copy a label */ CPanelLabel& operator=( const CPanelLabel &); friend std::ostream& operator<< (std::ostream &, const CPanelLabel &); }; /***************************************************************************** CSide class *****************************************************************************/ /** The CSide class describes a side of a panel. It is a collection of points. * * @ingroup SailCpp */ class CSide : public std::vector { public: CSide( unsigned int = 1 ); public: void fill( const CPoint3d &, const CPoint3d & ); void fill( const CPoint3d &, const CPoint3d &, const CPoint3d & ); real bottom() const; real left() const; CSide transformed(const CMatrix4x4 &m) const; // operators friend std::ostream& operator<< (std::ostream &, const CSide &); }; /** This class describes a seam of a sail. * * @see CSide */ class CSeam : public CSide { public: /** Constructor */ CSeam( unsigned int i = 1 ) : CSide( i ) {} ; /** type of the left point */ enumPointType leftPoint; /** type of the right point */ enumPointType rightPoint; }; /***************************************************************************** Panel class *****************************************************************************/ /** The CPanel describes a sail panel. * * A panel has at least four sides: top, bottom, left and right. * A developed panel also has four additional sides representing * the edge of the cloth taking into account seam width and hems width. * * @ingroup SailCpp */ class CPanel { public: CPanel(); CPanel( const CPanel &p ); /** panel's label */ CPanelLabel label; /** panel's left side */ CSide left; /** panel's right side */ CSide right; /** panel's top side */ CSide top; /** panel's bottom side */ CSide bottom; /** panel's cut left side */ CSide cutLeft; /** panel's cut right side */ CSide cutRight; /** panel's cut top side */ CSide cutTop; /** panel's cut bottom side */ CSide cutBottom; /** do we have hems added to the panel edges? */ bool hasHems; // member functions CRect3d boundingRect() const; CPoint3d centroid() const; // centroid of a panel void addHems( const real &, const real &, const real &, const real &); void add6Hems( const real &, const real &, const real &, const real &, const real &, const real & ); CPanel develop(enumDevelopAlign align) const; void placeLabel(); // place a label at the center of a panel void reframe(); CPanel rotated(const CPoint3d &, real angle, Qt::Axis axis) const; CPanel transformed(const CMatrix4x4 &m) const; CPanel operator+ (const CVector3d &) const; CPanel& operator= (const CPanel &); friend std::ostream& operator<< (std::ostream &, const CPanel &); }; // global functions std::ostream& operator<< (std::ostream &, const CPanel &); std::ostream& operator<< (std::ostream &, const CSide &); std::ostream& operator<< (std::ostream &, const CPanelLabel &); CVector3d rotateNormalized(real angle, const CVector3d &v); #endif sailcut-1.5.0/src/sailcpp/panelgroup.cpp000066400000000000000000000072721477005247400203050ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "panelgroup.h" /** Constructs a panel group with the specified number of panels. */ CPanelGroup::CPanelGroup( unsigned int nbpanels /* = 0 */) { resize(nbpanels); type = SAIL; } /** Copy constructor. */ CPanelGroup::CPanelGroup( const CPanelGroup& s ) : std::vector(s) { title = s.title; child = s.child; type = s.type; } /** Construct a panel group from a single panel. */ CPanelGroup::CPanelGroup( const CPanel& p ) { resize(1); at(0) = p; } /** Returns the smallest 3D box that contains all the panels. */ CRect3d CPanelGroup::boundingRect() const { CRect3d rect; bool rect_filled = 0; unsigned int i; if ( size() > 0 ) { rect = at(0).boundingRect(); for (i = 1; i < size(); i++) rect = rect.join( at(i).boundingRect() ); rect_filled = 1; } if ( child.size() > 0 ) { if (rect_filled) rect = rect.join( child[0].boundingRect() ); else rect = child[0].boundingRect(); for (i = 1; i < child.size(); i++) rect = rect.join( child[i].boundingRect() ); } return rect; } /** Positions each of the display Sail's panels' label. The font size is defined in void CSailDispLabel::drawLabels() */ void CPanelGroup::placeLabels() { for (unsigned int i = 0; i < size(); i++) { at(i).label.name = std::to_string(i); at(i).placeLabel(); } } /** Positions each of the plotted Sail's panels' label. The font size is default 5 mm */ void CPanelGroup::plotLabels() { for (unsigned int i = 0; i < size(); i++) { at(i).label.name = std::to_string(i); at(i).label.height = 5; // position the label and orientate it at(i).label.origin = at(i).bottom[2]; at(i).label.direction = CVector3d( at(i).bottom[3]- at(i).bottom[2]); } } /** Transform a sail. */ CPanelGroup CPanelGroup::transformed(const CMatrix4x4 &m) const { unsigned int i; CPanelGroup ret = *this; for (i = 0; i < size(); i++) ret[i] = at(i).transformed(m); for (i = 0; i < child.size(); i++) ret.child[i] = child[i].transformed(m); return ret; } /** Performs an assignment. */ CPanelGroup& CPanelGroup::operator=(const CPanelGroup& s) { if (&s == this) return *this; this->std::vector::operator=(s); title = s.title; child = s.child; type = s.type; return *this; } /** Outputs a CPanelGroup to a stream. */ std::ostream& operator<<(std::ostream &o, const CPanelGroup &s) { unsigned int i; for (i = 0; i < s.size(); i++) { o << "===== CPanel : " << i << " ====" << std::endl; o << s[i] << std::endl; } for (i = 0; i < s.child.size(); i++) { o << "===== child CPanelGroup : " << i << " ====" << std::endl; o << s.child[i] << std::endl; } return o; } sailcut-1.5.0/src/sailcpp/panelgroup.h000066400000000000000000000037351477005247400177520ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PANELGROUP_H #define PANELGROUP_H #include "panel.h" enum enumPanelGroupType { SAIL, RIG, HULL }; /** This class holds a collection of panels, for instance to represent * a 3D or a developed sail. * * @ingroup SailCpp */ class CPanelGroup : public std::vector { public: CPanelGroup( unsigned int = 0 ); CPanelGroup( const CPanelGroup& ); CPanelGroup( const CPanel& ); /** title of this panel group */ std::string title; /** children of this group */ std::vector child; /** type of boat object */ enumPanelGroupType type; // member functions public: /** rectangle containing all panels */ CRect3d boundingRect() const; /** function to place the labels on a displayed panel group */ void placeLabels(); /** function to place the labels on a plotted panel group */ void plotLabels(); CPanelGroup transformed(const CMatrix4x4 &m) const; // operators CPanelGroup& operator=( const CPanelGroup &); friend std::ostream& operator<< (std::ostream &, const CPanelGroup &); }; // global functions std::ostream& operator<< (std::ostream &, const CPanelGroup &); #endif sailcut-1.5.0/src/sailcpp/rigdef.cpp000066400000000000000000000033541477005247400173660ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "rigdef.h" /** Constructs a CRigDef object from the default rig parameters. * */ CRigDef::CRigDef() { // default values for member variables are set here rigID = "Test rig 1"; foreI = 6500; // height of fore triangle foreJ = 2000; // base of fore triangle MHeight = 8000; // mast height MCord = 140; MWidth = 70; MRakeM = 220; MRakeD = radiansToDegrees(atan2(MRakeM, MHeight)); MBase = foreJ - MRakeM * (foreI/MHeight); MRnd = 110; MRndPos = 50; CSH = 7000; // cap shroud height CSB = 500; LSB = 400; SPNB = 3; // number of spreaders SPH[0] = 0; SPW[0] = CSB; SPH[1] = 1800; SPW[1] = CSB; SPH[2] = 3600; SPW[2] = CSB -50; SPH[3] = 5400; SPW[3] = CSB -200; BAD = 750; // height of boom //MStack = CVector3d(2100, 750 , 0); HAD = 7000; //MShead = CVector3d(2200, 7000, 0); } sailcut-1.5.0/src/sailcpp/rigdef.h000066400000000000000000000041041477005247400170250ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef RIGDEF_H #define RIGDEF_H #include #include /** This class holds the parameters that define a rig * and the default parameters. * * @ingroup SailCpp * @see CRigWorker */ class CRigDef { public: CRigDef(); /** rig ID name */ std::string rigID; /** fore triangle hoist*/ real foreI; /** fore triangle base*/ real foreJ; ////// mast ///// /** mast height */ real MHeight; /** mast cord */ real MCord; /** mast width */ real MWidth; /** mast rake */ real MRakeM; /** mast rake angle in degree */ real MRakeD; /** mast base distance to stem */ real MBase; /** mast round */ real MRnd; /** mast round position */ int MRndPos; /** Boom height above deck */ real BAD; /** mainsail tack */ CVector3d MStack; /** mainsail head height above deck */ real HAD; /** mainsail head point */ CVector3d MShead; ////// spreaders and shrouds ///// /** cap shroud height */ real CSH; /** cap shroud base */ real CSB; /** lower shroud base */ real LSB; /** number of spreaders */ unsigned int SPNB; /** spreader height */ real SPH[4]; /** spreader width */ real SPW[4]; }; #endif sailcut-1.5.0/src/sailcpp/rigworker.cpp000066400000000000000000000214111477005247400201330ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "rigworker.h" #include "sailcalc.h" /** The constructor does some preliminary calculations to set * internal variables. */ CRigWorker::CRigWorker(const CRigDef &d) : CRigDef(d) { } /** Creates the rig. * * @return CPanelGroup */ CPanelGroup CRigWorker::makeRig() const { CPoint3d p0, p1, p2; CVector3d v1(1, 0, 0), vm(0, 1, 0); CPanel mast1, mast2; // half mast section unsigned int i = 0, j = 0; //unsigned int npl = mast1.left.size(); // number of right/left points unsigned int npb = mast1.bottom.size(); // number of bottom/top points real h = 0, cord; CPanelGroup rig; rig.type = RIG; // used for color scheme in saildispgl rig.title = rigID; // add mast // cord = MCord / 2; vm = CVector3d(MRakeM, MHeight, 0); //straight mast cord vector // base section of mast h = 0; p0 = mastCenter ( h ); for (j = 0 ; j < npb ; j++) { v1 = CVector3d(cos(M_PI * real(j) /(npb-1)), 0, sin(M_PI * real(j) /(npb-1) ) ); v1.setZ(v1.z() * MWidth / MCord); mast1.top[j] = p0 + cord * v1; mast2.top[j] = p0 - cord *v1; } // all other sections of mast for (i = 1; i <= 20; i++) { // top of current section h = real(i) * MHeight / 20; p2 = mastCenter ( h ); for (j = 0 ; j < npb ; j++) { v1 = CVector3d(cos(M_PI * real(j) /(npb-1)), 0, sin(M_PI * real(j) /(npb-1) ) ); v1.setZ(v1.z() * MWidth / MCord); mast1.bottom[j] = mast1.top[j]; mast2.bottom[j] = mast2.top[j]; mast1.top[j] = p2 + cord *v1; mast2.top[j] = p2 - cord * v1; } mast1.left.fill(mast1.bottom[0],mast1.top[0]); mast1.right.fill(mast1.bottom[npb-1],mast1.top[npb-1]); mast2.left.fill(mast2.bottom[0],mast2.top[0]); mast2.right.fill(mast2.bottom[npb-1],mast2.top[npb-1]); // add mast panel to rig rig.push_back(mast1); rig.push_back(mast2); } // add spreaders // cord = MCord / 6; for (i = 1; i <= SPNB; i++) { p2 = mastCenter ( SPH[i] ); //printf ("P2 x= %f, y= %f \n", p2.x(), p2.y()); for (j = 0 ; j < npb ; j++) { v1 = CVector3d(cos(M_PI * real(j) /(npb-1)), sin(M_PI * real(j) /(npb-1) ), 0 ); v1.setY(v1.y() / 2); mast1.bottom[j] = p2 + cord * v1; mast1.bottom[j] = mast1.bottom[j] + CVector3d(0 , 0 , -SPW[i]); mast1.top[j] = mast1.bottom[j] + CVector3d(0 , 0 , 2*SPW[i]); } mast1.left.fill(mast1.bottom[0],mast1.top[0]); mast1.right.fill(mast1.bottom[npb-1],mast1.top[npb-1]); rig.push_back(mast1); // make symetrical by rotation mast1 = mast1.rotated(p2, M_PI, Qt::ZAxis); rig.push_back(mast1); } // add shrouds // cord = MCord /12; // half width of shroud p1 = p0; // mast base centre if (SPNB >= 1) // add inner shroud if at least one spreader { for (i = 1; i <= SPNB; i++) { p2 = mastCenter( SPH[i] ); // make +Z shroud mast1.bottom[0] = p1 + cord * CVector3d (1,0,0) + CVector3d(0,0,SPW[i-1]); mast1.top[0] = p1 - cord * CVector3d(1,0,0) + CVector3d(0,0,SPW[i-1]); mast1.bottom[npb-1] = p2 + cord * CVector3d (1,0,0) + CVector3d(0,0,MWidth/2); mast1.top[npb-1] = p2 - cord * CVector3d(1,0,0) + CVector3d(0,0,MWidth/2); mast1.bottom.fill(mast1.bottom[0],mast1.bottom[npb-1]); mast1.top.fill(mast1.top[0],mast1.top[npb-1]); mast1.left.fill(mast1.bottom[0],mast1.top[0]); mast1.right.fill(mast1.bottom[npb-1],mast1.top[npb-1]); // make -Z symetrical mast2.bottom[0] = p1 + cord * CVector3d (1,0,0) - CVector3d(0,0,SPW[i-1]); mast2.top[0] = p1 - cord * CVector3d(1,0,0) - CVector3d(0,0,SPW[i-1]); mast2.bottom[npb-1] = p2 + cord * CVector3d (1,0,0) - CVector3d(0,0,MWidth/2); mast2.top[npb-1] = p2 - cord * CVector3d(1,0,0) - CVector3d(0,0,MWidth/2); mast2.bottom.fill(mast2.bottom[0],mast2.bottom[npb-1]); mast2.top.fill(mast2.top[0],mast2.top[npb-1]); mast2.left.fill(mast2.bottom[0],mast2.top[0]); mast2.right.fill(mast2.bottom[npb-1],mast2.top[npb-1]); // add inner shrouds to rig rig.push_back(mast1); rig.push_back(mast2); // add outer shroud to tip of spreaders // make +Z shroud mast1.bottom[0] = p1 + cord * CVector3d (1,0,0) + CVector3d(0,0,SPW[i-1]); mast1.top[0] = p1 - cord * CVector3d(1,0,0) + CVector3d(0,0,SPW[i-1]); mast1.bottom[npb-1] = p2 + cord * CVector3d (1,0,0) + CVector3d(0,0,SPW[i]); mast1.top[npb-1] = p2 - cord * CVector3d(1,0,0) + CVector3d(0,0,SPW[i]); mast1.bottom.fill(mast1.bottom[0],mast1.bottom[npb-1]); mast1.top.fill(mast1.top[0],mast1.top[npb-1]); mast1.left.fill(mast1.bottom[0],mast1.top[0]); mast1.right.fill(mast1.bottom[npb-1],mast1.top[npb-1]); // make -Z symetrical mast2.bottom[0] = p1 + cord * CVector3d (1,0,0) - CVector3d(0,0,SPW[i-1]); mast2.top[0] = p1 - cord * CVector3d(1,0,0) - CVector3d(0,0,SPW[i-1]); mast2.bottom[npb-1] = p2 + cord * CVector3d (1,0,0) - CVector3d(0,0,SPW[i]); mast2.top[npb-1] = p2 - cord * CVector3d(1,0,0) - CVector3d(0,0,SPW[i]); mast2.bottom.fill(mast2.bottom[0],mast2.bottom[npb-1]); mast2.top.fill(mast2.top[0],mast2.top[npb-1]); mast2.left.fill(mast2.bottom[0],mast2.top[0]); mast2.right.fill(mast2.bottom[npb-1],mast2.top[npb-1]); // add outer shroud to rig rig.push_back(mast1); rig.push_back(mast2); p1 = p2; } } // add cap shroud bit which is also the only shroud if n==0 p2 = mastCenter( CSH ); // make +Z mast1.bottom[0] = p1 + cord * CVector3d (1,0,0) + CVector3d(0,0,SPW[i-1]); mast1.top[0] = p1 - cord * CVector3d(1,0,0) + CVector3d(0,0,SPW[i-1]); mast1.bottom[npb-1] = p2 + cord * CVector3d (1,0,0) + CVector3d(0,0,MWidth/2); mast1.top[npb-1] = p2 - cord * CVector3d(1,0,0) + CVector3d(0,0,MWidth/2); mast1.bottom.fill(mast1.bottom[0],mast1.bottom[npb-1]); mast1.top.fill(mast1.top[0],mast1.top[npb-1]); mast1.left.fill(mast1.bottom[0],mast1.top[0]); mast1.right.fill(mast1.bottom[npb-1],mast1.top[npb-1]); // make -Z symetrical mast2.bottom[0] = p1 + cord * CVector3d (1,0,0) - CVector3d(0,0,SPW[i-1]); mast2.top[0] = p1 - cord * CVector3d(1,0,0) - CVector3d(0,0,SPW[i-1]); mast2.bottom[npb-1] = p2 + cord * CVector3d (1,0,0) - CVector3d(0,0,MWidth/2); mast2.top[npb-1] = p2 - cord * CVector3d(1,0,0) - CVector3d(0,0,MWidth/2); mast2.bottom.fill(mast2.bottom[0],mast2.bottom[npb-1]); mast2.top.fill(mast2.top[0],mast2.top[npb-1]); mast2.left.fill(mast2.bottom[0],mast2.top[0]); mast2.right.fill(mast2.bottom[npb-1],mast2.top[npb-1]); // add cap shroud to rig rig.push_back(mast1); rig.push_back(mast2); // return rig; } /** Routine for computing the 3D point at center of mast * at a given height */ CPoint3d CRigWorker::mastCenter( const real &HM ) const { CPoint3d p0, p1; CVector3d vm; real cord = MCord / 2; //straight mast cord vector vm = CVector3d(MRakeM, MHeight, 0); // upright mast base centre point p0 = CPoint3d (foreJ + cord , 0 , 0); // base centre point offset by rake p0 = p0 + CVector3d(-(MRakeM * foreI / MHeight), 0, 0); real h = HM / MHeight; if ( h < 0 ) h = 0; if ( h > 1 ) h = 1; // round real round = MRnd * RoundP( h, MRndPos ); // printf ("i= %d, MRnd = %f \n", i, round); // straight mast section center point p1 = p0 + HM * vm.normalized(); // displace center point of section by round p1 = p1 + rotateNormalized(M_PI/2, vm) * round; // return p1; } sailcut-1.5.0/src/sailcpp/rigworker.h000066400000000000000000000024331477005247400176030ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef RIGWORKER_H #define RIGWORKER_H #include "panelgroup.h" #include "rigdef.h" /** The CRigWorker class does all the rig-related calculations. * It is used to create the rig from its definition. * * @ingroup SailCpp * @see CRigDef, CPanelGroup */ class CRigWorker : public CRigDef { public: CRigWorker(const CRigDef &d); CPanelGroup makeRig() const; // point of mast center at given height CPoint3d mastCenter( const real &h ) const; }; #endif sailcut-1.5.0/src/sailcpp/sailcalc.cpp000066400000000000000000000115021477005247400176730ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "sailcalc.h" /** Compute the normalised roach or round of a sail side * Return the value of the normalised round at position X * X is the relative position of the point along the straight edge * P is the position of the maximum round in percent of the edge length * The curve is a parabola on either side of the point P */ real RoundP( const real &x, const int &p ) { /* X (0..1) is the relative position of the point along the edge P is the integer position of the maximum round in percent of the edge length The curve is a parabola on either side of the point P Return Y (0..1) is the value of the normalised round at position X */ real p1 = .5, x1 = 0 , y = 0; p1 = real(p) / 100; // limit the position of maximum round of side if (p1 < 0.01) p1=0.01; if (p1 > 0.99) p1=0.99; // limit the computation of the domain 0..1 if ( x <= 0 ) y = 0; else if ( x >= 1 ) y = 0; else if ( x > p1 ) { x1 = (x - p1) / (1 - p1); y = 1 - x1 * x1; } else { x1 = 1 - x / p1; y = 1 - (x1 * x1); } // return y; } /** Compute the angle of a 2D triangle from its 3 sides length * a, b and c are the length of the sides of the triangle * Return the angle in radian opposite to side a of the triangle */ real Atriangle( const real &a, real const &b, const real &c ) { real per = 0, AA = 0; per = (a + b + c) / 2; if ( per <= EPS ) AA = M_PI /3; else if ( fabs(per-a) <= EPS ) AA = M_PI; else AA = 2 * atan (sqrt ((per-b) * (per-c) / (per * (per-a)) ) ) ; // return AA; } /** Compute the angle of a 3D triangle. * The triangle is defined by 3d points pta, ptb, ptc * Return the angle AA in radian at point pta of the triangle */ real Atriangle3d ( const CPoint3d &pta, const CPoint3d &ptb, const CPoint3d &ptc ) { real AA=0, a=0, b=0, c=0, per=0; a = sqrt( (ptc.x()-ptb.x()) * (ptc.x()-ptb.x()) +(ptc.y()-ptb.y()) * (ptc.y()-ptb.y()) +(ptc.z()-ptb.z()) * (ptc.z()-ptb.z()) ); b = sqrt( (pta.x()-ptc.x()) * (pta.x()-ptc.x()) +(pta.y()-ptc.y()) * (pta.y()-ptc.y()) +(pta.z()-ptc.z()) * (pta.z()-ptc.z()) ); c = sqrt( (ptb.x()-pta.x()) * (ptb.x()-pta.x()) +(ptb.y()-pta.y()) * (ptb.y()-pta.y()) +(ptb.z()-pta.z()) * (ptb.z()-pta.z()) ); per =(a + b + c)/2; if ( per <= EPS ) AA = M_PI /3; else if ( fabs(per-a) <= EPS ) AA = M_PI; else AA = 2 * atan (sqrt ((per-b) * (per-c) / (per * (per-a)) ) ) ; // return AA; } /** Compute the distance from a point pta * to the line defined by the 2 points ptb and ptc * The two points ptb and ptc defining the baseline also define * its positive direction from point ptb toward point ptc. * It is assumed that the 3 points pta, ptb, ptc define a plane * not far from the X-Y plane. * The sign of d is positive if the point pta * is left of the line ptb=>ptc * The sign of d is negative if pta is right of the line. */ real Distance3d(const CPoint3d &pta, const CPoint3d &ptb, const CPoint3d &ptc) { real d; CVector3d Va = CVector3d( pta - ptb ); CVector3d Vb = CVector3d( ptc - ptb).normalized(); CVector3d Vd = CVector3d::crossProduct(Vb, Va); d = Vd.length(); if ( Vd.z() < 0 ) d = -d; // return d; } /** Calculates logical viewport rectangle to match * the ratio of the device viewport. */ CRect3d calcLRect(const CRect3d& viewRect, const CRect3d& objRect, const CPoint3d center, real zoom ) { CRect3d lRect; // avoid division by zero errors if ((viewRect.height() == 0) || (viewRect.width() == 0)) { lRect.min = center; lRect.max = center; return lRect; } // set correct aspect ratio lRect = objRect.expandToRatio(viewRect.width() / viewRect.height()); // recenter view return (lRect + (center - lRect.center())) * (1/zoom); } sailcut-1.5.0/src/sailcpp/sailcalc.h000066400000000000000000000033451477005247400173460ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILCALC_H #define SAILCALC_H #include /** @defgroup SailCpp Sail computations library * * SailCpp is the library that performs all the plotting calculations. * It provides classes for generating sails, hulls, rigs and boats from * their definitions. */ /* computation of parabolic edge round */ real RoundP( const real &x, const int &p ); /* computation of angle of triangle defined by 3 sides */ real Atriangle( const real &a, const real &b, const real &c ); /* computation of angle of triangle defined by 3 points */ real Atriangle3d ( const CPoint3d &pta, const CPoint3d &ptb, const CPoint3d &ptc ); /* computation of distance of a point to a line defined by 2 points */ real Distance3d(const CPoint3d &pta, const CPoint3d &ptb, const CPoint3d &ptc); /* logical viewport calculation */ CRect3d calcLRect(const CRect3d &viewRect, const CRect3d &objRect, const CPoint3d center, real zoom ); #endif sailcut-1.5.0/src/sailcpp/saildef.cpp000066400000000000000000000051601477005247400175320ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "saildef.h" /************************************************************************** construction / destruction **************************************************************************/ /** Constructs a CSailDef object from the default sail parameters. * */ CSailDef::CSailDef() { // default values for member variables are set here sailType = MAINSAIL; sailCut = CROSS; sailID = "Test sail 1"; LOA = 7000; // length of hull in millimetre foreJ = 2000; // base of fore triangle foreI = 6500; // height of fore triangle tackX = 1972; // longitudinal distance of main sail tack from stem in millimetre tackY = 750; // height of sail tack above stem in millimetre luffL = 6250; // in millimetre rake = 161; // in millimetre gaffDeg= 45; // in degree gaffL = 2500; // in millimetre leechL = 8220; // in millimetre footL = 4100; // in millimetre luffR = 67; // in millimetre // NOTE: Positive value for mast bend Negative for headstay sag luffRP = 50; // in percent of luff length gaffR = 150; // in millimetre gaffRP = 50; // in percent leechR = -120; // in millimetre // NOTE: Negative value for hollow leech leechRP= 55; // in percent footR = 150; // in millimetre // NOTE: Positive value for foot roach footRP = 50; // in percent clothW = 900; // in millimetre seamW = 13; // in millimetre leechHemW = 40; // in millimetre footHemW = 30; hemsW = 10; // in millimetre twistDeg = 18; // in degree sheetDeg = 0; dihedralDeg = 168; // in degree nbSections = 5; // radial sections nbGores = 5; // radial gores nbLuffGores = 2; // luff gores } sailcut-1.5.0/src/sailcpp/saildef.h000066400000000000000000000060731477005247400172030ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILDEF_H #define SAILDEF_H #include #include "sailmould.h" // enumerated types enum enumSailType { MAINSAIL, JIB, WING }; enum enumSailCut { CROSS, TWIST, HORIZONTAL, VERTICAL, RADIAL, MITRE , MITRE2}; /** The CSailDef class holds the parameters that define a sail * and its default values. * * @ingroup SailCpp * @see CFormSailDef for data input and checking * @see CSailWorker */ class CSailDef { public: CSailDef(); // member variables /** The Sail ID name */ std::string sailID; /** The type of cut layout */ enumSailCut sailCut; /** The type of sail */ enumSailType sailType; /** The boat deck Length in mm */ real LOA; /** The Fore triangle hoist in mm */ real foreI; /** The Fore triangle base in mm */ real foreJ; /** The distance from tack to stem */ real tackX; /** The Tack height above deck in mm */ real tackY; /** The straight line luff length in mm */ real luffL; /** The rake of Luff in mm */ real rake; /** The gaff angle from Luff line in degree */ real gaffDeg; /** The straight line Gaff length in mm */ real gaffL; /** The straight line Foot length in mm */ real footL; /** The straight line Leech length in mm */ real leechL; /** The value of round of sides */ real luffR, gaffR, leechR, footR; /** The position of round of sides in percent of its length*/ int luffRP, gaffRP, leechRP, footRP; /** The cloth width */ real clothW; /** The seam width between panels in mm */ real seamW; /** The leech seam width in mm */ real leechHemW; /** The foot seam width in mm */ real footHemW; /** The other seams width in mm */ real hemsW; /** The Inner guideline width in mm */ real innerW; /** The Sail twist between foot and head in degrees */ real twistDeg; /** The sail sheeting angle in degrees */ real sheetDeg; /** The Wing diedral angle in degrees */ real dihedralDeg; /** The number of radial sections */ unsigned int nbSections; /** The number of radial head gores */ unsigned int nbGores; /** The number of luff gores */ unsigned int nbLuffGores; /** The sail mould */ CSailMould mould; }; #endif sailcut-1.5.0/src/sailcpp/sailmould.cpp000066400000000000000000000230551477005247400201170ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "sailmould.h" /************************************************************************** CProfile class *************************************************************************** construction / destruction **************************************************************************/ /** The constructor. * * @param rDepth * @param rLeech * @param rLuff */ CProfile::CProfile( real rDepth, real rLeech, real rLuff) : depth(rDepth), kleech(rLeech), kluff(rLuff) { calcMax(); } /************************************************************************** member functions **************************************************************************/ /** Compute the depth of the profile at a point located at dX along the cord */ real CProfile::z( real dX ) const { /* dX = absiss 0 to 1 along the cord of the profile kluff = luff shape factor kleech = leech shape factor depth = depth of the profile profile function is obtained by integrating twice the equation d2z/dx2 = kd * (-a*(1-X)^kluff - kleech * X) giving first the slope of the profile dz/dx = kd * (a*(1-X)^(kluff+1)/(kluff+1) - kleech/2 * X^2 + c) and finally the depth of the profile z = kd * (-a*(1-X)^(kluff+2)/((kluff+1)*(kluff+2)) - kleech/6 * X^3 +c * X + b) b and c are such that z=0 for X=0 AND X=1 kd is such that the value of z at dX=xmax (max depth) is equal to depth */ real a=1, b=0, c=0, kd=1, z=.1 ; a = 1 + kluff/4 ;// specific to family of profile b = a / ((kluff+2)*(kluff+1)); c = kleech/6 - b; if (dX <= 0) /* point is outside profile range */ z = 0; else if (dX >= 1) /* point is outside profile range */ z = 0; else { /* point is inside profile range */ /* compute depth normalisation coefficient */ kd = depth / zmax; /* compute real depth z at point dX */ z = kd * (-a*pow(1-dX,kluff+2)/((kluff+1)*(kluff+2)) - kleech/6 * pow(dX,3) + c * dX + b ); } return z; } /** Compute the slope of the profile at a point located at dX along the cord */ real CProfile::slope( real dX ) const { /* dX = absiss 0 to 1 along the cord of the profile kluff = luff shape factor kleech = leech shape factor depth = depth of the profile profile function is obtained by integrating twice the equation d2z/dx2 = kd * (-a*(1-X)^kluff - kleech * X) giving first the slope of the profile dz/dx = kd * (a*(1-X)^(kluff+1)/(kluff+1) - kleech/2 * X^2 + c) and finally the depth of the profile z = kd * (-a*(1-X)^(kluff+2)/((kluff+1)*(kluff+2)) - kleech/6 * X^3 +c * X + b) b and c are such that z=0 for X=0 AND X=1 kd is such that the value of z at dX=xmax (max depth) is equal to depth */ real a=1, b=0, c=0, kd=1, dz=.1 , x=0; a = 1 + kluff/4 ;// specific to family of profile b = a / ((kluff+2)*(kluff+1)); c = kleech/6 - b; x = dX; if (x <= 0) /* point is outside profile range */ x = 0; else if (x >= 1) /* point is outside profile range */ x = 1; /* compute depth normalisation coefficient */ kd = depth / zmax; /* compute real slope dz at point dX */ dz = kd * ( a * pow(1-x,kluff+1) / (kluff+1) - kleech/2 * pow(x,2) + c ); return dz; } /** Compute the camber of the profile at a point located at dX along the cord */ real CProfile::camber( real dX ) const { /* dX = absiss 0 to 1 along the cord of the profile kluff = luff shape factor kleech = leech shape factor depth = depth of the profile profile function is obtained by integrating twice the equation d2z/dx2 = kd * (-a*(1-X)^kluff - kleech * X) giving first the slope of the profile dz/dx = kd * (a*(1-X)^(kluff+1)/(kluff+1) - kleech/2 * X^2 + c) and finally the depth of the profile z = kd * (-a*(1-X)^(kluff+2)/((kluff+1)*(kluff+2)) - kleech/6 * X^3 +c * X + b) b and c are such that z=0 for X=0 AND X=1 kd is such that the value of z at dX=xmax (max depth) is equal to depth */ real a=1, b=0, c=0, kd=1, dz=.1 , d2z=.1, camb=.1, x=0; a = 1 + kluff/4 ;// specific to family of profile b = a / ((kluff+2)*(kluff+1)); c = kleech/6 - b; x = dX; if (x <= 0) /* point is outside profile range */ x = 0; else if (x >= 1) /* point is outside profile range */ x = 1; /* compute depth normalisation coefficient */ kd = depth / zmax; /* compute real slope dz at point dX */ dz = kd * ( a * pow(1-x,kluff+1) / (kluff+1) - kleech/2 * pow(x,2) + c ); /* compute real d2z at point dX */ d2z = kd * ( -a * pow(1-x,kluff) - kleech * x ); /* compute real camber at point dX */ camb = d2z / pow((1 + pow(dz,2)),1.5); return camb; } /** Compute the absiss x of the point of maximum depth of a profile */ void CProfile::calcMax() { /* kluff = luff shape factor kleech = leech shape factor Profile function is defined by integrating twice the equation d2z/dx2 = kd * (-a*(1-x)^kluff - kleech * x) dz/dx = kd * (a*(1-x)^(kluff+1)/(kluff+1) - kleech/2 * x^2 + c) z = kd * (-a*(1-x)^(kluff+2)/((kluff+1)*(kluff+2)) - kleech/6 * x^3 +c * x + b) b and c are such that z=0 for x=0 AND x=1 */ real a=1, b=0, c=0; a = 1 + kluff/4; b = a / ((kluff+2)*(kluff+1)); c = kleech/6 - b; /* scan from 16% point until slope become <= 0 */ real x=.16, dz=.1; int n=16, step=8; while ((dz>0) && (n<60)) { x = real(n)/100; dz = a*pow( 1-x, kluff+1)/(kluff+1) - kleech/2 * (x * x) + c; while ((dz<=0) && (step>1)) { /* too big a step, go back halfway*/ /* switch to fine stepping */ step = step/2; if (step<2) { step = 2; } n = n - step; x = real(n)/100; dz = a*pow( 1-x, kluff+1)/(kluff+1) - kleech/2 * (x * x) + c; if (dz>0) { step = 1; } } n = n + step; } // we store xmax and zmax xmax = x; zmax = -a*pow(1-xmax,kluff+2)/ ((kluff+1)*(kluff+2)) - kleech/6 * pow(xmax,3) + c * xmax +b; } /************************************************************************** CSailMould class *************************************************************************** construction / destruction **************************************************************************/ /** Set the default vertical position of max depth * and the 3 profiles factors [depth, kleech, kluff] */ CSailMould::CSailMould() { vertpos = 40; profile.resize(3); profile[0] = CProfile( 0.02, 0.00, 0 ); profile[1] = CProfile( 0.08, 0.04, 3 ); profile[2] = CProfile( 0.06, 0.03, 5 ); } /************************************************************************** member functions **************************************************************************/ /** Interpolate the depth and coefficients of the profile at height h */ CProfile CSailMould::interpol ( const real h ) const { if ( profile.size() < 3) std::cout << "profile < 3 !!" << std::endl; CProfile p; real pv = real(vertpos) / 100; real dpth = 0; real hr; if ( h <= 0 ) // at or below lower profile { /*p = profile[0];*/ hr = h / pv; dpth = profile[0].getDepth() + (profile[1].getDepth()-profile[0].getDepth()) * hr; if ( dpth < 0 ) dpth = 0; p = CProfile( dpth, profile[0].getLeech() , profile[0].getLuff() ); } else if ( h < pv ) // below max depth { hr = h / pv; dpth = profile[0].getDepth() + (profile[1].getDepth()-profile[0].getDepth()) * (1-(1-hr)*(1-hr)); if ( dpth < 0 ) dpth = 0; p = CProfile( dpth , profile[0].getLeech() + (profile[1].getLeech()-profile[0].getLeech()) * hr, profile[0].getLuff() + (profile[1].getLuff()-profile[0].getLuff()) * hr ); } else if ( h < 1 ) // above max depth and below peak { hr = (h-pv) / (1-pv); dpth = profile[1].getDepth() + (profile[2].getDepth()-profile[1].getDepth()) * hr*hr; if ( dpth < 0 ) dpth = 0; p = CProfile( dpth , profile[1].getLeech() + (profile[2].getLeech()-profile[1].getLeech()) * hr, profile[1].getLuff() + (profile[2].getLuff()-profile[1].getLuff()) * hr ); } else // peak and above { p = profile[2]; } return p; } sailcut-1.5.0/src/sailcpp/sailmould.h000066400000000000000000000051311477005247400175570ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILMOULD_H #define SAILMOULD_H #include #include /** Class used to work on sail profiles. * * @ingroup SailCpp * @see CSailMould */ class CProfile { public: CProfile( real rDepth=0.05, real rLeech=0.02, real rLuff=1 ); real z( real dX ) const; real slope( real dX ) const; real camber( real dX ) const; /** Accessor for the depth */ real getDepth() const { return depth; } /** Accessor for the leech */ real getLeech() const { return kleech; } /** Accessor for the luff */ real getLuff() const { return kluff; } /** Accessor for xmax */ real getMaxPos() const { return xmax; } /** Accessor for zmax */ real getMaxDepth() const { return zmax; } /** Set the depth */ void setDepth( real ndepth ) { depth = ndepth; calcMax(); } /** Set the leech */ void setLeech( real nkleech ) { kleech = nkleech; calcMax(); } /** Set the luff */ void setLuff( real nkluff ) { kluff = nkluff; calcMax(); } protected: void calcMax(); // member variables /** depth */ real depth; /** leech coefficient */ real kleech; /** luff coefficient */ real kluff; /** x location of maximum z */ real xmax; /** maximum depth z */ real zmax; }; /** Class used to store the profile for a sail. * * see CFormMould, CProfile */ class CSailMould { public: CSailMould(); CProfile interpol( const real h ) const; /** the mould's profiles ( top, middle, bottom ) */ // CProfile profile[3]; std::vector profile; /** vertical position of profile[1] in percent */ int vertpos; }; #endif sailcut-1.5.0/src/sailcpp/sailworker.cpp000066400000000000000000004251471477005247400203200ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "sailworker.h" #include "sailcalc.h" #define MAX_PANELS 210 /* To enable debugging */ // #define DEBUG 1 enum DisplayOptions { DontRotatePanels = 0, RotatePanels = 1 }; enum IntersectionType { FootIntersection = 1, // seam intersects foot LuffIntersection = 2, // seam intersects luff GaffIntersection = 3, // seam intersects gaff LeechIntersection = 4, // seam intersects leech MitreIntersection = 5, // seam intersects mitre }; /** Prepare the display version of a developed sail. */ static CPanelGroup prepareDisplaySail(const CPanelGroup &flatsail, real verticalSpacing, DisplayOptions options = DontRotatePanels) { CPanelGroup dispsail = flatsail; for (unsigned int j = 1; j < flatsail.size(); j++) { CPoint3d top = dispsail[j-1].top[0]; CPoint3d bot = dispsail[j].bottom[0]; // rotation to align bottom of panel to top of previous panel if (options & RotatePanels) { real x = dispsail[j-1].top.back().x() - top.x(); real y = dispsail[j-1].top.back().y() - top.y(); real CC = atan2(y, x); dispsail[j] = dispsail[j].rotated(bot, CC, Qt::ZAxis); } // translation v to align panel bottom edge origin to previous panel upper edge origin CVector3d v = top; v.setX(v.x() - bot.x()); v.setY(v.y() + verticalSpacing); // adding offset to separate panels vertically dispsail[j] = dispsail[j] + v; } return dispsail; } /** * The constructor does some preliminary calculations to set * internal variables. */ CSailWorker::CSailWorker(const CSailDef &s) : CSailDef(s) { /* First compute the coordinates of the corner of the sail */ CVector3d v1; real x = 0, headstay = 0; /* Then Compute the coordinates of the 4 corners of the sail */ switch ( sailType ) { case JIB: x = tackY * foreJ / foreI; headstay = sqrt(foreI * foreI + foreJ * foreJ); rake = foreJ * luffL / headstay; tack = CPoint3d( x , tackY , 0 ); //gaffL = 1; gaffR = 0; gaffRP = 50; // imposed value for short gaff gaffDeg = radiansToDegrees(atan2(foreI, foreJ)) - 10; break; default: tack = CPoint3d( tackX, tackY, 0 ); break; } /** VC++ 6 pre-SP3 bug if we pass the result of a square root directly, see : MS knowledgebase 217164). */ real stupid_hack = sqrt(luffL*luffL - rake*rake); head = tack + CVector3d(rake, stupid_hack, 0); // initial vector gaff set on vertical const CVector3d vertical(0, 1, 0); peak = head + rotateNormalized(-asin(rake / luffL) - degreesToRadians(gaffDeg), vertical) * gaffL; if ( fabs(peak.y() - head.y()) < 1 ) peak.setY(head.y() + 1); // to avoid case with gaff horizontal /* Compute triangle tack-peak-clew. */ real aa, b, bb; bb = atan2( peak.y() - tack.y() , peak.x() - tack.x() ); b = CVector3d(peak - tack).length(); aa = Atriangle( leechL , b , footL ); v1 = CVector3d( footL, 0, 0 ); // initial foot vector set on horizontal if (sailType == WING) clew = tack + v1; else clew = tack + rotateNormalized(bb - aa, v1) * footL; /* end of computation of corners of the sail */ /** Define foot vector of sail edge. */ footV = CVector3d( clew - tack ); /** Define gaff vector of sail edge. */ gaffV = CVector3d( peak - head ); /** Define fleech vector of sail edge. */ leechV = CVector3d( peak - clew ); /** Define luff vector of sail edge. */ luffV = CVector3d( head - tack ); /** Define mitre vector bisecting foot-leech angle. */ mitreV = CVector3d( tack - clew ).normalized() + leechV.normalized(); /** Define the unitary vectors perpendicular to foot edge, rotated anti-clockwise. */ footVP = rotateNormalized(M_PI/2, footV); /** Define the unitary vectors perpendicular to gaff edge, rotated anti-clockwise. */ gaffVP = rotateNormalized(M_PI/2, gaffV); /** Define the unitary vectors perpendicular to leech edge, rotated anti-clockwise. */ leechVP = rotateNormalized(M_PI/2, leechV); /** Define the unitary vectors perpendicular to luff edge, rotated anti-clockwise. */ luffVP = rotateNormalized(M_PI/2, luffV); /** Define useful straight lines of edges and mitre. */ footLine = CSubSpace::line(tack , footV); gaffLine = CSubSpace::line(head , gaffV); leechLine = CSubSpace::line(clew , leechV); luffLine = CSubSpace::line(tack , luffV); mitreLine = CSubSpace::line(clew , mitreV); /** Define point at intersection of mitre and luff. */ mitreLuffPt = EdgeIntersect( LUFF_EDGE, clew , mitreV ); } /** * Make a Sail from its definition. */ CPanelGroup CSailWorker::makeSail() const { CPanelGroup flatsail, dispsail; return makeSail(flatsail,dispsail); } /** * Make a Sail from its definition. * This is the main routine of all the sail layout work * The output is a 3D sail, its display and development versions. */ CPanelGroup CSailWorker::makeSail( CPanelGroup &flatsail , CPanelGroup &dispsail) const { CPanelGroup output; switch ( sailType ) { case WING: output = LayoutWing(flatsail , dispsail); break; default: switch ( sailCut ) { case CROSS: output = Layout0(flatsail , dispsail); break; case TWIST: output = LayoutTwist(flatsail , dispsail); break; case HORIZONTAL: output = Layout0(flatsail , dispsail); break; case VERTICAL: output = LayoutVertical(flatsail , dispsail); break; case RADIAL: output = LayoutRadial(flatsail , dispsail); break; case MITRE: output = LayoutMitre(flatsail , dispsail); break; case MITRE2: output = LayoutMitre2(flatsail , dispsail); break; default: throw layout_error("CSailWorker::makeSail : unknown sail cut layout!"); } } // place the labels at the centre of each panel output.placeLabels(); dispsail.placeLabels(); flatsail.plotLabels(); // assign the sail names output.title = sailID + " (3D)"; dispsail.title = sailID + " (3D)"; flatsail.title = sailID + " (flat)"; return output; } /** * Creates a Cross cut or horizontal cut sail. * * @param flatsail the CPanelGroup object that will hold the developed sail * @param dispsail the CPanelGroup object that will hold the display * version of the developed sail * @return CPanelGroup */ CPanelGroup CSailWorker::Layout0( CPanelGroup &flatsail, CPanelGroup &dispsail ) const { /* First create arrays p1 and p2 of points at the end of each seams * located on the straight edge of the sail (no round) * p1[] are on the luff side and p2[] are on the leech side */ CPoint3d p1[MAX_PANELS], p2[MAX_PANELS]; /* Create two temporary sails lay and the corresponding dev */ CPanelGroup lay(MAX_PANELS); // 3D sail CPanelGroup dev(MAX_PANELS); // developed sail /* create number of panels */ unsigned int npanel = 1; unsigned int npl = lay[0].right.size(); // number of right/left points unsigned int npb = lay[0].bottom.size(); // number of bottom/top points unsigned int j = 0, k = 0, cnt = 0; bool flag = false; // to check if top of sail is reached /* create arrays t1 and t2 of type of intersection of upper seam * respectively at points p1 on luff side and p2 on leech side */ IntersectionType t1[MAX_PANELS], t2[MAX_PANELS]; /* define point ip for intersections */ CPoint3d ip; CVector3d seamV; // seam Vector CSubSpace seamL; // seam Line if ( sailCut == HORIZONTAL ) seamV = CVector3d(-1, 0, 0); // horizontal seam orientation for Horizontal cut else // define seamV as the vector perpendicular to the leech vector (peak-clew) seamV = leechVP; // for classical cross cut /* create variables for the development and edge corrections */ CPoint3d top(0, 0, 0); CPoint3d bot(0, 0, 0); CVector3d v(0, 0, 0); CVector3d vb(0, 0, 0); CVector3d vk(0, 0, 0); /* create variable for edge correction */ std::vector deviation; deviation.resize(npb); std::vector deviaPrev; deviaPrev.resize(npb); /* Other edge hem width */ real luffHemW = hemsW; // real luffInnerHemW, footInnerHemW; /* seam 0 is on the foot of the sail ending at the clew */ p1[0] = tack; // initialise seam forward end at tack point p2[0] = clew; // initialise seam aft end at clew point t1[0] = FootIntersection; t2[0] = LeechIntersection; /** Lay the panels starting from the foot, going upward to the peak */ for (npanel = 1 ; npanel < MAX_PANELS -1 ; npanel++) { real exc = 0; // current excess of width real exb = 0; // total correction cnt = 0; // counter of iterations do /* Loop for optimising the seam position to fit cloth width */ { cnt++; p2[npanel] = p2[npanel-1] + (clothW - seamW - exb) * leechV.normalized(); t2[npanel] = LeechIntersection; seamL = CSubSpace::line( p2[npanel] , seamV ); if (CVector3d::dotProduct(p2[npanel] - peak, leechV) > 0) { // we are above peak, stop this is last panel flag = true; p2[npanel] = peak; // check on which side of the sail the previous point p1 is located if (t1[npanel-1] == FootIntersection) { // previous seam on foot p1[npanel] = head; t1[npanel] = LuffIntersection; // left points on foot-tack-luff lay[npanel-1].left.fill(p1[npanel-1], tack, p1[npanel]); for (k = 0 ; k < npl / 2 ; k++) lay[npanel-1].left[k] = EdgeIntersect( FOOT_EDGE, lay[npanel-1].left[k] , seamV); for (k = npl / 2 +1 ; k < npl ; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k] , seamV); } else if (t1[npanel-1] == LuffIntersection) { // left points on luff p1[npanel] = head; t1[npanel] = LuffIntersection; lay[npanel-1].left.fill(p1[npanel-1], p1[npanel]); for (k = 0 ; k < npl ; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], seamV); } else { // left points on gaff p1[npanel] = p1[npanel-1]; t1[npanel] = GaffIntersection; lay[npanel-1].left.fill(p1[npanel-1], p1[npanel]); for (k = 0 ; k < npl ; k++) lay[npanel-1].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].left[k], seamV); } // fill right points on leech lay[npanel-1].right.fill(p2[npanel-1],p2[npanel]); for (k = 0 ; k < npl ; k++) lay[npanel-1].right[k]=EdgeIntersect( LEECH_EDGE, lay[npanel-1].right[k], seamV); // fill bottom points lay[npanel-1].bottom.fill(lay[npanel-1].left[0], lay[npanel-1].right[0]); // fill top points lay[npanel-1].top.fill(lay[npanel-1].left[npl-1], lay[npanel-1].right[npl-1]); // move all top points of top panel to gaff curve for (k = 1 ; k < npb -1 ; k++) lay[npanel -1].top[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].top[k], CVector3d (head.y()-peak.y(),peak.x()-head.x(),0)); // end peak panel // } else // normal panel below peak ////// { /* find position of luff/seam intersection relative to tack and head */ ip = seamL.intersectionPoint(luffLine, "seam and luff"); if (CVector3d::dotProduct(ip - tack, luffV) <= 0) { // seam intersects foot p1[npanel] = seamL.intersectionPoint(footLine, "seam and foot"); t1[npanel] = FootIntersection; if ( npanel == 1 ) { // set lower edge to start at same point p1 p1[0] = p1[npanel]; t1[0] = FootIntersection; } } else if (CVector3d::dotProduct(ip - head, luffV) > 0) { // seam intersects gaff p1[npanel] = seamL.intersectionPoint(gaffLine, "seam and gaff"); t1[npanel] = GaffIntersection; } else { // seam intersects luff p1[npanel] = ip; t1[npanel] = LuffIntersection; if ( npanel == 1 ) { // force seam 0 to start at the tack p1[0] = tack; t1[0] = LuffIntersection; } } /* We now add the intermediate points on all sides of the normal panel */ /* Below is the code for the left side depending * on t1 for the top side and bottom side */ if (t1[npanel-1] == FootIntersection && t1[npanel] == FootIntersection) { // full foot lay[npanel-1].left.fill(p1[npanel-1] , p1[npanel]); for (k = 0 ; k < npl ; k++) lay[npanel-1].left[k] = EdgeIntersect( FOOT_EDGE, lay[npanel-1].left[k], seamV); } else if (t1[npanel-1] == LuffIntersection && t1[npanel] == LuffIntersection) { // full luff lay[npanel-1].left.fill(p1[npanel-1] , p1[npanel]); for (k = 0 ; k < npl ; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k] , seamV); } else if (t1[npanel-1] == GaffIntersection && t1[npanel] == GaffIntersection) { // full gaff lay[npanel-1].left.fill(p1[npanel-1] , p1[npanel]); for (k = 0 ; k < npl ; k++) lay[npanel-1].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].left[k] , seamV); } else if (t1[npanel-1] == FootIntersection && t1[npanel] == LuffIntersection) { // foot-tack-luff lay[npanel-1].left.fill(p1[npanel-1], tack, p1[npanel]); for (k = 0 ; k < npl / 2 ; k++) lay[npanel-1].left[k] = EdgeIntersect( FOOT_EDGE, lay[npanel-1].left[k], seamV); for (k = npl / 2 +1 ; k < npl ; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], seamV); } else if (t1[npanel-1] == LuffIntersection && t1[npanel] == GaffIntersection) { // luff-head-gaff lay[npanel-1].left.fill(p1[npanel-1], head, p1[npanel]); for (k = 0 ; k < npl/2 ; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], seamV); for (k = npl / 2 +1 ; k < npl ; k++) lay[npanel-1].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].left[k], seamV); } // end IF ELSE for left side /* Below is the code for the intermediate points of the right side * which are all on the leech for a crosscut layout. */ // first check if upper point is not below lower point if (CVector3d::dotProduct(p2[npanel] - p2[npanel-1], leechV) < 0) p2[npanel] = p2[npanel-1]; lay[npanel-1].right.fill(p2[npanel-1] , p2[npanel]); for (k = 0 ; k < npl ; k++) lay[npanel-1].right[k] = EdgeIntersect( LEECH_EDGE, lay[npanel-1].right[k], seamV); /* Below is the code for the intermediate points of the top and bottom sides. * The first point is identical to the last point of the left side * The last point is identical to the last point of the right side */ lay[npanel-1].top.fill( lay[npanel-1].left[npl-1] , lay[npanel-1].right[npl-1] ); lay[npanel-1].bottom.fill( lay[npanel-1].left[0] , lay[npanel-1].right[0] ); /* Below is the code for the intermediate points of the bottom side of first panel */ if ( npanel == 1 ) { // move bottom side of first panel to foot curve for (k = 1 ; k < npb -1 ; k++) { lay[0].bottom[k] = EdgeIntersect( FOOT_EDGE, lay[0].bottom[k], CVector3d(0,-1,0)); } } #ifdef DEBUG if ( npanel == 1 ) { std::cout << "CSailWorker::Layout0 Crosscut foot after adding curve" << std::endl; for (k = 0 ; k < npb ; k++) std::cout << "pt="<< k << " xyz=" << lay[0].bottom[k] << std::endl; } #endif } /* end else normal panel */ /** Go over all the points of current panel and calculate their Z */ lay[npanel-1] = Zpanel(lay[npanel-1]); #ifdef DEBUG if ( npanel == 1 ) { // move bottom side of first panel to foot curve std::cout << "CSailWorker::Layout0 Crosscut foot after Z " << std::endl; for (k = 0 ; k < npb ; k++) std::cout << "pt="<< k << " xyz=" << lay[0].bottom[k] << std::endl; std::cout << "---end Z foot---- DO LOOP=" << cnt << std::endl; } #endif /** Develop the current panel */ if ( npanel == 1 ) { dev[npanel-1] = lay[npanel-1].develop(ALIGN_TOP); } else { dev[npanel-1] = lay[npanel-1].develop(ALIGN_BOTTOM); // add deviation of previous panel top edge to bottom edge for (k = 1; k < npb-1; k ++) dev[npanel-1].bottom[k] = dev[npanel-1].bottom[k] + deviaPrev[k]; } /** Compute and store the deviation of top edge of * the developed panel and straighten this top edge * except if this is the top panel */ if ( flag == false ) { vb= rotateNormalized(M_PI/2, dev[npanel-1].top[npb-1] - dev[npanel-1].top[0]); for (k = 1 ; k < npb -1 ; k ++) { vk = CVector3d (dev[npanel-1].top[k] - dev[npanel-1].top[0]); v = vb * -CVector3d::dotProduct(vk, vb); deviation[k] = v; dev[npanel-1].top[k] = dev[npanel-1].top[k] + deviation[k]; } } /** Add the seam and hems allowance */ if ( npanel == 1 ) { dev[npanel-1].add6Hems( hemsW, hemsW, seamW, leechHemW, leechHemW, footHemW ); } else if ( flag == true ) { dev[npanel-1].add6Hems( hemsW, hemsW, hemsW, leechHemW, leechHemW, 0 ); } else { if ( t1[npanel-1] == FootIntersection && t1[npanel] == LuffIntersection ) dev[npanel-1].add6Hems( footHemW, luffHemW, seamW, leechHemW, leechHemW, 0 ); else dev[npanel-1].add6Hems( hemsW, hemsW, seamW, leechHemW, leechHemW, 0 ); } /* Check the width of developed panel and store the excess */ exc = dev[npanel-1].boundingRect().height() - clothW; /* Sum previous correction + 80% of current excess of width + 1mm */ exb += 0.8 * exc + 1; } while ( exc > 0 && cnt < 9 ); /* loop as long the excess of width is positive AND counter < 9 */ deviaPrev = deviation; /** Reposition the developed panel such that the * lowest point is Y=0 AND most left point is X=0. */ dev[npanel-1].reframe(); /* check if peak has been reached to break off */ if ( flag == true ) break; } /** Loop FOR next panel */ if ( npanel == MAX_PANELS-1 ) throw layout_error("CSailWorker::Layout0 : MAX_PANELS without reaching head, do increase cloth width "); /* Copy the sails for 3D display */ CPanelGroup sail(npanel); for (j = 0 ; j < npanel ; j ++) sail[j] = lay[j]; /** Create the displays version of the developed sail */ /* Copy the developed sail */ flatsail = CPanelGroup(npanel); for (j = 0 ; j < npanel ; j++) { flatsail[j] = dev[j]; } dispsail = prepareDisplaySail(flatsail, 2 * seamW + 20, RotatePanels); return sail; } /* end layout0 = cross cut or horizontal //////////////// */ /** Creates a twist foot cut sail. * * @param flatsail the CPanelGroup object that will hold the developed sail * @param dispsail the CPanelGroup object that will hold the display * version of the developed sail * @return CPanelGroup */ CPanelGroup CSailWorker::LayoutTwist( CPanelGroup &flatsail, CPanelGroup &dispsail ) const { /* First create arrays p1 and p2 of points at the end of each seams * located on the straight edge of the sail (no round) */ CPoint3d p1[MAX_PANELS], p2[MAX_PANELS]; /* Create two temporary sails lay and the corresponding dev */ CPanelGroup lay(MAX_PANELS); // 3D sail CPanelGroup dev(MAX_PANELS); // developed sail /* create number of panels */ unsigned int npanel = 1; unsigned int npl = lay[0].right.size(); // number of right/left points unsigned int npb = lay[0].bottom.size(); // number of bottom/top points unsigned int j = 0, k = 0, cnt = 0; bool flag = false; /* create arrays t1 and t2 of type of intersection * respectively at points p1 on luff side and p2 on leech side */ IntersectionType t1[MAX_PANELS], t2[MAX_PANELS]; /* define point ip for intersections */ CPoint3d ip; /* define the seamV as the vector perpendicular to the leech vector (peak-clew)*/ CVector3d seamV = leechVP; CSubSpace seamL; // seam line CVector3d seamVT; // seam vector twisted CSubSpace seamLT; // seam line twisted /* create variables for the development and edge corrections */ CPoint3d top(0, 0, 0); CPoint3d bot(0, 0, 0); CVector3d v(0, 0, 0); CVector3d vb(0, 0, 0); CVector3d vk(0, 0, 0); /* create variable for edge correction */ std::vector deviation; deviation.resize(npb); std::vector deviaPrev; deviaPrev.resize(npb); /* seam 0 is on the foot of the sail ending at the clew */ p1[0] = tack; // initialised at tack point p2[0] = clew; t1[0] = LuffIntersection; t2[0] = LeechIntersection; /* Other edge hem width */ real luffHemW = hemsW; // real luffInnerHemW, footInnerHemW; /** Start laying the panels from foot upward to the peak */ for (npanel = 1; npanel < MAX_PANELS-1; npanel++) { real exb = 0; // total correction real exc = 0; // current excess of width cnt = 0; /* Loop for optimising the seam position to fit cloth width */ do { cnt++; p2[npanel] = p2[npanel-1] + leechV.normalized() * (clothW - seamW - exb); t2[npanel] = LeechIntersection; seamL = CSubSpace::line( p2[npanel] , seamV ); if (CVector3d::dotProduct(p2[npanel] - peak, leechV) > 0) { // we are above peak, stop this is last panel flag=true; p2[npanel] = peak; // check where previous point p1 is if (t1[npanel-1] == LuffIntersection) { // left points on luff p1[npanel] = head; t1[npanel] = LuffIntersection; lay[npanel-1].left.fill(p1[npanel-1] , p1[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], seamV); } else { // left points on gaff p1[npanel] = p1[npanel-1]; t1[npanel] = GaffIntersection; lay[npanel-1].left.fill(p1[npanel-1] , p1[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].left[k], seamV); } // fill right points on leech lay[npanel-1].right.fill(p2[npanel-1] , p2[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].right[k] = EdgeIntersect( LEECH_EDGE, lay[npanel-1].right[k], seamV); // fill bottom points lay[npanel-1].bottom.fill(lay[npanel-1].left[0], lay[npanel-1].right[0]); // fill top points lay[npanel-1].top.fill(lay[npanel-1].left[npl-1], lay[npanel-1].right[npl-1]); // move all top points to gaff curve for (k=1; k < npb-1; k++) lay[npanel-1].top[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].top[k], CVector3d (head.y()-peak.y() , peak.x()-head.x() , 0)); // end peak panel ////// } else // normal panel { /* find nominal position of luff/seam intersection relative to tack and head */ ip = seamL.intersectionPoint(luffLine, "seam and luff"); if (CVector3d::dotProduct(( ip - luffV.normalized() * (seamW + clothW/5) ) - p1[npanel-1], luffV) < 0) { // seam intersects luff below previous panel luff point + 1/5 clothW p1[npanel] = p1[npanel-1] + luffV.normalized() * (seamW + clothW/5); t1[npanel] = LuffIntersection; seamVT = CVector3d( p1[npanel] - p2[npanel] ).normalized(); seamLT = CSubSpace::line(p2[npanel] , seamVT); ip = seamLT.intersectionPoint(luffLine, "seamLT and luff"); #ifdef DEBUG std::cout << "CSailWorker::LayoutTwist Seam 1 LUFF CORRECTION DO LOOP = " << cnt << std::endl; std::cout << " ip = " << ip << std::endl; std::cout << "p1[0] " << p1[0] << " p2[0] " << p2[0] << " type "<< t1[0] << t2[0] << std::endl; std::cout << "p1[1] " << p1[1] << " p2[1] " << p2[1] << " type "<< t1[1] << t2[1] << std::endl; std::cout << "seam VT = " << seamVT << std::endl; std::cout << "--- " << std::endl; #endif } else if (CVector3d::dotProduct(ip - head, luffV) > 0) { // seam intersects gaff p1[npanel] = seamL.intersectionPoint(gaffLine, "seam and gaff"); t1[npanel] = GaffIntersection; seamVT = seamV; } else { // seam intersects luff normally p1[npanel] = ip; t1[npanel] = LuffIntersection; seamVT = seamV; } /* We now add the intermediate points on all sides of the panel */ /* Below is the code for the left side depending * on t1 for the top side and bottom side */ if (t1[npanel-1] == LuffIntersection && t1[npanel] == LuffIntersection) { // full luff lay[npanel-1].left.fill(p1[npanel-1], p1[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], seamVT); } else if (t1[npanel-1] == GaffIntersection && t1[npanel] == GaffIntersection) { // full gaff lay[npanel-1].left.fill(p1[npanel-1] , p1[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].left[k], seamV); } else if (t1[npanel-1] == LuffIntersection && t1[npanel] == GaffIntersection) { // luff-head-gaff lay[npanel-1].left.fill(p1[npanel-1] , head, p1[npanel]); for (k = 0; k < npl/2; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], seamV); for (k = npl/2 +1; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].left[k], seamV); } /* Compute the intermediate points of the right side * which are all on the leech for a twist cut layout. */ // first check if upper point is not below lower point if (CVector3d::dotProduct(p2[npanel] - p2[npanel-1], leechV) < 0) p2[npanel] = p2[npanel-1]; lay[npanel-1].right.fill(p2[npanel-1] , p2[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].right[k] = EdgeIntersect( LEECH_EDGE, lay[npanel-1].right[k], seamV); /* Compute the intermediate points of the top and bottom sides. * The first point is identical to the last point of the left side * The last point is identical to the last point of the right side */ lay[npanel-1].top.fill(lay[npanel-1].left[npl-1], lay[npanel-1].right[npl-1]); lay[npanel-1].bottom.fill(lay[npanel-1].left[0], lay[npanel-1].right[0]); #ifdef DEBUG if ( npanel == 1 ) { std::cout << "CSailWorker::LaoutTwist foot straight - LOOP= "<< cnt << std::endl; for (k = 0 ; k < npb ; k++) std::cout << "pt="<< k << " Bottom xyz= " << lay[0].bottom[k] << " Top xyz= " << lay[0].top[k] << std::endl; } #endif /* Move the intermediate points of the bottom side of first panel */ if ( npanel == 1 ) { // move bottom side of first panel to foot curve for (k = 1 ; k < npb-1 ; k++) lay[0].bottom[k] = EdgeIntersect( FOOT_EDGE, lay[0].bottom[k] , footVP ); } } /* end else normal panel //////// */ /* Now we go over all the points and calculate their Z */ lay[npanel-1] = Zpanel(lay[npanel-1]); /* Develop the current panel */ if ( npanel == 1 ) dev[npanel-1] = lay[npanel-1].develop(ALIGN_TOP); else { dev[npanel-1] = lay[npanel-1].develop(ALIGN_BOTTOM); // add deviation of previous panel top edge to this bottom edge for (k = 1 ; k < npb-1 ; k++) dev[npanel-1].bottom[k] = dev[npanel-1].bottom[k] + deviaPrev[k]; } /* Compute and store the deviation of top edge of developed panel * and straighten this top edge Except if this is the top panel. */ if (flag == false) { vb= rotateNormalized(M_PI/2, dev[npanel-1].top[npb-1] - dev[npanel-1].top[0]); for (k = 1 ; k < npb-1 ; k++) { vk = CVector3d (dev[npanel-1].top[k] - dev[npanel-1].top[0]); v = vb * -CVector3d::dotProduct(vk, vb); deviation[k] = v; dev[npanel-1].top[k] = dev[npanel-1].top[k] + deviation[k]; } } /* Add the seam and hems allowance */ if (npanel == 1) dev[npanel-1].add6Hems( luffHemW, luffHemW, seamW, leechHemW, leechHemW, footHemW ); else if (flag == true) dev[npanel-1].add6Hems( hemsW, hemsW, hemsW, leechHemW, leechHemW, 0 ); else if (t1[npanel-1] == LuffIntersection && t1[npanel] == LuffIntersection) dev[npanel-1].add6Hems( luffHemW, luffHemW, seamW, leechHemW, leechHemW, 0 ); else if (t1[npanel-1] == LuffIntersection && t1[npanel] == GaffIntersection) dev[npanel-1].add6Hems( luffHemW, hemsW, seamW, leechHemW, leechHemW, 0 ); else dev[npanel-1].add6Hems( hemsW, hemsW, seamW, leechHemW, leechHemW, 0 ); #ifdef DEBUG if ( npanel == 1 ) { // move bottom side of first panel to foot curve std::cout << "CSailWorker::LayoutTwist foot after adding seams " << std::endl; for (k = 0 ; k < npb ; k++) std::cout << "pt="<< k << " xyz=" << dev[0].bottom[k] << std::endl; std::cout << "------END LOOP="<< cnt << std::endl; } #endif /* Check the width of developed panel */ exc = dev[npanel-1].boundingRect().height() - clothW; /* Sum previous correction + 80% of current excess of width + 1mm */ exb += 0.8 * exc + 1; } while ( exc > 0 && cnt < 9 ); /* loop as long the excess of width is positive AND counter < 9 */ deviaPrev = deviation; /* Now we reposition the developed panel such that * bottom minimum is Y=0 AND most left point is X=0 */ dev[npanel-1].reframe(); /* check if peak has been reached to break off */ if ( flag == true ) break; } /* loop FOR next seam */ if (npanel == MAX_PANELS-1) throw layout_error("CSailWorker::LayoutTwist -5 : MAX_PANELS without reaching head, do increase cloth width "); /* Copy the sails for display */ CPanelGroup sail(npanel); for (j = 0; j < npanel; j++) sail[j] = lay[j]; /* Copy the developed sail */ flatsail = CPanelGroup(npanel); for (j = 0; j < npanel; j++) flatsail[j] = dev[j]; dispsail = prepareDisplaySail(flatsail, 2 * seamW + 20, RotatePanels); return sail; } /* end layout twist foot //////////// */ /** Creates a VERTICAL cut sail. * * @param flatsail the CPanelGroup object that will hold the developed sail * @param dispsail the CPanelGroup object that will hold the display * version of the developed sail * @return CPanelGroup */ CPanelGroup CSailWorker::LayoutVertical( CPanelGroup &flatsail, CPanelGroup &dispsail ) const { /* First create arrays p1 and p2 of points at the end of each seams * located on the straight edge of the sail (no round) */ CPoint3d p1[MAX_PANELS], p2[MAX_PANELS]; /* Create two temporary sails lay and the corresponding dev */ CPanelGroup lay(MAX_PANELS); // 3D sail CPanelGroup dev(MAX_PANELS); // developed sail /* create number of panels */ unsigned int npanel = 1; unsigned int npl = lay[0].right.size(); // number of right/left points unsigned int npb = lay[0].bottom.size(); // number of bottom/top points unsigned int j=0, k=0, cnt=0; bool flag=false; /* create arrays t1 and t2 of type of intersection * respectively at points p1 on luff side and p2 on leech side */ IntersectionType t1[MAX_PANELS], t2[MAX_PANELS]; /* define point ip for intersections */ CPoint3d ip; /* define seamV as the vector parrallel to the leech vector (peak-clew)*/ CVector3d seamV = leechV.normalized(); CSubSpace seamL; // seam Line /* create variables for the development and edge corrections */ CPoint3d pt(0, 0, 0); // test point CPoint3d top(0, 0, 0); CPoint3d bot(0, 0, 0); CVector3d v(0, 0, 0); CVector3d vb(0, 0, 0); CVector3d vk(0, 0, 0); /* create variable for panel width correction */ std::vector deviation; deviation.resize(npb); std::vector deviaPrev; deviaPrev.resize(npb); /* Other edge hem width */ real luffHemW = hemsW; // real luffInnerHemW, footInnerHemW; /* seam 0 is on the leech of the sail ending at the peak */ p1[0] = clew; // initialised at tack point p2[0] = peak; t1[0] = FootIntersection; t2[0] = GaffIntersection; /** Lay the panels parallel to the leech, from the leech toward the tack */ for (npanel = 1; npanel < MAX_PANELS-1; npanel++) { real exb = 0; // total correction real exc = 0; // current excess of width cnt = 0; //if (npanel==3) flag=true; /* Loop for optimising the seam position to fit cloth width */ do { cnt++; pt = p1[npanel-1] + (clothW -seamW -exb) * leechVP; seamL = CSubSpace::line(pt, seamV); p1[npanel] = seamL.intersectionPoint(footLine, "seam and foot"); t1[npanel] = FootIntersection; if ( p1[npanel].x() <= tack.x() ) { // last panel p1[npanel] = tack; t1[npanel] = FootIntersection; p2[npanel] = tack; t2[npanel] = LuffIntersection; flag = true; // set the FLAG to get out of FOR } else { // normal panel p2[npanel] = seamL.intersectionPoint(gaffLine, "seam and gaff"); if (CVector3d::dotProduct(p2[npanel] - head, gaffV) > 0) t2[npanel] = GaffIntersection; else { p2[npanel] = seamL.intersectionPoint(luffLine, "seam and luff"); t2[npanel] = LuffIntersection; } } // fill right side points if (t2[npanel-1] == LuffIntersection && t2[npanel] == LuffIntersection) { // printf ("full luff \n"); lay[npanel-1].right.fill(p2[npanel-1], p2[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].right[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].right[k], seamV); } else if (t2[npanel-1] == GaffIntersection && t2[npanel] == LuffIntersection) { // printf ("gaff-head-luff \n"); lay[npanel-1].right.fill(p2[npanel-1], head, p2[npanel]); for (k = 0; k < npl/2; k++) lay[npanel-1].right[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].right[k], seamV); for (k = npl/2+1; k < npl; k++) lay[npanel-1].right[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].right[k], seamV); } else { // printf ("full gaff \n"); lay[npanel-1].right.fill(p2[npanel-1], p2[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].right[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].right[k], seamV); } // fill left side points which are all on foot lay[npanel-1].left.fill(p1[npanel-1], p1[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( FOOT_EDGE, lay[npanel-1].left[k], leechV); // fill bottom points lay[npanel-1].bottom.fill(lay[npanel-1].left[0], lay[npanel-1].right[0]); if ( npanel == 1 ) { // bottom is on the leech for (k = 0; k < npb; k++) lay[npanel-1].bottom[k] = EdgeIntersect( LEECH_EDGE, lay[npanel-1].bottom[k], leechVP); } /* fill top side points on seam */ lay[npanel-1].top.fill(lay[npanel-1].left[npl-1], lay[npanel-1].right[npl-1]); /* Go over all the points and calculate their z */ lay[npanel-1] = Zpanel(lay[npanel-1]); /* Develop the current panel */ if ( npanel == 1 ) dev[npanel-1] = lay[npanel-1].develop(ALIGN_TOP); else { dev[npanel-1] = lay[npanel-1].develop(ALIGN_BOTTOM); // add deviation of previous panel top edge to bottom edge for (k = 1; k < npb-1; k ++) dev[npanel-1].bottom[k] = dev[npanel-1].bottom[k] + deviaPrev[k]; } /* Now we compute the deviation of top edge of developed panel * and straighten this top edge except if this is the top panel */ if ( flag == false ) { vb = rotateNormalized(M_PI/2, dev[npanel-1].top[npb-1] - dev[npanel-1].top[0]); for (k = 1; k < npb-1; k ++) { vk = CVector3d (dev[npanel-1].top[k] - dev[npanel-1].top[0]); v = vb * -CVector3d::dotProduct(vk, vb); deviation[k] = v; dev[npanel-1].top[k] = dev[npanel-1].top[k] + deviation[k]; } } /* Add the seam and hems allowance */ if ( npanel == 1 ) dev[npanel-1].add6Hems( footHemW, footHemW, seamW, hemsW, hemsW, leechHemW ); else if ( flag == true ) dev[npanel-1].add6Hems( footHemW, footHemW, luffHemW, luffHemW, luffHemW, 0 ); else if (t2[npanel-1] == GaffIntersection && t2[npanel] == GaffIntersection) dev[npanel-1].add6Hems( footHemW, footHemW, seamW, hemsW, hemsW, 0 ); else if (t2[npanel-1] == GaffIntersection && t2[npanel] == LuffIntersection) dev[npanel-1].add6Hems( footHemW, footHemW, seamW, luffHemW, hemsW, 0 ); else dev[npanel-1].add6Hems( footHemW, footHemW, seamW, luffHemW, luffHemW, 0 ); /* Check the width of developed panel and store excess */ exc = dev[npanel-1].boundingRect().height() - clothW; /* Sum previous correction + 80% of current excess of width + 1mm */ exb += 0.8 * exc + 1; } while ( exc > 0 && cnt < 9 ); /* loop as long the excess of width is positive AND counter < 9 */ deviaPrev = deviation; /* Now we reposition the developed panel such that bottom left is X=0 Y=0 */ dev[npanel-1].reframe(); /* check if peak has been reached to break off */ if ( flag == true ) break; } /* Loop FOR next seam */ if ( npanel == MAX_PANELS-1 ) throw layout_error("CSailWorker::LayoutVertical -4 : MAX_PANELS without reaching tack, do increase cloth width "); /* Copy the sails for display */ CPanelGroup sail( npanel ); for (j = 0; j < npanel; j++) sail[j] = lay[j]; /* Copy the developed sail into flatsail */ flatsail = CPanelGroup( npanel ); for (j = 0; j < npanel; j++) flatsail[j] = dev[j]; dispsail = prepareDisplaySail(flatsail, 2 * seamW + 10); return sail; } /* end layout vertical cut //////// */ /** Creates a WING with horizontal cut layout. * The panels are layed parrallel to the central line of the wing (horizontal cut) * @param flatsail the CPanelGroup object that will hold the developed sail * @param dispsail the CPanelGroup object that will hold the display * version of the developed sail * @return CPanelGroup */ CPanelGroup CSailWorker::LayoutWing( CPanelGroup &flatsail, CPanelGroup &dispsail ) const { /* First create arrays p1 and p2 of points at the end of each seams * located on the straight edge of the sail (no round) */ CPoint3d p1[MAX_PANELS], p2[MAX_PANELS]; /* Create two temporary sails lay and the corresponding dev */ CPanelGroup lay(MAX_PANELS); // 3D sail CPanelGroup dev(MAX_PANELS); // developed sail /* Create number of panels */ unsigned int npanel=1, np=1; unsigned int npl= lay[0].right.size(); // number of right/left points unsigned int npb= lay[0].bottom.size(); // number of bottom/top points /* Angle of the half wing from X-Y plane */ real alfa = degreesToRadians((180 - dihedralDeg) / 2); unsigned int j=0, k=0; bool flag=false; // to check if top of sail is reached /* create arrays t1 and t2 of type of intersection * respectively at points p1 on luff side and p2 on leech side */ IntersectionType t1[MAX_PANELS], t2[MAX_PANELS]; /* define point ip for intersections */ CPoint3d ip; /* define seamV as the horizontal vector*/ CVector3d seamV(-1,0,0); CSubSpace seamL; /* create variables for the development and edge corrections */ CPoint3d top(0, 0, 0); CPoint3d bot(0, 0, 0); CVector3d v(0, 0, 0); CVector3d vb(0, 0, 0); CVector3d vk(0, 0, 0); /* create variable for edge correction */ std::vector deviation; deviation.resize(npb); std::vector deviaPrev; deviaPrev.resize(npb); /* Other edge hem width */ real luffHemW = hemsW; // real luffInnerHemW, footInnerHemW; /* seam 0 is on the foot of the sail ending at the clew */ p1[0] = tack; // initialised at tack point p2[0] = clew; t1[0] = FootIntersection; t2[0] = LeechIntersection; /** Position the seams starting from the centre of the wing (foot) */ for (npanel = 1; npanel < MAX_PANELS-1; npanel++) { p2[npanel] = p2[npanel-1] + (clothW-seamW)/CVector3d::dotProduct(seamV, leechVP) * leechV.normalized(); t2[npanel] = LeechIntersection; seamL = CSubSpace::line(p2[npanel], seamV); if (CVector3d::dotProduct(p2[npanel] - peak, leechV) > 0) // we are above peak, stop last panel { flag = true; p2[npanel] = peak; // check on which side of the sail the previous point p1 is located if (t1[npanel-1] == FootIntersection) { // previous seam on foot p1[npanel] = head; t1[npanel] = LuffIntersection; // left points on foot-tack-luff lay[npanel-1].left.fill(p1[npanel-1], tack, p1[npanel]); for (k = 0; k < npl/2; k++) lay[npanel-1].left[k] = EdgeIntersect( FOOT_EDGE, lay[npanel-1].left[k], seamV); for (k = npl/2 +1; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], seamV); } else if (t1[npanel-1] == LuffIntersection) { // left points on luff p1[npanel] = head; t1[npanel] = LuffIntersection; lay[npanel-1].left.fill(p1[npanel-1], p1[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], seamV); } else { // left points on gaff p1[npanel] = p1[npanel-1]; t1[npanel] = GaffIntersection; lay[npanel-1].left.fill(p1[npanel-1], p1[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].left[k], seamV); } // fill right points on leech lay[npanel-1].right.fill(p2[npanel-1],p2[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].right[k] = EdgeIntersect( LEECH_EDGE, lay[npanel-1].right[k], seamV); // fill bottom points lay[npanel-1].bottom.fill(lay[npanel-1].left[0], lay[npanel-1].right[0]); // fill top points lay[npanel-1].top.fill(lay[npanel-1].left[npl-1], lay[npanel-1].right[npl-1]); // move all top points of top panel to gaff curve for (k = 1; k < npb-1; k++) lay[npanel-1].top[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].top[k], CVector3d (head.y()-peak.y(),peak.x()-head.x(),0)); // end peak panel } else // normal panel { /* find position of luff/seam intersection relative to tack and head */ ip = seamL.intersectionPoint(luffLine, "seam and luff"); if (CVector3d::dotProduct(ip - tack, luffV) <= 0) { // seam intersects foot p1[npanel] = seamL.intersectionPoint(footLine, "seam and foot"); t1[npanel] = FootIntersection; if ( npanel == 1 ) { // set lower edge to start at same point p1 p1[0] = p1[npanel]; t1[0] = FootIntersection; } } else if (CVector3d::dotProduct(ip - head, luffV) > 0) { // seam intersects gaff p1[npanel] = seamL.intersectionPoint(gaffLine, "seam and gaff"); t1[npanel] = GaffIntersection; } else { // seam intersects luff p1[npanel] = ip; t1[npanel] = LuffIntersection; if ( npanel == 1 ) { // force seam 0 to start at the tack p1[0] = tack; t1[0] = LuffIntersection; } } /* We now add the intermediate points on all sides of the normal panel */ /* Below is the code for the left side depending * on t1 for the top side and bottom side */ if (t1[npanel-1] == FootIntersection && t1[npanel] == FootIntersection) { // full foot lay[npanel-1].left.fill(p1[npanel-1], p1[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( FOOT_EDGE, lay[npanel-1].left[k], seamV); } else if (t1[npanel-1] == LuffIntersection && t1[npanel] == LuffIntersection) { // full luff lay[npanel-1].left.fill(p1[npanel-1], p1[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], seamV); } else if (t1[npanel-1] == GaffIntersection && t1[npanel] == GaffIntersection) { // full gaff lay[npanel-1].left.fill(p1[npanel-1], p1[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].left[k], seamV); } else if (t1[npanel-1] == FootIntersection && t1[npanel] == LuffIntersection) { // foot-tack-luff lay[npanel-1].left.fill(p1[npanel-1], tack, p1[npanel]); for (k = 0; k < npl/2; k++) lay[npanel-1].left[k] = EdgeIntersect( FOOT_EDGE, lay[npanel-1].left[k], seamV); for (k = npl/2 +1; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], seamV); } else if (t1[npanel-1] == LuffIntersection && t1[npanel] == GaffIntersection) { // luff-head-gaff lay[npanel-1].left.fill(p1[npanel-1], head, p1[npanel]); for (k = 0; k < npl / 2; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], seamV); for (k = npl/2 +1; k < npl; k++) lay[npanel-1].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].left[k], seamV); } // end IF ELSE for left side /* Below is the code for the intermediate points of the right side * which are all on the leech for a crosscut layout. */ lay[npanel-1].right.fill(p2[npanel-1],p2[npanel]); for (k = 0; k < npl; k++) lay[npanel-1].right[k] = EdgeIntersect( LEECH_EDGE, lay[npanel-1].right[k], seamV); /* Below is the code for the intermediate points of the top and bottom sides. * The first point is identical to the last point of the left side * The last point is identical to the last point of the right side */ lay[npanel-1].top.fill(lay[npanel-1].left[npl-1], lay[npanel-1].right[npl-1]); lay[npanel-1].bottom.fill(lay[npanel-1].left[0], lay[npanel-1].right[0]); /* Below is the code for the intermediate points of the bottom side of first panel */ if ( npanel == 1 ) { // move bottom side of first panel to foot curve for (k = 1; k < npb -1; k++) lay[0].bottom[k] = EdgeIntersect( FOOT_EDGE, lay[0].bottom[k], CVector3d(0,-1,0)); } } // end else normal panel ///////////////// */ /* Go over all the points and calculate their z */ lay[npanel-1] = Zpanel(lay[npanel-1]); /* Rotate the panel by the dihedral angle */ lay[npanel-1] = lay[npanel-1].rotated(tack, alfa, Qt::XAxis); /* If it is the first panel, then cut the foot to tack level */ if ( npanel == 1 ) { for (k=0; k < npb-1; k++) lay[0].bottom[k].setY(tack.y()); lay[0].left[0].setY(tack.y()); lay[0].right[0].setY(tack.y()); } /* Develop the current panel */ if ( npanel == 1 ) { dev[npanel-1] = lay[npanel-1].develop(ALIGN_TOP); } else { dev[npanel-1] = lay[npanel-1].develop(ALIGN_BOTTOM); // add deviation of previous panel top edge to bottom edge for (k = 1; k < npb-1; k ++) dev[npanel-1].bottom[k] = dev[npanel-1].bottom[k] + deviaPrev[k]; } /* Now we compute and store the deviation of top edge of * the developed panel and straighten this top edge * except if this is the top panel */ if ( flag == false ) { vb= rotateNormalized(M_PI/2, dev[npanel-1].top[npb-1] -dev[npanel-1].top[0]); for (k = 1; k < npb-1; k ++) { vk = CVector3d (dev[npanel-1].top[k] - dev[npanel-1].top[0]); v = vb * -CVector3d::dotProduct(vk, vb); deviation[k] = v; dev[npanel-1].top[k] = dev[npanel-1].top[k] + deviation[k]; } } /* Add the seam and hems allowance to wing horizontal layout */ if ( npanel == 1 ) dev[npanel-1].add6Hems( luffHemW, luffHemW, seamW, leechHemW, leechHemW, footHemW ); else if ( flag == true ) dev[npanel-1].add6Hems( hemsW, hemsW, hemsW, leechHemW, leechHemW, 0 ); else if ( t1[npanel-1] == GaffIntersection && t1[npanel] == GaffIntersection ) dev[npanel-1].add6Hems( hemsW, hemsW, seamW, leechHemW, leechHemW, 0 ); else if ( t1[npanel-1] == LuffIntersection && t1[npanel] == GaffIntersection ) dev[npanel-1].add6Hems( luffHemW, hemsW, seamW, leechHemW, leechHemW, 0 ); else dev[npanel-1].add6Hems( luffHemW, luffHemW, seamW, leechHemW, leechHemW, 0 ); /* Reset the previous panel deviation to the current panel */ deviaPrev = deviation; /* Reposition the developed panel such that * bottom minimum is Y=0 AND most left is X=0 */ dev[npanel-1].reframe(); /* check if peak has been reached to break off */ if ( flag == true ) break; } /* loop FOR next seam ///////////// */ if ( npanel == (MAX_PANELS/2 -1) ) throw layout_error("CSailWorker::LayoutWing -4 : got to MAX_PANELS without reaching head, do increase cloth width "); /** Create the symetrical panels */ np = npanel; for (j = 0; j < np +1; j++) { npanel++; lay[npanel] = lay[j]; dev[npanel] = dev[j]; for (k = 0 ; k < npb ; k++) { lay[npanel].top[k].setY(-lay[npanel].top[k].y()); lay[npanel].bottom[k].setY(-lay[npanel].bottom[k].y()); } for (k = 0 ; k < npl ; k++) { lay[npanel].left[k].setY(-lay[npanel].left[k].y()); lay[npanel].right[k].setY(-lay[npanel].right[k].y()); } } /* Copy the sails for display */ CPanelGroup sail( 2 * npanel +1 ); for (j = 0; j < npanel; j++) sail[j] = lay[j]; /* Copy the developed sail */ flatsail = CPanelGroup( 2 * npanel +1); for (j = 0; j < npanel; j++) { flatsail[j] = dev[j]; } dispsail = prepareDisplaySail(flatsail, 2 * seamW + 25, RotatePanels); return sail; } /* end layoutWing = cross cut or horizontal //////////////////// */ /** Creates a radial cut sail. * * @param flatsail the CPanelGroup object that will hold the developed sail * @param dispsail the CPanelGroup object that will hold the display * version of the developed sail * @return CPanelGroup */ CPanelGroup CSailWorker::LayoutRadial( CPanelGroup &flatsail, CPanelGroup &dispsail ) const { unsigned int h = 0, j = 0, k = 0, a = 1, b = 1; unsigned int ngLuff = nbLuffGores; // limit of luff gores unsigned int ng1 = 0; // number of central panels //bool flag=false; real x = 0, xm = 0, xp = 0, ym = 0; CPoint3d pt0, pt1, pt2, pt3, pt4, ptCentre, ptFoot; // points /* Create two temporary sails lay and the corresponding dev */ CPanelGroup lay(MAX_PANELS); // 3D sail CPanelGroup dev(MAX_PANELS); // developed sail /* create number of panels */ unsigned int npanel = 1; unsigned int npl = lay[0].right.size(); // number of right/left points unsigned int npb = lay[0].bottom.size(); // number of bottom/top points unsigned int nps[10]; // number of panels per sections /* create variables for the development and edge corrections */ CPoint3d top(0, 0, 0); CPoint3d bot(0, 0, 0); CVector3d v(0, 0, 0); CVector3d vb(0, 0, 0); CVector3d vk(0, 0, 0); /* create variable for edge correction */ std::vector deviation; deviation.resize(npb); /* Other edge hem width */ // real footHemW = hemsW; // real luffHemW = hemsW; // real luffInnerHemW, footInnerHemW; /* Create arrays of points at horizontal seams ends (10 maximum) */ CPoint3d luffH[10]; // point at the luff end of the horizontal seam CPoint3d leechH[10]; // point at the leech end of the horizontal seam CSubSpace seamH[10]; // corresponding seam lines CSubSpace seamL; // a seam line h = 0; luffH[h] = tack; leechH[h] = clew; seamH[h] = footLine; for (h = 1; h < nbSections; h++) { pt1 = tack + luffV * (real(h) / nbSections ); pt2 = clew + leechV * (real(h) / nbSections ); luffH[h] = EdgeIntersect( LUFF_EDGE, pt1, CVector3d( pt1 - pt2 ) ); leechH[h] = EdgeIntersect( LEECH_EDGE, pt2, CVector3d( pt2 - pt1) ); seamH[h] = CSubSpace::line(luffH[h], CVector3d( leechH[h] - luffH[h] )); } h = nbSections; // one more horizontal line than nbSections luffH[h] = head; leechH[h] = peak; seamH[h] = gaffLine; /* Create arrays of points on luff and leech catenaries * Luff and leech catenaries are the lines going from each side * of the middle panel of the gaff to the tack and clew. * They separate the surface of the sail in 3 zones: * the luff zone, the central zone and the leech zone. * The luff and leech zone have the same number of radial * panels from top to bottom while in the central zone * the number of panels increase by one at each section. */ CPoint3d luffCatenary[11] , leechCatenary[11]; // top point on luff catenary pt0 = head + gaffV * ( real(ngLuff) / real(nbGores) ); luffCatenary[nbSections] = pt0; // top point on leech catenary pt0 = head + gaffV * ( real(ngLuff+1) / real(nbGores) ); leechCatenary[nbSections] = pt0; // top of leech catenary // other points on both catenaries for (h = nbSections-1 ; h > 0 ; h--) { pt0 = tack + footV*(real(h) / real(nbSections))*(real(ngLuff) / real(nbGores)); seamL = CSubSpace::line(luffCatenary[h+1], CVector3d(pt0 - luffCatenary[h+1])); luffCatenary[h] = seamH[h].intersectionPoint(seamL, "luffCatenary"); pt0 = clew - footV*(real(h) / real(nbSections))*(real(nbGores-ngLuff) / real(nbGores)); seamL = CSubSpace::line(leechCatenary[h+1], CVector3d(pt0 - leechCatenary[h+1])); leechCatenary[h] = seamH[h].intersectionPoint(seamL, "leechCatenary"); } h = 0; luffCatenary[h] = tack; leechCatenary[h] = clew; /* Now we cut the radial panels * Panels are oriented with lower and upper edges on vertical catenary * Bottom side is on luff side and top side is on leech side * Left side is at the top of each section * p1 p2 are the end point of bottom side with * p1 = top of horizontal section, p2 = bottom of horizontal section * The seams between sections are twice the normal seam width */ npanel = 0; ng1 = 0; // initialise number of central panels /** Lay the panels from the top section downward to the foot section. */ for (h = nbSections; h > 0; h--) { nps[h] = 0; // counter of panels in current section /* Cutting the luff side panels * which are left of the catenary separating the vertical zones */ for (j = 1; j <= ngLuff; j++) { if ( j == 1 ) { // place bottom end points on luff catenary pt1 = luffH[h]; pt2 = luffH[h-1]; lay[npanel].bottom.fill( pt1, pt2 ); for (k = 1 ; k < npb -1 ; k++) lay[npanel].bottom[k] = EdgeIntersect( LUFF_EDGE, lay[npanel].bottom[k] , CVector3d( luffH[h-1] - leechH[h-1] ) ); } else { // copy previous points pt1 = pt3; pt2= pt4; lay[npanel].bottom.fill( pt1, pt2 ); } // we compute the top end points pt3 = luffH[h] + CVector3d( luffCatenary[h] - luffH[h] ) * (real(j) / ngLuff); if ( h == nbSections ) pt3 = EdgeIntersect( GAFF_EDGE, pt3, gaffVP ); pt4 = luffH[h-1] + CVector3d( luffCatenary[h-1] - luffH[h-1] ) * (real(j) / ngLuff); // we fill the other edges lay[npanel].top.fill( pt3 , pt4 ); lay[npanel].left.fill( pt1 , pt3 ); lay[npanel].right.fill( pt2 , pt4 ); if ( h == nbSections ) { for (k = 1; k < npl -1; k++) lay[npanel].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel].left[k] , gaffVP ); } // We compute Z lay[npanel] = Zpanel(lay[npanel]); // We develop the current panel dev[npanel] = lay[npanel].develop(ALIGN_TOP); // We add the seams and hems allowance if ( h == nbSections ) { if ( j == 1 ) dev[npanel].addHems(hemsW, seamW, 0, hemsW); else dev[npanel].addHems(hemsW, seamW, 0, 0); } else if ( j == 1 ) dev[npanel].addHems(2*seamW, seamW, 0, hemsW); else dev[npanel].addHems(2*seamW, seamW, 0, 0); nps[h]++; npanel++; } /* Cut the middle panels which are between the * vertical catenaries luff and leech sides. */ if ( h > 1 ) { ng1++; // we add one more central panel than section above a = int(floor(real(ng1) / 2) ); b = int(ceil(real(ng1) / 2) ); // we initialise the bottom end points pt3 = luffCatenary[h]; if ( h == nbSections ) pt3 = EdgeIntersect( GAFF_EDGE, pt3 , gaffVP ); pt4 = luffCatenary[h-1]; // we now compute the other points for (j = 1; j <= ng1; j++) { pt1 = pt3; pt2 = pt4; pt4 = luffCatenary[h-1] + CVector3d( leechCatenary[h-1] - luffCatenary[h-1] ) * (real(j) / ng1); if ( ng1 < 4 ) { pt3 = luffCatenary[h] + CVector3d( leechCatenary[h] - luffCatenary[h] ) * (real(j) / ng1); if ( h == nbSections ) pt3 = EdgeIntersect( GAFF_EDGE, pt3 , gaffVP ); } else { if ( j < a ) // before middle point { pt3 = luffCatenary[h] + CVector3d( leechCatenary[h] - luffCatenary[h] ) * (real(j) / (ng1-1)); } else if ( j > b ) // after middle point { pt3 = luffCatenary[h] + CVector3d( leechCatenary[h] - luffCatenary[h] ) * (real(j-1) / (ng1-1)); } else { pt3 = luffCatenary[h] + CVector3d( leechCatenary[h] - luffCatenary[h] ) * (real(j) / ng1); } } // we fill the 4 edges lay[npanel].left.fill( pt1 , pt3 ); lay[npanel].right.fill( pt2 , pt4 ); lay[npanel].bottom.fill( pt1 , pt2 ); lay[npanel].top.fill( pt3 , pt4 ); if ( h == nbSections ) { for (k = 1; k < npl-1; k++) lay[npanel].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel].left[k] , gaffVP ); } // Now we go over all the points and calculate their z lay[npanel] = Zpanel(lay[npanel]); // We develop the current panel dev[npanel] = lay[npanel].develop(ALIGN_TOP); // We add the seams and hems allowance if ( h == nbSections ) dev[npanel].addHems(hemsW, seamW, 0, 0); else dev[npanel].addHems(2*seamW, seamW, 0, 0); nps[h]++; npanel++; } } else // h = 1 middle panels of bottom section { // luff side central for (j = 1; j <= (ng1 / 2); j++) { pt1 = luffCatenary[h] + CVector3d( leechCatenary[h] - luffCatenary[h] ) * (real(j-1) / ng1); pt2 = tack; pt3 = luffCatenary[h] + CVector3d( leechCatenary[h] - luffCatenary[h] ) * (real(j) / ng1); pt4 = pt2; ptCentre = pt3; // memorise last point on horizontal seam 1 lay[npanel].left.fill(pt1 , pt3); lay[npanel].right.fill(pt2 , pt4); lay[npanel].bottom.fill(pt1 , pt2); lay[npanel].top.fill(pt3 , pt4); // compute Z lay[npanel] = Zpanel(lay[npanel]); // We develop the current panel dev[npanel] = lay[npanel].develop(ALIGN_TOP); // We add the seams allowance dev[npanel].addHems(2*seamW, seamW, 0, 0); nps[h]++; npanel++; } // luff side lower central pt0 = ( luffCatenary[nbSections] + leechCatenary[nbSections] ) * 0.5; ptFoot = EdgeIntersect( FOOT_EDGE, ptCentre , CVector3d(ptCentre - pt0) ); a = int( (CVector3d (ptFoot - ptCentre).length()) / (clothW) ); if (a < 2) a = 2; for (j = 1 ; j <= a ; j++) { // from center to foot pt1 = ptCentre + CVector3d (ptFoot - ptCentre) * (real(j-1) / a); pt2 = tack; pt3 = ptCentre + CVector3d (ptFoot - ptCentre) * (real(j) / a); pt4 = pt2; lay[npanel].left.fill( pt1 , pt3 ); lay[npanel].right.fill( pt2 , pt4 ); lay[npanel].bottom.fill( pt1 , pt2 ); lay[npanel].top.fill( pt3 , pt4 ); if ( j == a ) { for (k = 0; k < lay[npanel].top.size(); k++) lay[npanel].top[k] = EdgeIntersect(FOOT_EDGE, lay[npanel].top[k], CVector3d(ptFoot - ptCentre)); } // compute Z lay[npanel] = Zpanel(lay[npanel]); // We develop the current panel dev[npanel] = lay[npanel].develop(ALIGN_TOP); // We add the seams and hems allowance if ( j == a ) dev[npanel].addHems(seamW, footHemW, 0, 0); else dev[npanel].addHems(seamW, seamW, 0, 0); nps[h]++; npanel++; } // leech side lower central for (j = 1; j <= a; j++) { // from foot to center pt1 = ptFoot + CVector3d ( ptCentre - ptFoot ) * (real(j-1) / a ); pt2 = clew; pt3 = ptFoot + CVector3d ( ptCentre - ptFoot ) * (real(j) / a); pt4 = pt2; lay[npanel].left.fill( pt1, pt3 ); lay[npanel].right.fill( pt2, pt4 ); lay[npanel].bottom.fill( pt1, pt2 ); lay[npanel].top.fill( pt3, pt4 ); if ( j == 1 ) { for (k = 0; k < lay[npanel].bottom.size(); k++) lay[npanel].bottom[k] = EdgeIntersect(FOOT_EDGE, lay[npanel].bottom[k], CVector3d(ptFoot - ptCentre)); } // compute Z lay[npanel] = Zpanel(lay[npanel]); // We develop the current panel dev[npanel] = lay[npanel].develop(ALIGN_TOP); // We add the seams and hems allowance if ( j == 1 ) dev[npanel].addHems(0, seamW, 0, footHemW); else dev[npanel].addHems(0, seamW, 0, 0); nps[h]++; npanel++; } // leech side central for (j = ng1/2 +1 ; j <= ng1 ; j++) { pt1 = luffCatenary[h] + CVector3d( leechCatenary[h] - luffCatenary[h] ) * (real(j-1) / ng1); pt2 = clew ; pt3 = luffCatenary[h] + CVector3d( leechCatenary[h] - luffCatenary[h] ) * (real(j) / ng1); pt4 = pt2; lay[npanel].left.fill( pt1, pt3 ); lay[npanel].right.fill( pt2, pt4 ); lay[npanel].bottom.fill( pt1, pt2 ); lay[npanel].top.fill( pt3, pt4 ); // compute Z lay[npanel] = Zpanel(lay[npanel]); // We develop the current panel dev[npanel] = lay[npanel].develop(ALIGN_TOP); // We add the seams allowance dev[npanel].addHems(2*seamW, seamW, 0, 0); nps[h]++; npanel++; } } /* Cut the leech side panels */ for (j = 1; j < (nbGores - ngLuff); j++) { pt1 = leechCatenary[h] + CVector3d( leechH[h] - leechCatenary[h] ) * (real(j-1) / (nbGores - ngLuff -1) ); if ( h == nbSections ) pt1 = EdgeIntersect( GAFF_EDGE, pt1, gaffVP ); pt2 = leechCatenary[h-1] + CVector3d( leechH[h-1] - leechCatenary[h-1] ) * (real(j-1) / (nbGores - ngLuff -1) ); pt3 = leechCatenary[h] + CVector3d( leechH[h] - leechCatenary[h] ) * (real(j) / (nbGores - ngLuff -1) ); if ( h == nbSections ) pt3 = EdgeIntersect( GAFF_EDGE, pt3, gaffVP ); pt4 = leechCatenary[h-1] + CVector3d( leechH[h-1] - leechCatenary[h-1] ) * (real(j) / (nbGores - ngLuff -1) ); lay[npanel].bottom.fill( pt1, pt2 ); lay[npanel].top.fill( pt3, pt4 ); lay[npanel].left.fill( pt1, pt3 ); lay[npanel].right.fill( pt2, pt4 ); if ( h == nbSections ) { for (k = 1; k < npl -1; k++) lay[npanel].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel].left[k] , gaffVP ); } if ( j == nbGores - ngLuff -1) { for (k = 1; k < npb -1; k++) lay[npanel].top[k] = EdgeIntersect( LEECH_EDGE, lay[npanel].top[k] , CVector3d(luffH[h-1]-leechH[h-1]) ); } // we compute Z lay[npanel] = Zpanel(lay[npanel]); // We develop the current panel dev[npanel] = lay[npanel].develop(ALIGN_TOP); // We add the seams and hems allowance if ( h == nbSections ) { if ( j == nbGores - ngLuff -1 ) dev[npanel].addHems(hemsW, leechHemW, 0, 0); else dev[npanel].addHems(hemsW, seamW, 0, 0); } else if (j == nbGores - ngLuff -1) dev[npanel].addHems(2*seamW, leechHemW, 0, 0); else dev[npanel].addHems(2*seamW, seamW, 0, 0); nps[h]++; npanel++; } } /* Copy 3d lay into 3d sail */ CPanelGroup sail(npanel); for (j = 0 ; j < npanel ; j ++) sail[j] = lay[j]; /* Copy from temporary developed sail into flatsail */ flatsail = CPanelGroup(npanel); for (j = 0; j < npanel; j++) flatsail[j] = dev[j]; /* Prepare the displays version of the developed sail */ dispsail = flatsail; j = 0, h = nbSections, k = 0; v = CVector3d(0,0,0); xp = 0; xm = 0; ym = 0; for (j = 0; j < npanel; j++) { if ( k == nps[h] ) { // decrement section and offset x h--; k = 0; xp = xm + 2*seamW +20; // offset for next section v.setX(xp); v.setY(0); } // translation v to stack panel above previous panel dispsail[j] = dispsail[j] + v; CRect3d pRect = dispsail[j].boundingRect(); ym = pRect.height(); v.setY(v.y() + ym + 2 * seamW + 20); // adding offset to separate next panel vertically x = pRect.max.x(); if ( x > xm ) xm = x; k++; } return sail; } /* end layout radial cut ///////////// */ /** Creates a triradial cut sail. //// NOT USED //// * * @param flatsail the CPanelGroup object that will hold the developed sail * @param dispsail the CPanelGroup object that will hold the display * version of the developed sail * @return CPanelGroup */ CPanelGroup CSailWorker::LayoutTriRadial( CPanelGroup &flatsail, CPanelGroup &dispsail ) const { unsigned int h=0, j=0, k=0, a=1, b=1; unsigned int ngLuff = nbGores/2; // limit of luff gores unsigned int ng1=0; // number of central panels //bool flag=false; real x=0, xm=0, xp=0, ym=0; CPoint3d pt0, pt1, pt2, pt3, pt4, ptCentre, ptFoot; // points /* Create two temporary sails lay and the corresponding dev */ CPanelGroup lay(MAX_PANELS); // 3D sail CPanelGroup dev(MAX_PANELS); // developed sail /* create number of panels */ unsigned int npanel=1; unsigned int npl= lay[0].right.size(); // number of right/left points unsigned int npb= lay[0].bottom.size(); // number of bottom/top points unsigned int nps[10]; // number of panels per sections /* create variables for the development and edge corrections */ CPoint3d top(0, 0, 0); CPoint3d bot(0, 0, 0); CVector3d v(0, 0, 0); CVector3d vb(0, 0, 0); CVector3d vk(0, 0, 0); /* create variable for edge correction */ std::vector deviation; deviation.resize(npb); /* Create arrays of points at horizontal seams ends 10 maximum */ CPoint3d luffH[10]; // point at the luff end of the horizontal seam CPoint3d leechH[10]; // point at the leech end of the horizontal seam CSubSpace seamH[10]; // corresponding seam lines CSubSpace seamL; // a seam line for (h=0; h 0; h--) { pt0 = tack + footV*(real(h) / real(2* nbSections)); seamL = CSubSpace::line(luffCatenary[h+1], CVector3d(pt0 - luffCatenary[h+1])); luffCatenary[h] = seamH[h].intersectionPoint(seamL, "luffCatenary"); pt0 = clew - footV*(real(h) / real(2* nbSections)); seamL = CSubSpace::line(leechCatenary[h+1], CVector3d(pt0 - leechCatenary[h+1])); leechCatenary[h] = seamH[h].intersectionPoint(seamL, "leechCatenary"); } h = 0; luffCatenary[h] = tack; leechCatenary[h] = clew; /* Now cutting the radial panels. * Panels are oriented with lower edge vertical toward luff * and left side at the top of each section */ npanel = 0; ng1 = 0; // initialise number of central panels for (h = nbSections; h>0; h--) { /** Lay the panels from top section downward */ nps[h]=0; // counter of panels in current section /* cutting the luff side panels */ for (j=1; j<=ngLuff; j++) { if (j == 1) { pt1 = luffH[h]; pt2 = luffH[h-1]; lay[npanel].bottom.fill(pt1 , pt2); for (k=1; k 1 ) { ng1++; // add one more central panel than section above a = int(floor(real(ng1)/2)); b = int(ceil(real(ng1)/2)); pt3 = luffCatenary[h]; if (h == nbSections) pt3 = EdgeIntersect( GAFF_EDGE, pt3, gaffVP ); pt4 = luffCatenary[h-1]; for (j=1; j<=ng1; j++) { pt1 = pt3; pt2 = pt4; pt4 = luffCatenary[h-1] + CVector3d(leechCatenary[h-1]-luffCatenary[h-1])*(real(j)/ng1); if (ng1 < 4) { pt3 = luffCatenary[h] + CVector3d(leechCatenary[h]-luffCatenary[h])*(real(j)/ng1); if (h == nbSections) pt3 = EdgeIntersect( GAFF_EDGE, pt3, gaffVP ); } else { if (j < a) { pt3 = luffCatenary[h] + CVector3d(leechCatenary[h]-luffCatenary[h])*(real(j)/(ng1-1)); } else if (j > b ) { pt3 = luffCatenary[h] + CVector3d(leechCatenary[h]-luffCatenary[h])*(real(j-1)/(ng1-1)); } else { pt3 = luffCatenary[h] + CVector3d(leechCatenary[h]-luffCatenary[h])*(real(j)/ng1); } } lay[npanel].left.fill(pt1 , pt3); lay[npanel].right.fill(pt2 , pt4); lay[npanel].bottom.fill(pt1 , pt2); lay[npanel].top.fill(pt3 , pt4); if (h == nbSections) { for (k=1; k xm) xm = x; k++; } return sail; } /* end LayoutTriRadial cut ///////// NOT USED /////////// */ /** Creates a mitre cut sail with panels perpendicular to Leech and Foot. * * @param flatsail the CPanelGroup object that will hold the developed sail * @param dispsail the CPanelGroup object that will hold the display * version of the developed sail * @return CPanelGroup */ CPanelGroup CSailWorker::LayoutMitre( CPanelGroup &flatsail, CPanelGroup &dispsail ) const { /* First create arrays p1 and p2 of points at the end of each seams * located on the straight edge of the sail (no round) */ CPoint3d p1[MAX_PANELS], p2[MAX_PANELS]; /* Create two temporary sails lay and the corresponding dev */ CPanelGroup lay(MAX_PANELS); // 3D sail CPanelGroup dev(MAX_PANELS); // developed sail /* create number of panels */ unsigned int npanelFoot = 1, npanel = 1; unsigned int npl= lay[0].right.size(); // number of right/left points unsigned int npb= lay[0].bottom.size(); // number of bottom/top points unsigned int j = 0, k = 0, cnt = 0; bool flag = false; /* create arrays t1 and t2 of type of intersection * respectively at points p1 on luff side and p2 on leech side */ IntersectionType t1[MAX_PANELS], t2[MAX_PANELS]; /* define point ip for intersections */ CPoint3d ip; /* seam Line */ CSubSpace seamL; /* create variables for the development and edge corrections */ CPoint3d pt(0, 0, 0); // test point CPoint3d top(0, 0, 0); CPoint3d bot(0, 0, 0); CVector3d v(0, 0, 0); CVector3d vb(0, 0, 0); CVector3d vk(0, 0, 0); /* create variable for edge correction */ std::vector deviation; deviation.resize(npb); std::vector deviaPrev; deviaPrev.resize(npb); /** Mitre Hem Width is set at twice the Seam Width. */ real mitreHemW = 2 * seamW; /* Other edge hem width */ real luffHemW = hemsW; // real luffInnerHemW, footInnerHemW; /* seam 0 is on the foot of the sail ending at the clew */ p1[0] = clew; // initialised at clew point p2[0] = clew; t1[0] = FootIntersection; t2[0] = MitreIntersection; /** First Cut the foot panels perpendicular to the foot, * starting at the clew and moving toward the tack. */ for ( npanel = 1 ; npanel < (MAX_PANELS / 2) -1 ; npanel++ ) { real exb = 0; // total correction real exc = 0; // current excess of width cnt = 0; /* Loop for optimising the seam position to fit cloth width */ do { cnt++; // move base point along the foot pt = p1[npanel-1] - (clothW - seamW - exb) * footV.normalized(); seamL = CSubSpace::line( pt , footVP ); p1[npanel] = seamL.intersectionPoint(footLine, "seam and foot"); t1[npanel] = FootIntersection; if ( p1[npanel].x() <= tack.x() ) { // last panel p1[npanel] = tack; if (t2[npanel-1] == MitreIntersection) { p2[npanel] = mitreLuffPt; t2[npanel] = MitreIntersection; } else { p2[npanel] = tack; t2[npanel] = LuffIntersection; } flag = true; // set to get out of FOR } else { // normal panel p2[npanel] = seamL.intersectionPoint(mitreLine, "seam and mitre"); if (CVector3d::dotProduct(p2[npanel] - mitreLuffPt, mitreV) > EPS) { t2[npanel] = LuffIntersection; p2[npanel] = seamL.intersectionPoint(luffLine, "seam and luff"); } else { t2[npanel] = MitreIntersection; } } // fill right side points if (t2[npanel-1] == LuffIntersection && t2[npanel] == LuffIntersection) { lay[npanel-1].right.fill(p2[npanel-1] , p2[npanel]); for (k=0; k 0 && cnt < 9 ); /* loop as long the excess of width is positive AND counter < 9 */ deviaPrev = deviation; /* Now we reposition the developed panel such that bottom left is X=0 Y=0 */ dev[npanel-1].reframe(); /* check if peak has been reached to break off */ if ( flag == true ) break; } /* Loop FOR next foot panel seam /////////// */ /* Store the number of panels in foot */ npanelFoot = npanel; if (npanel == MAX_PANELS/2 -1) throw layout_error("CSailWorker::LayoutMitre -5 : Foot got to MAX_PANELS/2 without reaching tack, do increase cloth width."); p1[npanel] = clew; // re-initialising at clew point p2[npanel] = clew; t1[npanel] = MitreIntersection; t2[npanel] = LeechIntersection; /** Then lay the leech panels perpendicular to the leech, * starting from clew and moving upwards to the peak. */ flag = false; for ( npanel = npanel +1 ; npanel < MAX_PANELS -1 ; npanel++ ) { real exb = 0; // total correction real exc = 0; // current excess of width cnt = 0; // reset counter of iterations /* Loop for optimising the seam position to fit cloth width */ do { cnt++; p2[npanel] = p2[npanel-1] + (clothW -seamW -exb) * leechV.normalized(); t2[npanel] = LeechIntersection; seamL = CSubSpace::line(p2[npanel] , leechVP); if (CVector3d::dotProduct(p2[npanel] - peak, leechV) >= 0) { // we are above peak, stop last panel flag = true; p2[npanel] = peak; // check on which side of the sail the previous point p1 is located if ( t1[npanel-1] == MitreIntersection ) { // previous seam on mitre p1[npanel] = head; t1[npanel] = LuffIntersection; // left points on mitrePt-head lay[npanel-1].left.fill(p1[npanel-1] , mitreLuffPt , p1[npanel]); for (k = npl/2 +1 ; k < npl ; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], leechVP); } else if ( t1[npanel-1] == LuffIntersection ) { // left points on luff p1[npanel] = head; t1[npanel] = LuffIntersection; lay[npanel-1].left.fill(p1[npanel-1], p1[npanel]); for (k=0; k 0) { // seam intersects gaff p1[npanel] = seamL.intersectionPoint(gaffLine, "seam and gaff"); t1[npanel] = GaffIntersection; } else { // seam intersects luff p1[npanel] = ip; t1[npanel] = LuffIntersection; } } /* We now add intermediate points on all sides of the normal panel */ /* Below is the code for the left side depending * on t1 for the top side and bottom side */ if ( t1[npanel-1] == LuffIntersection && t1[npanel] == LuffIntersection ) { // full luff lay[npanel-1].left.fill(p1[npanel-1] , p1[npanel]); for (k = 0 ; k < npl ; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], leechVP); } else if ( t1[npanel-1] == GaffIntersection && t1[npanel] == GaffIntersection ) { // full gaff lay[npanel-1].left.fill(p1[npanel-1] , p1[npanel]); for (k = 0 ; k < npl ; k++) lay[npanel-1].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].left[k] , leechVP); } else if ( t1[npanel-1] == LuffIntersection && t1[npanel] == GaffIntersection ) { // luff-head-gaff lay[npanel-1].left.fill(p1[npanel-1] , head , p1[npanel]); for (k = 0 ; k < npl/2 ; k++) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k] , leechVP); for (k = npl/2 +1 ; k < npl ; k++) lay[npanel-1].left[k] = EdgeIntersect( GAFF_EDGE, lay[npanel-1].left[k] , leechVP); } else if ( t1[npanel-1] == MitreIntersection && t1[npanel] == LuffIntersection ) { // mitre-luff lay[npanel-1].left.fill(p1[npanel-1] , mitreLuffPt , p1[npanel]); for (k = 0 ; k < npl/2 ; k++) lay[npanel-1].left[k] = MitreIntersect(lay[npanel-1].left[k] , leechVP); for (k=npl/2+1; k 0 && cnt < 9 ); /* loop as long the excess of width is positive AND counter < 9 */ for (k = 0 ; k < npb ; k++) deviaPrev[k] = deviation[k]; /* Now we reposition the developed panel such that bottom left is X=0 Y=0 */ dev[npanel-1].reframe(); /* check if peak has been reached to break off */ if ( flag == true ) break; } /* loop FOR next seam of leech panels */ if ( npanel == MAX_PANELS-1 ) throw layout_error("CSailWorker::LayoutMitre -3 : Leech got to MAX_PANELS without reaching head, you need to increase cloth width "); /* Copy the sails for display */ CPanelGroup sail(npanel); for (j = 0; j < npanel; j++) sail[j] = lay[j]; /* Copy the developed sail into flatsail */ flatsail = CPanelGroup(npanel); for (j = 0 ; j < npanel ; j++) flatsail[j] = dev[j]; dispsail = prepareDisplaySail(flatsail, 2 * seamW + 10); return sail; } /* end layoutMitre cut //////////////////// */ /** Creates a Mitre 2 cut sail with panels Parallel to Leech & Foot. * * @param flatsail the CPanelGroup object that will hold * the developed sail * @param dispsail the CPanelGroup object that will hold * the display version of the developed sail * @return CPanelGroup */ CPanelGroup CSailWorker::LayoutMitre2( CPanelGroup &flatsail, CPanelGroup &dispsail ) const { /* First create arrays p1 and p2 of points at the end of each seams * located on the straight edge of the sail (no round) */ CPoint3d p1[MAX_PANELS], p2[MAX_PANELS]; /* Create two temporary sails lay and the corresponding dev */ CPanelGroup lay(MAX_PANELS); // 3D sail CPanelGroup dev(MAX_PANELS); // developed sail /* create number of panels */ unsigned int npanelFoot = 1, npanel = 1; unsigned int npl = lay[0].right.size(); // number of right/left points unsigned int npb = lay[0].bottom.size(); // number of bottom/top points unsigned int j = 0, k = 0, cnt = 0, cntMax = 9; bool flag = false; /* create arrays t1 and t2 of type of intersection * respectively at points p1 on luff side and p2 on leech side */ IntersectionType t1[MAX_PANELS], t2[MAX_PANELS]; /* define point ip for intersections */ CPoint3d ip; /* define seam line */ CSubSpace seamL; /* create variables for the development and edge corrections */ CPoint3d pt(0, 0, 0); // test point CPoint3d top(0, 0, 0); CPoint3d bot(0, 0, 0); CVector3d v(0, 0, 0); CVector3d vb(0, 0, 0); CVector3d vk(0, 0, 0); /* create variable for edge correction */ std::vector deviation; deviation.resize(npb); std::vector deviaPrev; deviaPrev.resize(npb); /* create variable to monitor excess over cloth width */ real exb = 0, exc = 0; /** Mitre Hem Width is set at twice the Seam Width. */ real mitreHemW = 2 * seamW; /* Other edge hem */ real luffHemW = hemsW; // real luffInnerHemW, footInnerHemW; /** Start by laying the foot panels parallel to the foot, * from the foot upward toward the mitre */ p1[0] = tack; // initialised at clew point p2[0] = clew; // initialised at tack point t1[0] = LuffIntersection; t2[0] = MitreIntersection; for ( npanel = 1; npanel < MAX_PANELS/2-1; npanel++ ) { // std::cout << " ----- FOR LOOP foot npanel = " << npanel << std::endl; exb = 0; exc = 0; cnt = 0; // reset counter /* begin the loop for optimising the seam position to fit cloth width */ do { cnt++; // move base point perpendicular to foot pt = p1[npanel-1] + (clothW -seamW -exb) * footVP.normalized(); seamL = CSubSpace::line( pt, footV ); // find intersection on luff and mitre p1[npanel] = seamL.intersectionPoint(luffLine, "seam and luff"); t1[npanel] = LuffIntersection; p2[npanel] = seamL.intersectionPoint(mitreLine, "seam and mitre"); t1[npanel] = MitreIntersection; // check if top seam is past luff mitre point if (CVector3d::dotProduct(p2[npanel] - mitreLuffPt, mitreV) > EPS) { // last foot panel is meeting Mitre luff point p1[npanel] = mitreLuffPt; p2[npanel] = p2[npanel-1]; // new top edge on mitre // old code p2[npanel] = mitreLuffPt; t2[npanel] = LuffIntersection; flag = true; // set to get out of FOR loop } // fill right side points which are all on mitre lay[npanel-1].right.fill( p2[npanel-1], p2[npanel] ); for ( k = 0; k < npl; k++ ) lay[npanel-1].right[k] = MitreIntersect( lay[npanel-1].right[k], footV ); // fill left side points which are all on luff lay[npanel-1].left.fill( p1[npanel-1], p1[npanel] ); for ( k = 0; k < npl; k++ ) lay[npanel-1].left[k] = EdgeIntersect( LUFF_EDGE, lay[npanel-1].left[k], footV ); // fill bottom points lay[npanel-1].bottom.fill( lay[npanel-1].left[0], lay[npanel-1].right[0] ); if ( npanel == 1 ) { // bottom is on the foot for ( k = 0; k < npb; k++ ) lay[npanel-1].bottom[k] = EdgeIntersect( FOOT_EDGE,lay[npanel-1].bottom[k], footVP ); } // fill top side points on seam lay[npanel-1].top.fill( lay[npanel-1].left[npl-1], lay[npanel-1].right[npl-1] ); /* Now we go over all the points and calculate their Z */ lay[npanel-1] = Zpanel(lay[npanel-1]); /* Now we develop the current panel */ if ( npanel == 1 ) dev[npanel-1] = lay[npanel-1].develop(ALIGN_TOP); else { dev[npanel-1] = lay[npanel-1].develop(ALIGN_BOTTOM); // add deviation of previous panel top edge to bottom edge for( k = 1; k < npb-1; k ++) dev[npanel-1].bottom[k] = dev[npanel-1].bottom[k] + deviaPrev[k]; } /* Now we compute the deviation of top edge of developed panel * and straighten this top edge except if this is the top panel */ if ( flag == false ) { vb = rotateNormalized(M_PI/2, dev[npanel-1].top[npb-1] - dev[npanel-1].top[0]); for( k = 1; k < npb-1; k ++) { vk = CVector3d (dev[npanel-1].top[k] - dev[npanel-1].top[0]); v = vb * -CVector3d::dotProduct(vk, vb); deviation[k] = v; dev[npanel-1].top[k] = dev[npanel-1].top[k] + deviation[k]; } } /* Now we add the seam and hems allowance to the foot panels */ if ( npanel == 1 ) // Foot panel dev[npanel-1].add6Hems( luffHemW, luffHemW, seamW, mitreHemW, mitreHemW, footHemW ); else if ( flag == true ) // last foot section panel dev[npanel-1].add6Hems( luffHemW, luffHemW, mitreHemW, mitreHemW, 1.5*mitreHemW, 0 ); else // Normal Panel dev[npanel-1].add6Hems( luffHemW, luffHemW, seamW, mitreHemW, mitreHemW, 0 ); /* Now we check the width of developed panel */ exc = dev[npanel-1].boundingRect().height() - clothW; // current excess of width exb = exb + (0.8 * exc) +1; // sum previous correction + 80% of current excess of width +1mm if (cnt == cntMax) std::cout << "CSailcorker::LayoutMitre2 Foot panel " << npanel << " may be wider than cloth by " << exc << "mm." << std::endl; } while ( exc > 0 && cnt < cntMax ); /* Loop DO as long as the excess of width is positive AND counter <9 */ deviaPrev = deviation; /* Reposition the developed panel such that bottom left is X=0 Y=0 */ dev[npanel-1].reframe(); /* Check if peak has been reached to break off */ if ( flag == true ) break; } /* Loop FOR next seam */ /* Store the number of panels in the foot area */ npanelFoot = npanel; if ( npanelFoot == MAX_PANELS/2 -1 ) throw layout_error("CSailWorker::LayoutMitre2 : Foot got to MAX_PANELS/2 without reaching Mitre intersection at Luff. Please increase cloth width."); /** Continue by laying the leech panels parallel to the leech, * from the leech toward the luff intersection with the mitre. */ p1[npanel] = clew; // re-initialising at clew point. p2[npanel] = peak; // initialise at the peak. t1[npanel] = MitreIntersection; t2[npanel] = GaffIntersection; flag = false; for (npanel = npanelFoot+1; npanel < MAX_PANELS-1; npanel++) { // printf(" ----- FOR panel = %d \n" , npanel); exb = 0; exc = 0; cnt = 0; // reset loop counter /* begin the loop for optimising the seam position to fit cloth width */ do { cnt++; /* Determine width of Panel Perpendicular to Leech side. */ pt = p1[npanel-1] + (clothW -seamW -exb) * leechVP.normalized(); seamL = CSubSpace::line(pt, leechV); // find intersection on mitre p1[npanel] = seamL.intersectionPoint(mitreLine, "seam and mitre"); if ( p1[npanel].x() >= clew.x() ) // point beyong clew p1[npanel] = clew; t1[npanel] = MitreIntersection; // check if top seam is passed luff mitre point if (CVector3d::dotProduct(p1[npanel] - mitreLuffPt, mitreV) > EPS) { // last leech panel p1[npanel] = p1[npanel-1]; // new top edge on mitre // old code p1[npanel] = mitreLuffPt; t1[npanel] = MitreIntersection; p2[npanel] = mitreLuffPt; t2[npanel] = LuffIntersection; flag=true; // to get out of FOR } else { // printf ("normal panel \n"); p2[npanel] = seamL.intersectionPoint(gaffLine, "seam and gaff"); if (CVector3d::dotProduct(p2[npanel] - head, gaffV) > EPS) t2[npanel] = GaffIntersection; else { p2[npanel] = seamL.intersectionPoint(luffLine, "seam and luff"); t2[npanel] = LuffIntersection; } } // fill right side points if (t2[npanel-1] == LuffIntersection && t2[npanel] == LuffIntersection) { // std::cout << "CSailWorker::LayoutMitre2 full luff" << std::endl; lay[npanel-1].right.fill(p2[npanel-1], p2[npanel]); for ( k = 0; k < npl; k++ ) lay[npanel-1].right[k]=EdgeIntersect( LUFF_EDGE, lay[npanel-1].right[k], leechV); } else if (t2[npanel-1] == GaffIntersection && t2[npanel] == LuffIntersection) { // std::cout << "CSailWorker::LayoutMitre2 gaff-head-luff" << std::endl; lay[npanel-1].right.fill(p2[npanel-1], head, p2[npanel]); for ( k = 0; k < npl/2; k++ ) lay[npanel-1].right[k] = EdgeIntersect( GAFF_EDGE,lay[npanel-1].right[k], leechV); for ( k = npl/2+1; k < npl; k++ ) lay[npanel-1].right[k] = EdgeIntersect( LUFF_EDGE,lay[npanel-1].right[k], leechV); } else { // std::cout << "CSailWorker::LayoutMitre2 full gaff << std::endl; lay[npanel-1].right.fill(p2[npanel-1], p2[npanel]); for ( k = 0; k < npl; k++ ) lay[npanel-1].right[k] = EdgeIntersect( GAFF_EDGE,lay[npanel-1].right[k], leechV); } // fill left side points which are all on the mitre lay[npanel-1].left.fill(p1[npanel-1], p1[npanel]); if (!qFuzzyCompare(p1[npanel-1], p1[npanel])) { // clew limit for ( k = 0; k < npl; k++ ) lay[npanel-1].left[k] = MitreIntersect(lay[npanel-1].left[k], leechV); } // fill bottom points lay[npanel-1].bottom.fill(lay[npanel-1].left[0], lay[npanel-1].right[0]); if ( npanel == npanelFoot +1 ) { // bottom is on the leech for ( k = 0; k < npb; k++ ) lay[npanel-1].bottom[k] = EdgeIntersect( LEECH_EDGE,lay[npanel-1].bottom[k], leechVP); } // fill top side points on seam lay[npanel-1].top.fill(lay[npanel-1].left[npl-1], lay[npanel-1].right[npl-1]); /* Now we go over all the points and calculate their z */ lay[npanel-1] = Zpanel(lay[npanel-1]); /* Now we develop the current panel */ if ( npanel == npanelFoot +1 ) dev[npanel-1] = lay[npanel-1].develop(ALIGN_TOP); else { dev[npanel-1] = lay[npanel-1].develop(ALIGN_BOTTOM); // add deviation of previous panel top edge to bottom edge for( k = 1; k < npb-1; k ++) dev[npanel-1].bottom[k] = dev[npanel-1].bottom[k] + deviaPrev[k]; } /* Now we compute the deviation of top edge of developed panel * and straighten this top edge except if this is the top panel */ if ( flag == false ) { vb = rotateNormalized(M_PI/2, dev[npanel-1].top[npb-1] - dev[npanel-1].top[0]); for( k = 1; k < npb-1; k++ ) { vk = CVector3d (dev[npanel-1].top[k] - dev[npanel-1].top[0]); v = vb * -CVector3d::dotProduct(vk, vb); deviation[k] = v; dev[npanel-1].top[k] = dev[npanel-1].top[k] + deviation[k]; } } /* Now we add the seam and hems allowance to the leech panels*/ if ( npanel == npanelFoot +1 ) dev[npanel-1].add6Hems( 0, 0, seamW, hemsW, hemsW, leechHemW ); else if( flag == true ) dev[npanel-1].add6Hems( 0, 0, 0, luffHemW, luffHemW, 0 ); // old code dev[npanel-1].add6Hems( 0, 0, luffHemW, hemsW, hemsW, 0 ); else dev[npanel-1].add6Hems( 0, 0, seamW, hemsW, hemsW, 0 ); /* Now we check the width of developed panel and correct for the next loop */ exc = dev[npanel-1].boundingRect().height() - clothW; exb = exb + (0.8 * exc) + 1; // sum previous correction + 80% of current excess of width +1mm if (cnt == cntMax) std::cout << "CSailWorker::LayoutMitre2 Leech panel " << npanel << " may be wider than cloth by " << exc << "mm." << std::endl; } while ( exc > 0 && cnt < cntMax ); /* loop DO as long as the excess of width is positive AND counter <9 */ deviaPrev = deviation; /* Now we reposition the developed panel such that bottom left is X=0 Y=0 */ dev[npanel-1].reframe(); /* check if peak has been reached to break off */ if ( flag == true ) break; } /* Loop FOR next seam */ if ( npanel == MAX_PANELS -1 ) throw layout_error("CSailWorker::LayoutMitre2 -f : MAX_PANELS without reaching Miter Intersect Point at Luff. Please increase cloth width."); /* Copy the sails for display */ CPanelGroup sail(npanel); for( j = 0; j < npanel; j++ ) sail[j] = lay[j]; /* Copy the developed sail into flatsail */ flatsail = CPanelGroup(npanel); for ( j = 0; j < npanel; j++ ) flatsail[j] = dev[j]; /* Prepare the displays version of the developed sail */ dispsail = flatsail; for ( j = 1; j < npanel; j++ ) { top = dispsail[j-1].top[0]; bot = dispsail[j].bottom[0]; // translation v to align panel bottom edge origin to previous panel upper edge origin v = top; v.setX(v.x() - bot.x()); v.setY(v.y() + 2 * seamW + 10); // adding offset to separate panels vertically dispsail[j] = dispsail[j] + v; } return sail; } /* end LayoutMitre2 ////////////////// */ /** Routine used for computing the cord of the profiles. * Return a 3d point which is the aft intersection of * the horizontal line passing by p1 with the leech. * If the point p1 is above or below the leech segment then * the aft intersection is forced to be on the vertical of the * corresponding peak or clew. */ CPoint3d CSailWorker::AftIntersect( const CPoint3d& pt1 ) const { // real x=0, y=0, z=0; // for debugging only CPoint3d pAft = pt1; // aft intersection point is initialised at p1 CVector3d vH = CVector3d( 1, 0, 0 ); if ( pt1.y() >= peak.y() ) { // rear point above the peak, set output on vertical above peak pAft.setX(peak.x()); } else if ( pt1.y() <= clew.y() ) { // rear point on or below the clew, set output on vertical below clew pAft.setX(clew.x()); } else { // move point on leech which is not straight pAft = EdgeIntersect( LEECH_EDGE, pt1, vH ); } // ensure that Z=0 pAft.setZ(0); // return pAft; } /** * Routine for computing the area of the sail taking * into account the luff and leech round. */ real CSailWorker::Area() { real surface = CVector3d::crossProduct(luffV, footV).length() / 2; surface = surface + CVector3d::crossProduct(leechV, gaffV).length() / 2; surface = surface + .75*(luffL*luffR + footL*footR + leechL*leechR + gaffL*gaffR); /// round down the sail area to cm2 and return it in m2 return ( .0001 * floor(surface/100) ); } /** * Routine for computing the diagonal length from head to clew. */ real CSailWorker::Diagonal() { return floor( CVector3d(head-clew).length() ); } /** * Routine for computing the width of the sail at a given * relative height on the leech in accordance with IRC rule. */ real CSailWorker::IRCwidth( const real &HL ) { unsigned int i, imax=10; real h1=0, h2=0, LL=0, l1=0, w=0; CPoint3d p, p1, p2, p3; //printf ("IRC height = %f \n", HL); /// compute the leech edge length LL h1 = 1; LL = LeechLength( h1 ); //printf ("IRC leech length = %f \n", LL); /* compute the point on leech for relative length HL */ h2 = HL; //do { h1 = h2; l1 = LeechLength(h1); h2 = h1 * (1-(l1 - LL*HL)/(LL*HL)); //printf (" HL=%f l1=%f h1=%f - h2=%f \n", HL, l1, h1, h2); h1 = h2; l1 = LeechLength(h1); h2 = h1 * (1-(l1 - LL*HL)/(LL*HL)); //printf (" HL=%f l1=%f h1=%f - h2=%f \n", HL, l1, h1, h2); } //while ( fabs(h1-h2)>.001 ); /* compute the shortest distance to the real luff */ p1 = clew + leechV*h2; p2 = Zpoint(EdgeIntersect( LEECH_EDGE, p1, leechVP)); p1 = Zpoint(EdgeIntersect( LUFF_EDGE, p2, luffVP)); w = 0; p3 = p1; for (i = 1; i <= imax; i++) { h1 = real(i) / imax; p = Zpoint(p1 +CVector3d(p2 - p1) * h1); w = w + CVector3d(p - p3).length(); p3 = p; } return ( w ); } /** * Routine for computing the width of the sail at a given * relative height on the luff and the leech. */ real CSailWorker::SailWidth( const real &HL ) { unsigned int i, imax=10; real h=0, h1=0, h2=0, LeL=0, LuL=0, l1=0, w=0; CPoint3d p, p1, p2, p3; //printf ("IRC height = %f \n", HL); // compute the leech edge length LeL h = 1; LeL = LeechLength( h ); //printf ("IOR leech length = %f \n", LeL); /* compute the height of point on leech for relative length HL */ h2 = HL; //do { h = h2; l1 = LeechLength( h ); h2 = h * (1-(l1 - LeL*HL) / (LeL*HL)); //printf (" HL=%f l1=%f h1=%f - h2=%f \n", HL, l1, h, h2); h = h2; l1 = LeechLength(h); h2 = h * (1-(l1 - LeL*HL) / (LeL*HL)); //printf (" HL=%f l1=%f h=%f - h1=%f \n", HL, l1, h, h2); } //while ( fabs(h1-h2)>.001 ); /* compute the luff edge length LuL */ h = 1; LuL = LuffLength( h ); //printf ("IOR luff length = %f \n", LuL); /* compute the height of point on luff for relative length HL */ h1 = HL; //do { h = h1; l1 = LuffLength( h ); h1 = h * (1 - (l1 - LuL*HL) / (LuL*HL) ); //printf (" HL=%f l1=%f h1=%f - h2=%f \n", HL, l1, h, h1); h = h1; l1 = LuffLength( h ); h1 = h * (1 - (l1 - LuL*HL) / (LuL*HL) ); //printf (" HL=%f l1=%f h=%f - h1=%f \n", HL, l1, h, h1); } //while ( fabs(h1-h2)>.001 ); /* compute the shortest distance real leech to the real luff */ p = clew + leechV * h2; p2 = Zpoint(EdgeIntersect( LEECH_EDGE, p , leechVP) ); p = tack + luffV * h1; p1 = Zpoint(EdgeIntersect( LUFF_EDGE, p , luffVP) ); w = 0; p3 = p1; for (i = 1; i <= imax; i++) { h1 = real(i) / imax; p = Zpoint( p1 + CVector3d(p2 - p1) * h1 ); w = w + CVector3d(p - p3).length(); p3 = p; } return ( w ); } /** * Routine for computing the perpendicular width of the sail * from clew to luff, measured perpendicular to the luff. */ real CSailWorker::SailLP( ) { unsigned int i, imax=10; real h1=0, w=0; CPoint3d p, p1, p2, p3; CVector3d v; p1 = Zpoint( EdgeIntersect( LUFF_EDGE, clew , luffVP) ); v = CVector3d(clew - p1); p2 = p1; // compute the distance from the real luff to clew for (i = 1 ; i <= imax ; i++) { h1 = real(i) / imax; p = p1 + v * h1 ; p.setZ(0); p3 = Zpoint( p ); w = w + CVector3d(p3 - p2).length(); p2 = p3; } // return ( w ); } /** * Routine for computing the actual length of the leech edge * up to a given relative heigth on straight leech line. */ real CSailWorker::LeechLength( const real &h ) { unsigned int i=0, imax=20; CPoint3d p1, p2, p3; real l=0, h1=0; p1 = clew; for (i = 1; i <= imax; i++) { h1= real(i) / imax; p2 = clew + leechV * (h * h1); p3 = Zpoint( EdgeIntersect( LEECH_EDGE, p2 , leechVP) ); l = l + CVector3d(p3 - p1).length(); // printf ("step = %f - p2.y = %f - leech length = %f \n", h1, p2.y(), l); p1 = p3; } return ( l ); } /** * Routine for computing the actual length of the luff edge * up to a given relative heigth on straight luff line. */ real CSailWorker::LuffLength( const real &h ) { unsigned int i=0, imax=20; CPoint3d p1=tack, p2, p3; real l=0, h1=0; for (i = 1 ; i < imax ; i++) { h1= real(i) / imax; p2 = tack + luffV * (h * h1); p3 = Zpoint( EdgeIntersect( LUFF_EDGE, p2 , luffVP ) ); l = l + CVector3d(p3 - p1).length(); p1 = p3; } return ( l ); } /** * Routine used for computing the forward end of the cord of the profile. * Return a 3d point which is the forward intersection of * the horizontal line passing by p1 with either foot, luff or gaff. */ CPoint3d CSailWorker::FwdIntersect( const CPoint3d &pt1 ) const { CPoint3d pFwd = pt1; // forward intersection point initialised at p1 CVector3d vH = CVector3d( 1, 0, 0 ); if ( pt1.y() <= tack.y() ) // point is at or below tack { pFwd.setX(tack.x()); // set forward point on vertical below tack // pFwd.setZ(tack.z()); } else if ( pt1.y() < head.y() ) // forward point is on luff curve { pFwd = EdgeIntersect( LUFF_EDGE, pt1, vH ); } else if ( pt1.y() == head.y() ) // point exactly at head height { pFwd.setX(head.x()); // pFwd.setZ(head.z()); } else if ( pt1.y() < peak.y() ) { // forward point is on gaff pFwd = EdgeIntersect( GAFF_EDGE, pt1, vH ); } else { // point is above peak pFwd.setX(peak.x()); // set forward point on vertical above peak //pFwd.setZ(peak.z()); // } // Ensure Z = 0 pFwd.setZ(0); // return pFwd; } /* end FwdIntersect //////////////// */ /** * Routine used for computing the point position on a sail curved edge. * Return a 3D point which is the intersection of the vector v1 * passing by pt1 point inside sail area with the Edge curve. */ CPoint3d CSailWorker::EdgeIntersect( const enumEdgeType &Edge, const CPoint3d &pt1, const CVector3d &v1 ) const { if ( v1.length() <= EPS ) throw layout_error("CSailWorker::EdgeIntersect : input vector is nul"); // Input line CSubSpace InputLine = CSubSpace::line( pt1 , v1 ); // Edge end points CPoint3d pEnd1, pEnd2; // Edge Vector CVector3d vEdge; // Edge perpendicular vector toward outside of sail CVector3d vpEdge; // Edge round real EdgeR = 0; // Edge round position from end1 toward end2 int EdgeRP; switch ( Edge ) { case LUFF_EDGE: pEnd1 = tack; pEnd2 = head; EdgeR = luffR; EdgeRP = luffRP; vEdge = CVector3d( pEnd2 - pEnd1 ); vpEdge = rotateNormalized(M_PI/2, vEdge); break; case GAFF_EDGE: pEnd1 = head; pEnd2 = peak; EdgeR = gaffR; EdgeRP = gaffRP; vEdge = CVector3d( pEnd2 - pEnd1 ); vpEdge = rotateNormalized(M_PI/2, vEdge); break; case FOOT_EDGE: pEnd1 = tack; pEnd2 = clew; EdgeR = footR; EdgeRP = footRP; vEdge = CVector3d( pEnd2 - pEnd1 ); vpEdge = rotateNormalized(-M_PI/2, vEdge); break; case LEECH_EDGE: pEnd1 = clew; pEnd2 = peak; EdgeR = leechR; EdgeRP = leechRP; vEdge = CVector3d( pEnd2 - pEnd1 ); vpEdge = rotateNormalized(-M_PI/2, vEdge); break; } // Edge line CSubSpace Line2 = CSubSpace::line( pEnd1, vEdge ); real h1=0, h2=0, d1=0, d2=0; CPoint3d p0 , p1 , p2 , p3; CVector3d v; // find point p0 at intersection of straight edge with input line p0 = InputLine.intersectionPoint(Line2, "with edge"); p2 = p0; // default output if (CVector3d::dotProduct(p0 - pEnd1, vEdge) <= 0) p2 = pEnd1; // intersection left of edge else if (CVector3d::dotProduct(p0 - pEnd2, vEdge) >= 0) p2 = pEnd2; // intersection right of edge else if ( fabs(EdgeR) > 1 ) { // intersection is on curved edge h1 = CVector3d(p0 - pEnd1).length() / (vEdge.length() + EPS); // relative height d1 = EdgeR * RoundP(h1 , EdgeRP); // local depth of edge curve p1 = p0 + vpEdge * d1; // define a line parrallel to edge at distance d1 Line2 = CSubSpace::line( p1 , vEdge ); // point2 at intersection of input line with parrallel to edge is always valid p2 = InputLine.intersectionPoint(Line2, "with parallel to edge"); v = CVector3d( p2 - p1); if ( v.length() > EPS ) { // translate point0 on straight edge p3 = p0 + v; // check if p3 is inside edge if (CVector3d::dotProduct(p3 - pEnd1, vEdge) <= 0) // p3 outside left of edge end p2 = pEnd1; else if (CVector3d::dotProduct(p3 - pEnd2, vEdge) >= 0) // p3 outside right of edge end p2 = pEnd2; else { // point is on edge curve h2 = CVector3d(p3 - pEnd1).length() / (vEdge.length() + EPS); d2 = EdgeR * RoundP( h2 , EdgeRP ); // local depth of edge curve p2 = p3 + vpEdge * d2; } v = CVector3d ( p2 - p1 ); if ( v.length() <= EPS ) // keep p1 which is strictly on input line p2 = p1; else { // displaced point 2 and p1 are used for Line2 Line2 = CSubSpace::line( p1 , v ); // compute final intersection point p2 p2 = InputLine.intersectionPoint(Line2, "with ?"); } } } // return p2; } /* end EdgeIntersect //////////////////// */ /** * Routine used for computing the intersection with mitre line. * Return a 3d point which is the intersection of the vector v1 * passing by pt1 point with the mitre line. */ CPoint3d CSailWorker::MitreIntersect( const CPoint3d &pt1, const CVector3d &v1 ) const { if ( v1.length() <= EPS ) throw layout_error("CSailWorker::MitreIntersect : input vector is nul"); // real x=0, y=0, z=0; // for debugging only /* straight line passing through input point */ CSubSpace ptv1 = CSubSpace::line(pt1 , v1); CPoint3d p2 = pt1; if ( CVector3d(p2 - clew).length() <= EPS ) p2 = clew; else { /* point at intersection of input vector and mitre ckecking if it is inside segment or not is in LayoutMitre */ p2 = ptv1.intersectionPoint(mitreLine, "with mitre"); } return p2; } /** * Routine used for computing the Z of a point of the sail. * Return a 3D point which is the input point p1 with its Z modified. */ CPoint3d CSailWorker::Zpoint( const CPoint3d &p1 ) const { CPoint3d p2 = p1; // p2 will be the returned point with Z added to p1 real x=0, z=0, twist=0, pivotX=0, pos=0, cord=1; CPoint3d pFwd = FwdIntersect( p1 ); // forward end of the cord CPoint3d pAft = AftIntersect( p1 ); // rear end of the cord /* computing local cord of the profile */ cord = CVector3d( pAft - pFwd ).length(); /* computing Z from normalised position on profile */ if ( cord < 1 ) // to avoid division by cord = zero { pos = 0 ; z = 0; } else // position on profile { pos = ( CVector3d( p1 - pFwd ).length() ) / cord; /* computing the relative height on the sail */ real h1 = (p1.y() - tack.y()) / (peak.y() - tack.y()); // for mould /* Now computing actual Z including twist and sheeting angle * kluff, kleech, depth coefficient used in z1=f(pos, h1) of the * sailmould are interpolated between the respective profile[0..2]. * The position of profile[1] is driven by vertpos which is * the vertical position of the middle profile entered in the * left vertical pane of formmouldbase. */ z = cord * mould.interpol( h1 ).z(pos); } /* computing the twist from the relative height on straight leech */ real h2 = ( p1.y() - clew.y() ) / leechV.y(); if ( h2 >= 1 ) // above peak h2 = 1; else if ( h2 <= 0 ) // below clew h2 = 0; twist = degreesToRadians(h2 * twistDeg + sheetDeg); if ( p1.y() >= head.y() ) // on gaff pivotX = head.x(); else if ( p1.y() <= tack.y() ) // below tack pivotX = tack.x(); else // on luff pivotX = pFwd.x(); x = p1.x() - pivotX; /* applying the twist by rotating the profile around pivotX */ p2.setX(pivotX + x * cos(twist) - z * sin(twist)); p2.setZ(x * sin(twist) + z * cos(twist)); return p2; } /* end Zpoint ///////////////// */ /** * Routine used for computing the Z of all the points of a panel. * Returns a CPanel with all its points Z's modified. */ CPanel CSailWorker::Zpanel( const CPanel &p1 ) const { CPanel ret = p1; unsigned int k; for (k = 0; k < ret.left.size(); k++) ret.left[k] = Zpoint(ret.left[k]); for (k = 0; k < ret.right.size(); k++) ret.right[k] = Zpoint(ret.right[k]); for (k = 0; k < ret.top.size(); k++) ret.top[k] = Zpoint(ret.top[k]); for (k = 0; k < ret.bottom.size(); k++) ret.bottom[k] = Zpoint(ret.bottom[k]); return ret; } sailcut-1.5.0/src/sailcpp/sailworker.h000066400000000000000000000124361477005247400177560ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILWORKER_H #define SAILWORKER_H #include "panelgroup.h" #include "saildef.h" // forward declarations class CPanelGroup; class CSeam; enum enumEdgeType { LUFF_EDGE, GAFF_EDGE, FOOT_EDGE, LEECH_EDGE }; class layout_error : public std::runtime_error { public: layout_error(const std::string &message) : std::runtime_error(message) { std::cout << "in sailworker:" << what() << std::endl; } }; /** The CSailWorker class does all the sail-related calculations like laying the panels. * It is used to create the sail from a CSailDef definition. * * @ingroup SailCpp * @see CSailDef, CPanelGroup */ class CSailWorker : public CSailDef { public: CSailWorker(const CSailDef &s); /** The area of the sail. */ real Area(); /** The head to clew diagonal length. */ real Diagonal(); /** The computation of the width as per IRC rule. */ real IRCwidth( const real &h ); /** The computation of the sail width at any height. */ real SailWidth( const real &h ); /** The length of the leech measured along its curved edge. */ real LeechLength( const real &h ); /** The length of the luff measured along its curved edge. */ real LuffLength( const real &h ); /** The maximum width of the sail perpendicular to the luff. */ real SailLP( ); CPanelGroup makeSail() const; CPanelGroup makeSail(CPanelGroup &flatsail, CPanelGroup &dispsail) const; /** The Tack 3D point. */ CPoint3d tack; /** The Head 3D point. */ CPoint3d head; /** The Peak 3D point. */ CPoint3d peak; /** The Clew 3D point. */ CPoint3d clew; protected: /** The Cross cut and Horizontal cut layout of sail's panels. */ CPanelGroup Layout0( CPanelGroup &flatsail, CPanelGroup &dispsail ) const; /** The Twist cut layout of sail's panels. */ CPanelGroup LayoutTwist( CPanelGroup &flatsail, CPanelGroup &dispsail ) const; /** The Vertical cut layout of sail's panels. */ CPanelGroup LayoutVertical( CPanelGroup &flatsail, CPanelGroup &dispsail ) const; /** The Radial cut layout of sail's panels. */ CPanelGroup LayoutRadial( CPanelGroup &flatsail, CPanelGroup &dispsail ) const; /** The Mitre cut layout of sail's panels perpendicular to leech and foot. */ CPanelGroup LayoutMitre( CPanelGroup &flatsail, CPanelGroup &dispsail ) const; /** The Mitre 2 cut layout of sail's panels parralel to foot and leech. */ CPanelGroup LayoutMitre2( CPanelGroup &flatsail, CPanelGroup &dispsail ) const; /** The Tri Radial cut layout of sail's panels. */ CPanelGroup LayoutTriRadial( CPanelGroup &flatsail, CPanelGroup &dispsail ) const; /** The Wing cut layout of sail's panels. */ CPanelGroup LayoutWing( CPanelGroup &flatsail, CPanelGroup &dispsail ) const; /** The type of sail Edge for an intersection. */ enumEdgeType Edge; /** The intersection of a line defined by a point and a vector with an edge. */ CPoint3d EdgeIntersect( const enumEdgeType &Edge, const CPoint3d &pt1, const CVector3d &v1 ) const; /** The horizontal intersection with forward edge. */ CPoint3d FwdIntersect( const CPoint3d &pt1 ) const; /** The horizontal intersection with aft edge. */ CPoint3d AftIntersect( const CPoint3d &pt1 ) const; /** The intersection of a line defined by a point and a vector with the mitre line. */ CPoint3d MitreIntersect( const CPoint3d &pt1, const CVector3d &v1 ) const; /** The mitre intersection point with luff. */ CPoint3d mitreLuffPt; /** The depth of the sail at a point. */ CPoint3d Zpoint( const CPoint3d &p1 ) const; /** The depth of the sail at all points of a panel. */ CPanel Zpanel( const CPanel &p1 ) const; /** Foot vector. */ CVector3d footV; /** Unitary vector perpendicular to foot. */ CVector3d footVP; /** Gaff vector. */ CVector3d gaffV; /** Unitary vector perpendicular to gaff. */ CVector3d gaffVP; /** Leech vector. */ CVector3d leechV; /** Unitary vector perpendicular to leech. */ CVector3d leechVP; /** Luff vector. */ CVector3d luffV; /** Unitary vector perpendicular to luff. */ CVector3d luffVP; /** Mitre vector. */ CVector3d mitreV; /** The foot straight 3D line. */ CSubSpace footLine; /** The gaff straight 3D line. */ CSubSpace gaffLine; /** The leech straight 3D line. */ CSubSpace leechLine; /** The luff straight 3D line. */ CSubSpace luffLine; /** The mitre straight 3D line. */ CSubSpace mitreLine; }; #endif sailcut-1.5.0/src/saildisp.cpp000066400000000000000000000102351477005247400162770ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "saildisp.h" const real ZOOM_FACTOR = 2; const real ZOOM_MIN = 0.8; const real ZOOM_MAX = pow(ZOOM_FACTOR, 8) * ZOOM_MIN; /***************************************************************************** CSailDisp class *****************************************************************************/ /** Constructs a generic view area for a sail. */ CSailDisp::CSailDisp() : m_azimuth(0) , m_elevation(0) , m_zoom(ZOOM_MIN) { // initialise data drawLabels = false; } /** Returns a rotated copy of the object by a given azimuth and elevation. */ CPanelGroup CSailDisp::dispObject() const { const CVector3d center = baseRect.center(); CMatrix4x4 matrix; matrix.translate(center); matrix.rotate(degreesToRadians(m_elevation), CVector3d(1, 0, 0)); matrix.rotate(degreesToRadians(m_azimuth), CVector3d(0, 1, 0)); matrix.translate(-center); return baseObject.transformed(matrix); } /** * Accessor for the logical viewport rectangle. */ CRect3d CSailDisp::logicalRect() const { return calcLRect(viewRect, baseRect, m_center, m_zoom); } /** Resets display zoom and center to their default values. */ void CSailDisp::resetZoomCenter() { m_center = baseRect.center(); m_zoom = ZOOM_MIN; } /** Converts screen coordinates to logical coordinates. */ CPoint3d CSailDisp::screenToLogical( const int x, const int y ) const { // avoid division by zero if ((viewRect.width()==0)||(viewRect.height()==0)) return m_center; const CRect3d logicalRect = this->logicalRect(); return m_center + CVector3d( logicalRect.width() * ( real(x) / viewRect.width() - 0.5 ), logicalRect.height() * ( 0.5 - real(y) / viewRect.height() ), 0); } /** Sets the azimuth view angle. * * @param azimuth azimuth in degrees */ void CSailDisp::setAzimuth(real azimuth) { m_azimuth = azimuth; } /** Returns the center of the display in logical coordinates. */ CPoint3d CSailDisp::center() const { return m_center; } /** Sets the center of the display in logical coordinates. * * @param newCenter the new center */ void CSailDisp::setCenter(const CPoint3d ¢er) { m_center = center; } /** Sets the elevation view angle. * * @param elevation elevation in degrees */ void CSailDisp::setElevation(real elevation) { m_elevation = elevation; } /** Sets the object that is to be displayed * and center the view. */ void CSailDisp::setObject( const CPanelGroup &obj ) { baseObject = obj; baseRect = baseObject.boundingRect(); // handle case where the bounding rectangle is flat if (baseRect.height() == 0) baseRect.max.setY(baseRect.max.y() + 1); if (baseRect.width() == 0) baseRect.max.setX(baseRect.max.x() + 1); m_center = baseRect.center(); } /** Set the size of the viewing rectangle. */ void CSailDisp::setViewRect( const CRect3d &rect ) { viewRect = rect; } /** Returns the zoom factor. */ real CSailDisp::zoom() const { return m_zoom; } /** Sets the zoom factor. * * @param zoom */ void CSailDisp::setZoom(real zoom) { m_zoom = std::max(ZOOM_MIN, std::min(zoom, ZOOM_MAX)); } /** Zooms IN by a factor ZOOM_FACTOR. */ void CSailDisp::zoomIn() { setZoom(m_zoom * ZOOM_FACTOR); } /** Zooms OUT by a factor ZOOM_FACTOR. */ void CSailDisp::zoomOut() { setZoom(m_zoom / ZOOM_FACTOR); } sailcut-1.5.0/src/saildisp.h000066400000000000000000000042741477005247400157520ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILDISP_H #define SAILDISP_H #include "sailcpp/panelgroup.h" #include "sailcpp/sailcalc.h" /** A generic display area for a panel group. * * @see CSailDispLabel * @see CSailDispGL */ class CSailDisp { public: CSailDisp(); /** The destructor. */ virtual ~CSailDisp() {} ; /** Acessor for the logical viewport rectangle */ /** Redraw the view. */ virtual void redraw() = 0; virtual void resetZoomCenter( void ); virtual CPoint3d screenToLogical( const int x, const int y ) const; void setAzimuth(real azimuth); void setElevation(real elevation); CPoint3d center() const; void setCenter(const CPoint3d &newCenter); void setObject( const CPanelGroup &objs ); void setViewRect( const CRect3d &rect ); real zoom() const; void setZoom(real newZoom); void zoomIn(); void zoomOut(); /** Should labels be drawn ? */ bool drawLabels; protected: CPanelGroup dispObject() const; CRect3d logicalRect() const; private: real m_azimuth; /** The center of the viewing area, in logical coordinates */ CPoint3d m_center; real m_elevation; real m_zoom; /** Viewport rectangle, in device coordinates */ CRect3d viewRect; /** Bounding rectangle of the unrotated object */ CRect3d baseRect; /** Unrotated copy of the object */ CPanelGroup baseObject; }; #endif sailcut-1.5.0/src/saildispgl.cpp000066400000000000000000000140441477005247400166240ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "saildispgl.h" static const char* vertexShader = "attribute mediump vec4 posAttr;\n" "uniform mediump mat4 matrixAttr;\n" "void main()\n" "{\n" " gl_Position = matrixAttr * posAttr;\n" "}\n"; static const char* fragmentShader = "uniform mediump vec4 colorAttr;\n" "void main()\n" "{\n" " gl_FragColor = colorAttr;\n" "}\n"; /** Construct an OpenGL view area. * * @param parent the parent widget */ CSailDispGL::CSailDispGL(QWidget * parent) : QOpenGLWidget(parent) { } void CSailDispGL::putPoint(GLfloat **vertex, const CPoint3d &pt) const { *((*vertex)++) = pt.x(); *((*vertex)++) = pt.y(); *((*vertex)++) = pt.z(); } /** Draw a panel of a sail. * * @param panel */ void CSailDispGL::draw( const CPanel &panel ) { unsigned int i; const int mainCount = panel.top.size() * 2; const int leftCount = panel.left.size() + 1; const int rightCount = panel.right.size() + 1; const int maxCount = qMax(mainCount, qMax(leftCount, rightCount)); const int vertexSize = 3; GLfloat vertexArray[maxCount * vertexSize]; GLfloat *vertex; // main vertex = vertexArray; for (i = 0; i < panel.top.size(); i++) { putPoint(&vertex, panel.top[i]); putPoint(&vertex, panel.bottom[i]); } program->enableAttributeArray(posAttr); program->setAttributeArray(posAttr, vertexArray, vertexSize); glDrawArrays(GL_TRIANGLE_STRIP, 0, mainCount); program->disableAttributeArray(posAttr); // left side vertex = vertexArray; putPoint(&vertex, (panel.left.front() + panel.left.back()) * 0.5); for (i = 0; i < panel.left.size(); i++) putPoint(&vertex, panel.left[i]); program->enableAttributeArray(posAttr); program->setAttributeArray(posAttr, vertexArray, vertexSize); glDrawArrays(GL_TRIANGLE_FAN, 0, leftCount); program->disableAttributeArray(posAttr); // right side vertex = vertexArray; putPoint(&vertex, (panel.right.front() + panel.right.back()) * 0.5); for (i =0; i < panel.right.size(); i++) putPoint(&vertex, panel.right[i]); program->enableAttributeArray(posAttr); program->setAttributeArray(posAttr, vertexArray, vertexSize); glDrawArrays(GL_TRIANGLE_FAN, 0, rightCount); program->disableAttributeArray(posAttr); } /** Draw a complete sail. * * @param sail */ void CSailDispGL::draw( const CPanelGroup &sail ) { unsigned int i; for (i = 0; i < sail.size(); i++) { if (sail.type == HULL) { // Hull color (green) program->setUniformValue(colorAttr, QColor(26, 128, 51)); } else if ( sail.type == RIG) { // Rig color (dark red) program->setUniformValue(colorAttr, QColor(128, 26, 26)); } else { // Sail color (alternate dark yellow / yellow / white) program->setUniformValue(colorAttr, QColor(204, 179 + 12 * (i % 3), 102 + 51 * (i % 3))); } draw(sail[i]); } for (i = 0; i < sail.child.size(); i++) draw(sail.child[i]); } /** Force a redraw of the view area. */ void CSailDispGL::redraw() { update(); } /** Initialize the OpenGL subsystem. */ void CSailDispGL::initializeGL() { initializeOpenGLFunctions(); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearDepthf(1.0f); program = new QOpenGLShaderProgram(this); if (!program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader)) qWarning("could not load vertex shader"); if (!program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader)) qWarning("could not load fragment shader"); program->link(); colorAttr = program->uniformLocation("colorAttr"); matrixAttr = program->uniformLocation("matrixAttr"); posAttr = program->attributeLocation("posAttr"); } /** We received a mouse click. * * @param event */ void CSailDispGL::mousePressEvent ( QMouseEvent *event ) { if (event->button() == Qt::LeftButton) { setCenter(screenToLogical(event->pos().x(), event->pos().y())); redraw(); } } /** Perform OpenGL painting. */ void CSailDispGL::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // set transform const CRect3d lRect = logicalRect(); QMatrix4x4 matrix; matrix.scale( real(2) / lRect.width(), real(2) / lRect.height(), - real(2) / sqrt(lRect.width() * lRect.width() + lRect.height() * lRect.height())); matrix.translate(-center().x(), -center().y(), -center().z()); program->bind(); program->setUniformValue(matrixAttr, matrix); draw(dispObject()); program->release(); } /** The draw area has been resized. * * @param w the new width * @param h the new height */ void CSailDispGL::resizeGL( int w, int h ) { glViewport(0, 0, (GLint)w, (GLint)h); setViewRect(CRect3d(CPoint3d(0, 0, 0), CPoint3d(w, h, 0))); } /** We received a mouse wheel movement. * * @param event */ void CSailDispGL::wheelEvent( QWheelEvent *event) { const int delta = event->pixelDelta().y(); if (delta > 0) zoomIn(); else if (delta < 0) zoomOut(); redraw(); } sailcut-1.5.0/src/saildispgl.h000066400000000000000000000032531477005247400162710ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILDISPGL_H #define SAILDISPGL_H #include "saildisp.h" #include #include class QOpenGLShaderProgram; /** An OpenGL display area for a sail. This is only used if Sailcut is * compiled with OpenGL support enabled. * * @see CSailDispLabel */ class CSailDispGL : public QOpenGLWidget, public QOpenGLFunctions, public CSailDisp { public: CSailDispGL( QWidget *parent ); void redraw(); protected: void draw( const CPanel &panel ); void draw( const CPanelGroup &sail ); void initializeGL(); void mousePressEvent ( QMouseEvent * ); void paintGL(); void resizeGL( int w, int h ); void wheelEvent( QWheelEvent *event); private: void putPoint(GLfloat **vertex, const CPoint3d &pt) const; QOpenGLShaderProgram *program; int colorAttr; int matrixAttr; int posAttr; }; #endif sailcut-1.5.0/src/saildisplabel.cpp000066400000000000000000000054041477005247400173010ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "saildisplabel.h" #include "sailpainter.h" #include /** Constructs a QLabel based view area. */ CSailDispLabel::CSailDispLabel( QWidget * parent ) : QLabel( parent ), wasResized(true) { // set the background to white QPalette pal = palette(); pal.setColor( QPalette::Window, Qt::white ); setPalette( pal ); } /** Forces a redraw of the view area. */ void CSailDispLabel::redraw() { update(); } /** We received a mouse click. */ void CSailDispLabel::mousePressEvent ( QMouseEvent *event ) { if (event->button() == Qt::LeftButton) { setCenter(screenToLogical(event->pos().x(),event->pos().y())); redraw(); } } /** We received a request to paint the drawing area. */ void CSailDispLabel::paintEvent( QPaintEvent * ) { // erase viewport CSailPainter painter( this ); QRect rect = painter.viewport(); painter.eraseRect(rect); // check if the window was resized since last redraw if ( wasResized ) { setViewRect(painter.viewRect()); wasResized = 0; } // set coordinate system to match the logical viewport painter.setWindow(logicalRect()); painter.setFontSize(8, zoom()); painter.setPenColor(Qt::black); painter.setPenWidth(); // draw the sail const CPanelGroup obj = dispObject(); painter.draw(obj); // optionally draw labels if (drawLabels) { painter.drawLabels(obj); /*/ draw markers on edges for test purpose painter.setFontSize(10, zoom/10); painter.drawMarkers(obj); */ } // painter.end(); } /** The draw area has been resized. */ void CSailDispLabel::resizeEvent( QResizeEvent * ) { wasResized = 1; } /** We received a mouse wheel movement. */ void CSailDispLabel::wheelEvent( QWheelEvent *event) { const int delta = event->pixelDelta().y(); if (delta > 0) zoomIn(); else if (delta < 0) zoomOut(); redraw(); } sailcut-1.5.0/src/saildisplabel.h000066400000000000000000000026161477005247400167500ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILDISPLABEL_H #define SAILDISPLABEL_H #include #include "saildisp.h" class QGridLayout; /** A wireframe display area for a sail, based on a QLabel. * * @see CSailDispGL */ class CSailDispLabel : public QLabel, public CSailDisp { public: CSailDispLabel(QWidget *parent); void redraw(); protected: void mousePressEvent ( QMouseEvent * ); void paintEvent( QPaintEvent * ); void resizeEvent( QResizeEvent * ); void wheelEvent( QWheelEvent *event); private: /** Has the area been resized since last redraw */ bool wasResized; }; #endif sailcut-1.5.0/src/saildoc.cpp000066400000000000000000000703451477005247400161150ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "saildoc.h" #include /** This contains all the input and output functions * to read and write the sail, hull, rig, boat data to file. */ /************************************************************************** construction / destruction **************************************************************************/ /** Constructs an empty CSailDoc object. */ CSailDoc::CSailDoc() : QDomDocument("Sailcut") { top = createElement("CSailDoc"); appendChild(top); } /** Constructs a CSailDoc from a given XML file. * * @param filename */ CSailDoc::CSailDoc( const QString &filename ) { QFile f( filename ); if ( !f.open(QIODevice::ReadOnly) ) throw read_error("CSailDoc::CSailDoc : cannot open file for read access!"); if ( !setContent( &f ) ) { f.close(); throw read_error("CSailDoc::CSailDoc : cannot set XML content from file!"); } f.close(); top = documentElement(); } /** Creates an element with the given name and type. * * @param type a string containing the type of the element * @param name a string containing the name of the element */ QDomElement CSailDoc::createElement(const QString &type, const QString &name) { QDomElement e = createElement(type); e.setAttribute("name", name); return e; } /** Creates an element with the given name, type and value. * * @param type a string containing the type of the element * @param name a string containing the name of the element * @param value a string containing the name of the element */ QDomElement CSailDoc::createElement(const QString &type, const QString &name, const QString &value) { QDomElement e = createElement(type,name); e.setAttribute("value", value); return e; } /** Looks for an element with a given name and type in the current XML document. * * @param parent the parent node * @param type a string containing the type of the element * @param name a string containing the name of the element */ QDomElement CSailDoc::findElement(const QDomNode &parent, const QString &type, const QString &name) { QDomNamedNodeMap attr; QDomNode n = parent.firstChild(); while ( !n.isNull() ) { if (n.nodeName() == type) { attr = n.toElement().attributes(); if (attr.namedItem("name").nodeValue() == name) return n.toElement(); } n = n.nextSibling(); } // we didn't find the element, throw an exception throw doc_element_error(QString("CSailDoc::findElement(" + type + "," + name + ") : did not find requested element").toStdString()); n.clear(); return n.toElement(); } /************************************************************************** Input **************************************************************************/ /** Reads an integer value from an XML document. * * @param parent the parent node * @param i the integer * @param name the name of the value */ void CSailDoc::get ( const QDomNode &parent, int &i, const QString &name ) { QDomElement e = findElement( parent, "int", name); QDomNamedNodeMap attr = e.attributes(); i = attr.namedItem("value").nodeValue().toInt(); } /** Reads an unsigned integer value from an XML document. * * @param parent the parent node * @param i the unsigned integer * @param name the name of the value */ void CSailDoc::get ( const QDomNode &parent, unsigned int &i, const QString &name ) { int temp; get(parent, temp, name); i = temp; } /** Reads a real value from an XML document. * * @param parent the parent node * @param r the real value * @param name the name of the value */ void CSailDoc::get ( const QDomNode &parent, real &r, const QString &name ) { QDomElement e = findElement( parent, "real", name); QDomNamedNodeMap attr = e.attributes(); r = attr.namedItem("value").nodeValue().toDouble(); } /** Reads a std::string value from an XML document. * * @param parent the parent node * @param s the string * @param name the name of the string */ void CSailDoc::get ( const QDomNode &parent, std::string &s, const QString &name ) { QDomElement e = findElement( parent, "string", name); QDomNamedNodeMap attr = e.attributes(); s = attr.namedItem("value").nodeValue().toStdString(); } /** Reads a QString string value from an XML document. * * @param parent the parent node * @param s the string * @param name the name of the string */ void CSailDoc::get ( const QDomNode &parent, QString &s, const QString &name ) { QDomElement e = findElement( parent, "string", name); QDomNamedNodeMap attr = e.attributes(); s = attr.namedItem("value").nodeValue(); } /** Reads a CPoint3D point with x,y,z coordinates from an XML document. * * @param parent the parent node * @param p the 3D point * @param name the name of the 3D point */ void CSailDoc::get ( const QDomNode &parent, CPoint3d &p, const QString &name ) { real x, y, z; QDomElement e = findElement( parent, "CPoint3d", name); get(e, x, "x"); get(e, y, "y"); get(e, z, "z"); p = CPoint3d(x, y, z); } /** Reads an enumPanelGroupType enumerated Panel Group Type from an XML document. * * @param parent the parent node * @param t the enumPanelGroupType * @param name the name of the value */ void CSailDoc::get ( const QDomNode &parent, enumPanelGroupType &t, const QString &name ) { QDomElement e = findElement( parent, "enumPanelGroupType", name); QString s = e.attributes().namedItem("value").nodeValue(); if (!s.compare("SAIL")) { t = SAIL; } else if (!s.compare("RIG")) { t = RIG; } else if (!s.compare("HULL")) { t = HULL; } else { throw std::invalid_argument("CSailDoc::get : unknown panel group type"); } } /** Reads an enumSailCut enumerated Sail Cut type from an XML document. * * @param parent the parent node * @param c the enumSailCut * @param name the name of the value */ void CSailDoc::get ( const QDomNode &parent, enumSailCut &c, const QString &name ) { QDomElement e = findElement( parent, "enumSailCut", name); QString s = e.attributes().namedItem("value").nodeValue(); if (!s.compare("CROSS")) c = CROSS; if (!s.compare("TWIST")) c = TWIST; if (!s.compare("HORIZONTAL")) c = HORIZONTAL; if (!s.compare("VERTICAL")) c = VERTICAL; if (!s.compare("RADIAL")) c = RADIAL; if (!s.compare("MITRE")) c = MITRE; if (!s.compare("MITRE2")) c = MITRE2; } /** Reads an enumSailType enumerated Sail Type from an XML document. * * @param parent the parent node * @param t the enumSailType * @param name the name of the value */ void CSailDoc::get ( const QDomNode &parent, enumSailType &t, const QString &name ) { QDomElement e = findElement( parent, "enumSailType", name); QString s = e.attributes().namedItem("value").nodeValue(); if (!s.compare("MAINSAIL")) t = MAINSAIL; if (!s.compare("JIB")) t = JIB; if (!s.compare("WING")) t = WING; } /** Reads an enumBoatElementType enumerated Boat Element Type from an XML document. * * @param parent the parent node * @param t the enumBoatElementType * @param name the name of the value */ void CSailDoc::get ( const QDomNode &parent, enumBoatElementType &t, const QString &name ) { QDomElement e = findElement( parent, "enumBoatElementType", name); QString s = e.attributes().namedItem("value").nodeValue(); if (!s.compare("HULLDEF")) t = HULLDEF; if (!s.compare("SAILDEF")) t = SAILDEF; if (!s.compare("RIGDEF")) t = RIGDEF; if (!s.compare("PANELGROUP")) t = PANELGROUP; } /** Reads a CHullDef hull definition from an XML document. * * @param parent the parent node * @param d the hull definition * @param name the name of the hull definition */ void CSailDoc::get ( const QDomNode &parent, CHullDef &d, const QString &name ) { QDomElement e = findElement( parent, "CHullDef", name); get(e, d.hullID, "hullID"); /** read hull bottom data */ get(e, d.BLWL, "BLWL"); get(e, d.BfwdHeight, "BfwdHeight"); get(e, d.BaftHeight, "BaftHeight"); get(e, d.BSlopeA, "BSlopeA"); get(e, d.BBW, "BBW"); get(e, d.BBWPos, "BBWPos"); get(e, d.BaftW, "BaftW"); get(e, d.BDeadriseA, "BDeadriseA"); get(e, d.BSweepA, "BSweepA"); get(e, d.BfwdShape, "BfwdShape"); get(e, d.BaftShape, "BaftShape"); /** read hull deck data */ get(e, d.DfwdHeight, "DfwdHeight"); get(e, d.DaftHeight, "DaftHeight"); get(e, d.DSlopeA, "DSlopeA"); /** read hull stem angle */ get(e, d.StemA, "StemA"); /** read hull transom angle */ get(e, d.TransomA, "TransomA"); /** read hull side planks data */ get(e, d.NBPlank, "NBPlank"); get(e, d.TopPlankA, "TopPlankA"); get(e, d.LowPlankA, "lowPlankA"); // get(e, d.AutoPlank, "AutoPlank"); // } /** Reads a CSailDef sail definition from an XML document. * NEW members are added at the end of the list * See also CSailDoc::put(QDomNode &parent, const CSailDef &d, const QString &name ) * * @param parent the parent node * @param d the sail definition * @param name the name of the sail definition */ void CSailDoc::get ( const QDomNode &parent, CSailDef &d, const QString &name ) { QDomElement e = findElement( parent, "CSailDef", name); /** read sail cut layout and type */ get(e, d.sailCut, "sailCut"); get(e, d.sailType, "sailType"); /** read sail boat data */ get(e, d.LOA, "LOA"); get(e, d.foreI, "foreI"); get(e, d.foreJ, "foreJ"); get(e, d.tackX, "tackX"); get(e, d.tackY, "tackY"); /** read sail sides */ get(e, d.luffL, "luffL"); get(e, d.rake, "rake"); get(e, d.gaffDeg, "gaffDeg"); get(e, d.gaffL, "gaffL"); get(e, d.footL, "footL"); get(e, d.leechL, "leechL"); /** read sail shape of sides */ get(e, d.luffR, "luffR"); get(e, d.gaffR, "gaffR"); get(e, d.leechR, "leechR"); get(e, d.footR, "footR"); get(e, d.luffRP, "luffRP"); get(e, d.gaffRP, "gaffRP"); get(e, d.leechRP, "leechRP"); get(e, d.footRP, "footRP"); /** read sail cloth width, seam and hems width */ get(e, d.clothW, "clothW"); get(e, d.seamW, "seamW"); get(e, d.leechHemW, "leechHemW"); get(e, d.hemsW, "hemsW"); /** read sail twist */ get(e, d.twistDeg, "twistDeg"); /** read sail mould */ get(e, d.mould, "mould"); /** read sail sheeting angle */ get(e, d.sheetDeg, "sheetDeg"); /** NOTE : we maintain backward file format compatibility by adding below * all new members in the order they are introduced in CSailDoc::put */ try { /** read Sail ID */ get(e, d.sailID, "sailID"); /** read Radial sections */ get(e, d.nbSections, "nbSections"); /** read Radial gores */ get(e, d.nbGores, "nbGores"); /** read Luff gores */ get(e, d.nbLuffGores, "nbLuffGores"); /** read Wing dihedral angle */ get(e, d.dihedralDeg, "dihedralDeg"); /** read Foot hem width */ get(e, d.footHemW, "footHemW"); } catch (doc_element_error const&) { /** catch read error to avoid killing the program */ } } /** Reads a CSide sail side from an XML document. * * @param parent the parent node * @param s the sail side * @param name the name of the sail side */ void CSailDoc::get ( const QDomNode &parent, CSide &s, const QString &name ) { QDomElement e = findElement( parent, "CSide", name); get_vector(e, s, "point"); } /** Reads a CPanel sail panel from an XML document. * * @param parent the parent node * @param p the panel * @param name the name of the panel */ void CSailDoc::get ( const QDomNode &parent, CPanel &p, const QString &name ) { QDomElement e = findElement( parent, "CPanel", name); get(e, p.top, "top"); get(e, p.bottom, "bottom"); get(e, p.left, "left"); get(e, p.right, "right"); int temp; get(e, temp, "hasHems"); p.hasHems = (temp != 0); if (p.hasHems) { get(e, p.cutTop, "cutTop"); get(e, p.cutBottom, "cutBottom"); get(e, p.cutLeft, "cutLeft"); get(e, p.cutRight, "cutRight"); } } /** Reads a CPanelGroup from an XML document. * * @param parent the parent node * @param g the panel group * @param name the name of the panel group */ void CSailDoc::get ( const QDomNode &parent, CPanelGroup &g, const QString &name ) { QDomElement e = findElement( parent, "CPanelGroup", name); get_vector(e, g, "panel"); get(e, g.title, "title"); get_vector(e, g.child, "child"); /* NOTE : we maintain backward file format compatibility * by adding below all new members in the order they were introduced */ try { get(e, g.type, "type"); } catch (doc_element_error const&) { // to avoid killing the program } } /** Reads a CProfile sail profile from an XML document. * * @param parent the parent node * @param p the profile * @param name the name of the profile */ void CSailDoc::get ( const QDomNode &parent, CProfile &p, const QString &name ) { QDomElement e = findElement( parent, "CProfile", name); real depth=0,kluff=0,kleech=0; get(e, depth, "depth"); get(e, kleech, "kleech"); get(e, kluff, "kluff"); p = CProfile(depth,kleech,kluff); } /** Reads a CBoatDef boat definition from an XML document. * * @param parent the parent node * @param d the boat definition * @param name the name of the boat definition */ void CSailDoc::get ( const QDomNode &parent, CBoatDef &d, const QString &name ) { QDomElement e = findElement( parent, "CBoatDef", name); get_vector(e, d, "element"); } /** Reads a CBoatElement from an XML document. * * @param parent the parent node * @param s the boat element * @param name the name of the boat element */ void CSailDoc::get ( const QDomNode &parent, CBoatElement &s, const QString &name ) { QDomElement e = findElement( parent, "CBoatElement", name); get(e, (CPanelGroup&)s, "panelgroup"); get(e, s.type, "type"); get(e, s.filename, "filename"); get(e, s.origin, "origin"); } /** Reads a CSailMould sail mould from an XML document. * * @param parent the parent node * @param m the mould * @param name the name of the mould */ void CSailDoc::get ( const QDomNode &parent, CSailMould &m, const QString &name ) { QDomElement e = findElement( parent, "CSailMould", name); get(e, m.vertpos, "vertpos"); get_vector(e, m.profile, "profile"); } /** Reads a CPrefs set of preferences from an XML document. * * @param parent the parent node * @param p the preferences * @param name the name of the preferences */ void CSailDoc::get ( const QDomNode &parent, CPrefs &p, const QString &name ) { QDomElement e = findElement( parent, "CPrefs", name); try { get(e, p.language, "language"); get_vector(e, p.mruDocuments, "mruDocuments"); get(e, p.mainWindowHeight, "mainWindowHeight"); get(e, p.mainWindowWidth, "mainWindowWidth"); } catch (doc_element_error const&) { // we do not let this kill the program } } /** Reads a CRigDef rig definition from an XML document. * * @param parent the parent node * @param d the rig definition * @param name the name of the rig definition */ void CSailDoc::get ( const QDomNode &parent, CRigDef &d, const QString &name ) { QDomElement e = findElement( parent, "CRigDef", name); get(e, d.rigID, "rigID"); /** read fore triangle data */ get(e, d.foreI, "foreI"); get(e, d.foreJ, "foreJ"); /** read mast data */ get(e, d.MHeight, "MHeight"); get(e, d.MCord, "MCord"); get(e, d.MWidth, "MWidth"); get(e, d.MRakeM, "MRakeM"); get(e, d.MRakeD, "MRakeD"); get(e, d.MBase, "MBase"); get(e, d.MRnd, "MRnd"); get(e, d.MRndPos, "MRndPos"); /** read shrouds data */ get(e, d.CSH, "CSH"); get(e, d.CSB, "CSB"); get(e, d.LSB, "LSB"); /** read spreaders data */ get(e, d.SPNB, "SPNB"); get(e, d.SPH[0], "SPH0"); get(e, d.SPH[1], "SPH1"); get(e, d.SPH[2], "SPH2"); get(e, d.SPH[3], "SPH3"); get(e, d.SPW[0], "SPW0"); get(e, d.SPW[1], "SPW1"); get(e, d.SPW[2], "SPW2"); get(e, d.SPW[3], "SPW3"); /** read mainsail data */ get(e, d.BAD, "BAD"); get(e, d.HAD, "HAD"); // } /************************************************************************** Output **************************************************************************/ /** Puts an integer value to an XML document. */ void CSailDoc::put(QDomNode &parent, const int &i, const QString &name ) { QDomElement e = createElement("int",name,QString::number(i)); parent.appendChild(e); } /** Puts an unsigned integer value to an XML document. */ void CSailDoc::put(QDomNode &parent, const unsigned int &i, const QString &name ) { put(parent, int(i), name); } /** Puts a real value to an XML document. */ void CSailDoc::put(QDomNode &parent, const real &r, const QString &name ) { QDomElement e = createElement("real",name, QString::number(r)); parent.appendChild(e); } /** Puts a std::string value to an XML document. */ void CSailDoc::put(QDomNode &parent, const std::string &s, const QString &name ) { QDomElement e = createElement("string", name, QString::fromStdString(s)); parent.appendChild(e); } /** Puts a QString value to an XML document. */ void CSailDoc::put(QDomNode &parent, const QString &s, const QString &name ) { QDomElement e = createElement("string", name, s); parent.appendChild(e); } /** Puts a CPoint3d to an XML document. */ void CSailDoc::put(QDomNode &parent, const CPoint3d &p, const QString &name ) { QDomElement e = createElement("CPoint3d",name); parent.appendChild(e); put(e, p.x(), "x"); put(e, p.y(), "y"); put(e, p.z(), "z"); } /** Puts an enumBoatElementType enumerated Boat Element Type to an XML document. */ void CSailDoc::put(QDomNode &parent, const enumBoatElementType &t, const QString &name ) { QString value; switch (t) { case HULLDEF: value = "HULLDEF"; break; case SAILDEF: value = "SAILDEF"; break; case RIGDEF: value = "RIGDEF"; break; case PANELGROUP: value = "PANELGROUP"; break; } QDomElement e = createElement("enumBoatElementType",name,value); parent.appendChild(e); } /** Puts an enumPanelGroupType enumerated Panel Group Type to an XML document. */ void CSailDoc::put(QDomNode &parent, const enumPanelGroupType &t, const QString &name ) { QString value; switch (t) { case SAIL: value = "SAIL"; break; case RIG: value = "RIG"; break; case HULL: value = "HULL"; break; } QDomElement e = createElement("enumPanelGroupType",name,value); parent.appendChild(e); } /** Puts an enumSailCut enumerated Sail Cut Type to an XML document. */ void CSailDoc::put(QDomNode &parent, const enumSailCut &c, const QString &name ) { QString value; switch (c) { case CROSS: value = "CROSS"; break; case TWIST: value = "TWIST"; break; case HORIZONTAL: value = "HORIZONTAL"; break; case VERTICAL: value = "VERTICAL"; break; case RADIAL: value = "RADIAL"; break; case MITRE: value = "MITRE"; break; case MITRE2: value = "MITRE2"; break; } QDomElement e = createElement("enumSailCut",name,value); parent.appendChild(e); } /** Puts an enumSailType enumerated Sailf Type to an XML document. */ void CSailDoc::put(QDomNode &parent, const enumSailType &t, const QString &name ) { QString value; switch (t) { case MAINSAIL: value = "MAINSAIL"; break; case JIB: value = "JIB"; break; case WING: value = "WING"; break; } QDomElement e = createElement("enumSailType",name,value); parent.appendChild(e); } /** Puts a CHullDef hull definition to an XML document. */ void CSailDoc::put(QDomNode &parent, const CHullDef &d, const QString &name ) { QDomElement e = createElement("CHullDef",name); parent.appendChild(e); put(e, d.hullID, "hullID"); /** write hull bottom data */ put(e, d.BLWL, "BLWL"); put(e, d.BfwdHeight, "BfwdHeight"); put(e, d.BaftHeight, "BaftHeight"); put(e, d.BSlopeA, "BSlopeA"); put(e, d.BBW, "BBW"); put(e, d.BBWPos, "BBWPos"); put(e, d.BaftW, "BaftW"); put(e, d.BDeadriseA, "BDeadriseA"); put(e, d.BSweepA, "BSweepA"); put(e, d.BfwdShape, "BfwdShape"); put(e, d.BaftShape, "BaftShape"); /** write hull deck data */ put(e, d.DfwdHeight, "DfwdHeight"); put(e, d.DaftHeight, "DaftHeight"); put(e, d.DSlopeA, "DSlopeA"); /** write hull stem angle */ put(e, d.StemA, "StemA"); /** write hull transom angle */ put(e, d.TransomA, "TransomA"); /** write hull side planks data */ put(e, d.NBPlank, "NBPlank"); put(e, d.TopPlankA, "TopPlankA"); put(e, d.LowPlankA, "lowPlankA"); // put(e, d.AutoPlank, "AutoPlank"); // } /** Puts a CSailDef sail definition to an XML document. * NEW members shall be added at THE END OF THE LIST in order * to maintain backward comaptibility of files. * * See also CSailDoc::get(QDomNode &parent, const CSailDef &d, const QString &name ) */ void CSailDoc::put(QDomNode &parent, const CSailDef &d, const QString &name ) { QDomElement e = createElement("CSailDef",name); parent.appendChild(e); /** write Sail cut and Sail type */ put(e, d.sailCut, "sailCut"); put(e, d.sailType, "sailType"); /** write Sail Boat data */ put(e, d.LOA, "LOA"); put(e, d.foreI, "foreI"); put(e, d.foreJ, "foreJ"); put(e, d.tackX, "tackX"); put(e, d.tackY, "tackY"); /** write Sides of the sail */ put(e, d.luffL, "luffL"); put(e, d.rake, "rake"); put(e, d.gaffDeg, "gaffDeg"); put(e, d.gaffL, "gaffL"); put(e, d.footL, "footL"); put(e, d.leechL, "leechL"); /** write Shape of sail sides */ put(e, d.luffR, "luffR"); put(e, d.gaffR, "gaffR"); put(e, d.leechR, "leechR"); put(e, d.footR, "footR"); put(e, d.luffRP, "luffRP"); put(e, d.gaffRP, "gaffRP"); put(e, d.leechRP, "leechRP"); put(e, d.footRP, "footRP"); /** write sail Cloth width, Seam and Hems width */ put(e, d.clothW, "clothW"); put(e, d.seamW, "seamW"); put(e, d.leechHemW, "leechHemW"); put(e, d.hemsW, "hemsW"); /** write sail Twist angle*/ put(e, d.twistDeg, "twistDeg"); /** write sail Sheeting angle*/ put(e, d.sheetDeg, "sheetDeg"); /** write sail Mould */ put(e, d.mould, "mould"); //** NOTE: this is the point at which sail data evolutions start */ /** write sail ID */ put(e, d.sailID, "sailID"); /** write sail Radial sections */ put(e, d.nbSections, "nbSections"); /** write sail Radial gores */ put(e, d.nbGores, "nbGores"); /** write sail Luff gores */ put(e, d.nbLuffGores, "nbLuffGores"); /** write sail Wing dihedral angle */ put(e, d.dihedralDeg, "dihedralDeg"); /** write sail Foot hem width */ put(e, d.footHemW, "footHemW"); /** NOTE: write here below future new elements of sail */ // } /** Puts a CSide sail side to an XML document. */ void CSailDoc::put(QDomNode &parent, const CSide &s, const QString &name ) { QDomElement e = createElement("CSide",name); parent.appendChild(e); put_vector(e, s, "point"); } /** Puts a CPanel sail panel to an XML document. */ void CSailDoc::put(QDomNode &parent, const CPanel &p, const QString &name ) { QDomElement e = createElement("CPanel",name); parent.appendChild(e); put(e, p.left, "left"); put(e, p.top, "top"); put(e, p.right, "right"); put(e, p.bottom, "bottom"); put(e, p.hasHems, "hasHems"); if (p.hasHems) { put(e, p.cutLeft, "cutLeft"); put(e, p.cutTop, "cutTop"); put(e, p.cutRight, "cutRight"); put(e, p.cutBottom, "cutBottom"); } } /** Puts a CPanelGroup to an XML document. */ void CSailDoc::put(QDomNode &parent, const CPanelGroup &g, const QString &name ) { QDomElement e = createElement("CPanelGroup",name); parent.appendChild(e); put_vector(e, g, "panel"); put(e, g.title, "title"); put_vector(e, g.child, "child"); put(e, g.type, "type"); } /** Puts a CProfile sail profile to an XML document. */ void CSailDoc::put(QDomNode &parent, const CProfile &p, const QString &name ) { QDomElement e = createElement("CProfile",name); parent.appendChild(e); put(e, p.getDepth(), "depth"); put(e, p.getLeech(), "kleech"); put(e, p.getLuff(), "kluff"); } /** Puts a CSailMould sail mould to an XML document. */ void CSailDoc::put(QDomNode &parent, const CSailMould &m, const QString &name ) { QDomElement e = createElement("CSailMould",name); parent.appendChild(e); put(e, m.vertpos, "vertpos"); put_vector(e, m.profile, "profile"); } /** Put a CBoatDef boat definition to an XML document. */ void CSailDoc::put(QDomNode &parent, const CBoatDef &d, const QString &name ) { QDomElement e = createElement("CBoatDef",name); parent.appendChild(e); put_vector(e, d, "element"); } /** Put a CBoatElement elements of a boat (sail, hull, rig) to an XML document. */ void CSailDoc::put(QDomNode &parent, const CBoatElement &s, const QString &name ) { QDomElement e = createElement("CBoatElement",name); parent.appendChild(e); put(e, s.filename, "filename"); put(e, s.type, "type"); put(e, s.origin, "origin"); put(e, (CPanelGroup&)s, "panelgroup"); } /** Puts a CPrefs preferences to an XML document. */ void CSailDoc::put(QDomNode &parent, const CPrefs& p, const QString& name) { QDomElement e = createElement("CPrefs",name); parent.appendChild(e); put(e, p.language, "language"); put_vector(e, p.mruDocuments, "mruDocuments"); put(e, p.mainWindowHeight, "mainWindowHeight"); put(e, p.mainWindowWidth, "mainWindowWidth"); } /** Puts a CRigDef rig definition to an XML document. */ void CSailDoc::put(QDomNode &parent, const CRigDef &d, const QString &name ) { QDomElement e = createElement("CRigDef",name); parent.appendChild(e); put(e, d.rigID, "rigID"); /** write rig fore triangle */ put(e, d.foreI, "foreI"); put(e, d.foreJ, "foreJ"); /** write rig mast data*/ put(e, d.MHeight, "MHeight"); put(e, d.MCord, "MCord"); put(e, d.MWidth, "MWidth"); put(e, d.MRakeM, "MRakeM"); put(e, d.MRakeD, "MRakeD"); put(e, d.MBase, "MBase"); put(e, d.MRnd, "MRnd"); put(e, d.MRndPos, "MRndPos"); /** write rig shrouds data */ put(e, d.CSH, "CSH"); put(e, d.CSB, "CSB"); put(e, d.LSB, "LSB"); /** write rig spreaders data */ put(e, d.SPNB, "SPNB"); put(e, d.SPH[0], "SPH0"); put(e, d.SPH[1], "SPH1"); put(e, d.SPH[2], "SPH2"); put(e, d.SPH[3], "SPH3"); put(e, d.SPW[0], "SPW0"); put(e, d.SPW[1], "SPW1"); put(e, d.SPW[2], "SPW2"); put(e, d.SPW[3], "SPW3"); /** write rig mainsail data */ put(e, d.BAD, "BAD"); put(e, d.HAD, "HAD"); // } /** Writes the CSailDoc document to file. * * @throws an exception if writing failed. */ void CSailDoc::toFile(const QString &filename) { QFile f( filename ); if ( !f.open(QIODevice::WriteOnly) ) throw write_error("CSailDoc::toFile : cannot open file for write access!"); f.write(toByteArray()); f.close(); } sailcut-1.5.0/src/saildoc.h000066400000000000000000000150661477005247400155610ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILDOC_H #define SAILDOC_H #include #include "filewriter.h" #include "sailcpp/panelgroup.h" #include "sailcpp/boatdef.h" #include "sailcpp/hulldef.h" #include "sailcpp/rigdef.h" #include "sailcpp/saildef.h" #include "prefs.h" class doc_element_error : public std::runtime_error { public: doc_element_error(const std::string &message) : std::runtime_error(message) { std::cout << what() << std::endl; } }; /** @defgroup FileIo File input and output */ /** This class handles all input and output to Sailcut XML documents. * * @ingroup FileIo */ class CSailDoc : protected QDomDocument { public: CSailDoc(); CSailDoc( const QString &filename ); /** Creates an element of the given type. */ QDomElement createElement(const QString &type) { return QDomDocument::createElement(type); }; QDomElement createElement(const QString &type, const QString &name); QDomElement createElement(const QString &type, const QString &name, const QString& value); QDomElement findElement(const QDomNode &parent, const QString &type, const QString &name); // input void get (const QDomNode &parent, int &i, const QString &name ); void get (const QDomNode &parent, unsigned int &i, const QString &name ); void get (const QDomNode &parent, real &r, const QString &name ); void get (const QDomNode &parent, std::string &s, const QString &name ); void get (const QDomNode &parent, QString &s, const QString &name ); void get (const QDomNode &parent, CPoint3d &p, const QString &name ); void get (const QDomNode &parent, enumBoatElementType &t, const QString &name ); void get (const QDomNode &parent, enumPanelGroupType &t, const QString &name ); void get (const QDomNode &parent, enumSailCut &c, const QString &name ); void get (const QDomNode &parent, enumSailType &t, const QString &name ); void get (const QDomNode &parent, CHullDef &d, const QString &name ); void get (const QDomNode &parent, CSailDef &d, const QString &name ); void get (const QDomNode &parent, CSide &s, const QString &name ); void get (const QDomNode &parent, CPanel &p, const QString &name ); void get (const QDomNode &parent, CBoatDef &d, const QString &name ); void get (const QDomNode &parent, CBoatElement &s, const QString &name ); void get (const QDomNode &parent, CPanelGroup &g, const QString &name ); void get (const QDomNode &parent, CProfile &p, const QString &name ); void get (const QDomNode &parent, CSailMould &m, const QString &name ); void get (const QDomNode &parent, CPrefs &p, const QString &name ); void get (const QDomNode &parent, CRigDef &d, const QString &name ); // output void put(QDomNode &parent, const int &i, const QString &name ="" ); void put(QDomNode &parent, const unsigned int &i, const QString &name ="" ); void put(QDomNode &parent, const real &r, const QString &name ="" ); void put(QDomNode &parent, const std::string &s, const QString &name="" ); void put(QDomNode &parent, const QString &s, const QString &name="" ); void put(QDomNode &parent, const CPoint3d &p, const QString &name="" ); void put(QDomNode &parent, const enumBoatElementType &t, const QString &name=""); void put(QDomNode &parent, const enumPanelGroupType &t, const QString &name="" ); void put(QDomNode &parent, const enumSailCut &c, const QString &name="" ); void put(QDomNode &parent, const enumSailType &t, const QString &name="" ); void put(QDomNode &parent, const CBoatDef &d, const QString &name="" ); void put(QDomNode &parent, const CBoatElement &s, const QString &name="" ); void put(QDomNode &parent, const CHullDef &d, const QString &name="" ); void put(QDomNode &parent, const CSailDef &d, const QString &name="" ); void put(QDomNode &parent, const CSide &s, const QString &name="" ); void put(QDomNode &parent, const CPanel &p, const QString &name="" ); void put(QDomNode &parent, const CPanelGroup &g, const QString &name="" ); void put(QDomNode &parent, const CProfile &p, const QString &name="" ); void put(QDomNode &parent, const CSailMould &m, const QString &name="" ); void put(QDomNode &parent, const CPrefs &p, const QString &name="" ); void put(QDomNode &parent, const CRigDef &d, const QString &name="" ); void toFile(const QString &filename); /** the toplevel element */ QDomElement top; protected: /** Reads a vector of elements from an XML document. * * @param parent the parent node * @param v the vector * @param name the name of the vector */ template void get_vector (QDomNode &parent, std::vector& v, const QString &name="") { QDomElement e = findElement( parent, "vector", name); if ( e.isNull() ) throw doc_element_error(QString("CSailDoc::get(vector, " + name + ") : did not find requested element").toStdString()); unsigned int size = e.attributes().namedItem("size").nodeValue().toInt(); v.resize(size); for ( unsigned int i = 0; i < size; i++) { get (e, v[i], QString::number(i)); } } /** Writes a vector of elements to an XML document. * * @param parent the parent node * @param v the vector * @param name the name of the vector */ template void put_vector(QDomNode &parent, const std::vector& v, const QString &name="") { QDomElement e = createElement("vector",name); e.setAttribute("size", (unsigned int)v.size()); parent.appendChild(e); for (unsigned int i =0; i #include "sailpainter.h" #include "sailcpp/sailcalc.h" #include "sailcpp/panelgroup.h" #define MIN_DISTANCE 5 QPolygonF& operator<<(QPolygonF &poly, const CPoint3d &p) { poly << QPointF(p.x(), - p.y()); return poly; } /** Draws a single panel of a sail. */ void CSailPainter::draw(const CPanel &panel) { CSide::const_iterator iter; CSide::const_reverse_iterator riter; QPolygonF poly; for (iter = panel.bottom.begin(); iter != panel.bottom.end(); iter++) poly << *iter; for (iter = panel.right.begin(); iter != panel.right.end(); iter++) poly << *iter; for (riter = panel.top.rbegin(); riter != panel.top.rend(); riter++) poly << *riter; for (riter = panel.left.rbegin(); riter != panel.left.rend(); riter++) poly << *riter; drawPolyline(poly); if (panel.hasHems) { // switch pen to red const QPen oldPen = pen(); setPenColor(Qt::red); poly = QPolygonF(); for (iter = panel.cutBottom.begin(); iter != panel.cutBottom.end(); iter++) poly << *iter; for (iter = panel.cutRight.begin(); iter != panel.cutRight.end(); iter++) poly << *iter; for (riter = panel.cutTop.rbegin(); riter != panel.cutTop.rend(); riter++) poly << *riter; for (riter = panel.cutLeft.rbegin(); riter != panel.cutLeft.rend(); riter++) poly << *riter; drawPolyline(poly); // reset pen color setPen(oldPen); } } /** Draws the label of a panel. */ void CSailPainter::drawLabels(const CPanel &panel) { drawTextCentered(panel.label.origin, QStringList(QString::fromStdString(panel.label.name))); } /** Draws a complete sail. */ void CSailPainter::draw(const CPanelGroup &sail) { unsigned int i; // set pen color const QPen oldPen = pen(); if ( sail.type == HULL ) setPenColor(Qt::darkGreen); else if ( sail.type == RIG ) setPenColor(Qt::darkRed); else setPenColor(Qt::blue); for (i = 0; i < sail.size(); i++) draw(sail[i]); for (i = 0; i < sail.child.size(); i++) draw(sail.child[i]); // reset pen color setPen(oldPen); } /** Print a label with a line to a point. * * @param pDisp the display point coordinates * @param lst a list of lines of text to print * @param angle */ void CSailPainter::drawArrowLabel(const CPoint3d &pDisp, const QStringList &lst, const real angle) { CVector3d textDim = textSize(lst); CPoint3d arrowStart; CPoint3d arrowEnd; CVector3d v = rotateNormalized(angle, CVector3d(1, 0, 0)); if (fabs(angle) > .1*M_PI) arrowEnd = pDisp + real( 2 * fontMetrics().height()) * v; else arrowEnd = pDisp + real( 1.3 * fontMetrics().height()) * v; CVector3d v1 = rotateNormalized(M_PI/6, v); arrowStart = pDisp + real(.3 * fontMetrics().height()) * v1; // the distance from the arrow end to the center of the text box real dist; if (fabs(v.x() * textDim.y()) < fabs(textDim.x() * v.y())) { // the arrow touches the text box on the top or bottom sides dist = fabs(textDim.y() / (2.0 * sin(angle))); } else { // the arrow touches the text box on the left or right sides dist = fabs(textDim.x() / (2.0 * cos(angle))); } CPoint3d textCenter = arrowEnd + 1.2 * dist * v; drawLine(int(pDisp.x()), -int(pDisp.y()), int(arrowStart.x()), -int(arrowStart.y())); drawLine(int(pDisp.x()), -int(pDisp.y()), int(arrowEnd.x()), -int(arrowEnd.y())); drawTextCentered(textCenter, lst); } /** Draw a label representing a point's coordinates. * * @param point * @param angle */ void CSailPainter::drawCoord(const CPoint3d &point, const real angle) { // build list of lines to print QStringList lst; lst.append(QString("X=") + QString::number(point.x(), 'f', 1)); lst.append(QString("Y=") + QString::number(point.y(), 'f', 1)); drawArrowLabel(point, lst, angle); } /** Draw a label representing a distance. * * @param pDisp the display point coordinates * @param vValue the distances * @param angle */ void CSailPainter::drawDelta(const CPoint3d &pDisp, const CVector3d &vValue, real angle) { // build list of lines to print QStringList lst; lst.append(QString("dX=") + QString::number(vValue.x(), 'f', 1)); lst.append(QString("dY=") + QString::number(vValue.y(), 'f', 1)); drawArrowLabel(pDisp, lst, angle); } /** Draws a cross at a given Point position. */ void CSailPainter::drawCross(const CPoint3d &p, const real size) { drawLine(int(p.x()), -int(p.y()+ .5 * size), int(p.x()), -int(p.y() -.5 * size)); drawLine(int(p.x() + .5 * size), -int(p.y()), int(p.x() - .5 * size), -int(p.y())); } /** Draw text centered at the given position. */ void CSailPainter::drawTextCentered(const CPoint3d &p, const QString &str) { drawTextCentered(p, QStringList(str)); } /** Draw text centered at the given position. */ void CSailPainter::drawTextCentered(const CPoint3d &p, const QStringList &lst) { CVector3d dim = textSize(lst); int i; real xPos = p.x() - 0.5 * dim.x(); real yPos = -p.y() + 0.75 * fontMetrics().height() - 0.5 * dim.y(); for (i = 0; i < lst.size(); i++) { drawText(int(xPos), int(yPos), lst.at(i)); yPos += fontMetrics().height(); } } /** Draw all the sail's panel labels. */ void CSailPainter::drawLabels(const CPanelGroup &sail) { unsigned int i; for (i = 0; i < sail.size(); i++) drawLabels(sail[i]); for (i = 0; i < sail.child.size(); i++) drawLabels(sail.child[i]); } /** Draw the markers for a panel. * * @param currentPanel */ void CSailPainter::drawMarkers(const CPanel ¤tPanel) { unsigned int npt = 0; real dx=0, dy=0; // top fwd corners drawCoord(currentPanel.top.front(), .6*M_PI); // top middle npt = int ( (currentPanel.top.size() -1) /2 ); if ( CVector3d(currentPanel.top[npt] - currentPanel.top.front()).length() > MIN_DISTANCE ) { dx = CVector3d::dotProduct(currentPanel.top[npt] - currentPanel.top.front(), CVector3d(currentPanel.top.back() - currentPanel.top.front() ).normalized()); dy = Distance3d(currentPanel.top[npt] , currentPanel.top.front() , currentPanel.top.back() ); drawDelta(currentPanel.top[npt], CVector3d(dx, dy, 0), .45*M_PI); } // top aft corner if ( CVector3d(currentPanel.top.back() - currentPanel.top.front()).length() > MIN_DISTANCE ) drawCoord(currentPanel.top.back(), .25*M_PI); // right middle npt = (currentPanel.right.size() -1)/2; drawCoord(currentPanel.right[npt], 0.05*M_PI); // left side if ( CVector3d(currentPanel.left.back() - currentPanel.left.front()).length() > MIN_DISTANCE ) { // left bottom drawCoord(currentPanel.left.front(), -.7*M_PI); // left middle npt = (currentPanel.left.size() -1)/2; drawCoord(currentPanel.left[npt], .95*M_PI); // left upper middle if ( CVector3d(currentPanel.left[npt+1] - currentPanel.left[npt]).length() > MIN_DISTANCE ) drawCoord(currentPanel.left[npt+1], .8*M_PI); } // bottom intermediate fwd npt = int ( (currentPanel.bottom.size() -1) /5 ); if ( CVector3d(currentPanel.bottom[npt] - currentPanel.bottom.front()).length() > MIN_DISTANCE ) { dx = CVector3d::dotProduct(currentPanel.bottom[npt] - currentPanel.bottom.front(), CVector3d(currentPanel.bottom.back() - currentPanel.bottom.front()).normalized()); dy = Distance3d( currentPanel.bottom[npt] , currentPanel.bottom.front() , currentPanel.bottom.back() ); drawDelta(currentPanel.bottom[npt], CVector3d(dx, dy, 0), -.65*M_PI); } // bottom intermediate middle npt = int ( (currentPanel.bottom.size() -1) /2 ); dx = CVector3d::dotProduct(currentPanel.bottom[npt] - currentPanel.bottom.front(), CVector3d(currentPanel.bottom.back() - currentPanel.bottom.front()).normalized()); dy = Distance3d( currentPanel.bottom[npt] , currentPanel.bottom.front() , currentPanel.bottom.back() ); drawDelta(currentPanel.bottom[npt], CVector3d(dx, dy, 0), -.55*M_PI); // bottom intermediate aft npt = int ( (currentPanel.bottom.size() -1) *4/5 ); if ( CVector3d(currentPanel.bottom[npt] - currentPanel.bottom.back()).length() > MIN_DISTANCE ) { dx = CVector3d::dotProduct(currentPanel.bottom[npt] - currentPanel.bottom.front(), CVector3d(currentPanel.bottom.back() - currentPanel.bottom.front()).normalized()); dy = Distance3d( currentPanel.bottom[npt] , currentPanel.bottom.front(), currentPanel.bottom.back() ); drawDelta(currentPanel.bottom[npt], CVector3d(dx, dy, 0), -.4*M_PI ); } // bottom aft corner drawCoord(currentPanel.bottom.back(), -.25*M_PI); } /** Draw the markers for a full sail. * * @param sail */ void CSailPainter::drawMarkers(const CPanelGroup &sail) { for (unsigned int i = 0; i < sail.size(); i++) drawMarkers(sail[i]); } /** Set the font size. * * @param size * @param zoom */ void CSailPainter::setFontSize(const real size, const real zoom) { // set the font size for labeling function of zoom QFont myfont = font(); myfont.setPointSizeF(real(zoom * size * window().height()) / device()->height()); setFont(myfont); } /** Set the pen color. * * Unlike setPen(QColor), this does not change the pen width. */ void CSailPainter::setPenColor(const QColor &color) { QPen p = pen(); p.setColor(color); setPen(p); } /** Set the default pen width. * * The width is set to 0, indicating a 1 pixel cosmetic pen. */ void CSailPainter::setPenWidth() { QPen p = pen(); p.setWidth(0); setPen(p); } /** Set coordinate system to match the logical viewport. * * @param lRect the logical viewport rectangle */ void CSailPainter::setWindow(const CRect3d& lRect) { QPainter::setWindow( int(lRect.min.x()), int(-lRect.max.y()), int(lRect.width()), int(lRect.height()) ); } /** Return text size vector. */ CVector3d CSailPainter::textSize(const QStringList &lst) { CVector3d v(0, 0, 0); int i; // calculate text height and width by scanning the list of lines for (i = 0; i < lst.size(); i++) { real lineWidth = fontMetrics().boundingRect(lst.at(i)).width(); if (lineWidth > v.x()) v.setX(lineWidth); v.setY(v.y() + fontMetrics().height()); } return v; } /** Return the viewport rectangle. */ CRect3d CSailPainter::viewRect() const { return CRect3d(CPoint3d(0,0,0), CPoint3d(viewport().width(), viewport().height(), 0)); } /** Construct a new CTextPainter. */ CTextPainter::CTextPainter(QPaintDevice *pd) : CSailPainter(pd) { } /** Reset the text cursors to its initial position. */ void CTextPainter::printReset() { xPos = fontMetrics().maxWidth() * 4; yPos = fontMetrics().height() * 2; } /** Print a header banner (used at the top of a for example). * * @param title the title to print */ void CTextPainter::printHeader(const QString title) { QString btitle = " " + title + " "; drawText(int(xPos), int(yPos), btitle); // draw box around header const QRect textBox = fontMetrics().boundingRect(btitle); drawRect(xPos, yPos - textBox.height(), textBox.width(), 1.5 * textBox.height()); yPos += 1.5 * textBox.height(); } /** Print a data section title. * * @param title the title of the section */ void CTextPainter::printDataSection(const QString title) { yPos += 0.5 * fontMetrics().height(); drawText(int(xPos), int(yPos), title); yPos += fontMetrics().height(); } /** Print a line of data. * * @param title the title for the current line of data * @param data0 first value * @param data1 second value * @param data2 third value */ void CTextPainter::printDataLine(const QString title, const QString data0, const QString data1, const QString data2) { unsigned int x1 = int(xPos + 2 * fontMetrics().maxWidth()); unsigned int x2 = int(x1 + 26 * fontMetrics().maxWidth()); unsigned int x3 = int(x2 + 13 * fontMetrics().maxWidth()); unsigned int x4 = int(x3 + 13 * fontMetrics().maxWidth()); drawText(x1, int(yPos), title); drawText(x2, int(yPos), data0); drawText(x3, int(yPos), data1); drawText(x4, int(yPos), data2); yPos += .8 * fontMetrics().height(); } sailcut-1.5.0/src/sailpainter.h000066400000000000000000000051571477005247400164560ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILPAINTER_H #define SAILPAINTER_H #include #include class CSide; class CPanel; class CPanelLabel; class CPanelGroup; /** A sail painter. * * @see CSailDispLabel */ class CSailPainter : public QPainter { public: /** Construct a new sail painter. * * @param dev the paint device we are operating on */ CSailPainter(QPaintDevice *dev) : QPainter(dev) {}; void draw(const CPanel &panel); void draw(const CPanelGroup &sail); void drawArrowLabel(const CPoint3d &pDisp, const QStringList &lst, const real angle); void drawCoord(const CPoint3d &p, const real angle); void drawDelta(const CPoint3d &pDisp, const CVector3d &vValue, const real angle); void drawCross(const CPoint3d &p, const real size); void drawTextCentered(const CPoint3d &p, const QString &str); void drawTextCentered(const CPoint3d &p, const QStringList &lst); void drawLabels(const CPanel &panel); void drawLabels(const CPanelGroup &sail); void drawMarkers(const CPanel &panel); void drawMarkers(const CPanelGroup &sail); void setFontSize(const real size, const real zoom); void setPenColor(const QColor &color); void setPenWidth(); void setWindow(const CRect3d& lRect); CVector3d textSize(const QStringList &lst); CRect3d viewRect() const; }; /** A text painter. */ class CTextPainter : public CSailPainter { public: CTextPainter(QPaintDevice *pd); void printReset(); void printHeader(const QString title); void printDataSection(const QString title); void printDataLine(const QString title, const QString data0 = "", const QString data1 = "", const QString data2 = ""); protected: /** current x offset for text output */ real xPos; /** current y offset for text output */ real yPos; }; #endif sailcut-1.5.0/src/sailprinter.cpp000066400000000000000000000224171477005247400170300ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "sailprinter.h" #include #include #include "sailcpp/sailcalc.h" #include "sailcpp/saildef.h" #include "sailcpp/panelgroup.h" #include "sailcpp/sailcalc.h" double CPrinter::scaleToFit(QPaintDevice* device) const { Q_UNUSED(device); return -1; } /** Print the current sail data sheet. * * @param painter * @param fontsize */ void CSailDataPrinter::print(CTextPainter *painter, int, real scale, real fontsize) const { Q_UNUSED(scale); QString text2=" ", text3=" "; painter->setFontSize(fontsize, 1); painter->setPenColor(Qt::black); painter->printReset(); // text of page header QString sailID = QString::fromStdString(saildef.sailID); painter->printHeader(tr("Sailcut CAD data sheet") + (( sailID.length() > 0 ) ? " - " + sailID : " ")); // sail cut and type switch (saildef.sailType ) { case MAINSAIL: text2 = tr("Mainsail"); break; case JIB: text2 = tr("Jib"); break; case WING: text2 = tr("Wing")+" @ " + QString::number(saildef.dihedralDeg) + tr("deg"); break; } painter->printDataLine(tr("Sail type"), text2, " "); text3 = " "; switch ( saildef.sailCut ) { case CROSS: text2 = tr("Cross Cut"); break; case HORIZONTAL: text2 = tr("Horizontal Cut"); break; case RADIAL: text2 = tr("Radial Cut"); text3 = QString::number(saildef.nbSections) + " " + tr("sections") + ", "; text3 += QString::number(saildef.nbGores) + " " + tr("head gores") + ", "; text3 += QString::number(saildef.nbLuffGores) + " " + tr("luff gores") + "."; break; case TWIST: text2 = tr("Twist Foot Cut"); break; case VERTICAL: text2 = tr("Vertical Cut"); break; case MITRE: text2 = tr("Mitre Cut"); break; case MITRE2: text2 = tr("Mitre Cut 2"); break; } painter->printDataLine(tr("Sail layout"), text2, text3); // boat data painter->printDataSection(tr("Rig")); painter->printDataLine(tr("Boat LOA"), QString::number(saildef.LOA), "mm"); painter->printDataLine(tr("Luff rake"), QString::number(saildef.rake), "mm"); painter->printDataLine(tr("Tack position X"), QString::number(saildef.tackX), "mm"); painter->printDataLine(tr("Tack height Y"), QString::number(saildef.tackY), "mm"); painter->printDataLine(tr("Fore triangle hoist I"), QString::number(saildef.foreI), "mm"); painter->printDataLine(tr("Fore triangle base J"), QString::number(saildef.foreJ), "mm"); // sides of the sail painter->printDataSection(tr("Sail dimensions")); painter->printDataLine(tr("Luff length"), QString::number(saildef.luffL), "mm"); painter->printDataLine(tr("Foot length"), QString::number(saildef.footL), "mm"); painter->printDataLine(tr("Leech length"), QString::number(saildef.leechL), "mm"); painter->printDataLine(tr("Gaff length"), QString::number(saildef.gaffL), "mm"); painter->printDataLine(tr("Gaff angle wrt luff"), QString::number(saildef.gaffDeg), "deg"); // shape of sides painter->printDataSection(tr("Shape of edges")); painter->printDataLine(tr("Luff round"), QString::number(saildef.luffR), "mm"); painter->printDataLine(tr("Luff round position"), QString::number(saildef.footRP), "%"); painter->printDataLine(tr("Foot round"), QString::number(saildef.footR), "mm"); painter->printDataLine(tr("Foot round position"), QString::number(saildef.footRP), "%"); painter->printDataLine(tr("Leech round"), QString::number(saildef.leechR), "mm"); painter->printDataLine(tr("Leech round position"), QString::number(saildef.leechRP), "%"); painter->printDataLine(tr("Gaff round"), QString::number(saildef.gaffR), "mm"); painter->printDataLine(tr("Gaff round position"), QString::number(saildef.gaffRP), "%"); // sail setting painter->printDataSection(tr("Sail settings")); painter->printDataLine(tr("Twist angle"), QString::number(saildef.twistDeg), "deg"); painter->printDataLine(tr("Sheeting angle"), QString::number(saildef.sheetDeg), "deg"); // cloth width, seam and hems width painter->printDataSection(tr("Cloth seams and hems")); painter->printDataLine(tr("Cloth width"), QString::number(saildef.clothW), "mm"); painter->printDataLine(tr("Seams width"), QString::number(saildef.seamW), "mm"); painter->printDataLine(tr("Leech hem width"), QString::number(saildef.leechHemW), "mm"); painter->printDataLine(tr("Foot hem width"), QString::number(saildef.footHemW), "mm"); painter->printDataLine(tr("Other hems width"), QString::number(saildef.hemsW), "mm"); // sail mould painter->printDataSection(tr("Sail mould")); painter->printDataLine("", tr("Luff factor"), tr("Depth"), tr("Leech factor")); painter->printDataLine( tr("Top profile"), QString::number( saildef.mould.profile[2].getLuff() ), QString::number( saildef.mould.profile[2].getDepth()*100 )+ "%", QString::number( saildef.mould.profile[2].getLeech()*50)); painter->printDataLine( tr("Mid profile at h = ") + QString::number( saildef.mould.vertpos ) + "%", QString::number( saildef.mould.profile[1].getLuff() ), QString::number( saildef.mould.profile[1].getDepth()*100 )+"%", QString::number( saildef.mould.profile[1].getLeech()*50)); painter->printDataLine( tr("Bottom profile"), QString::number( saildef.mould.profile[0].getLuff() ), QString::number( saildef.mould.profile[0].getDepth()*100 )+"%", QString::number( saildef.mould.profile[0].getLeech()*50)); } /** Print a developed sail panel by panel. * * @param painter * @param page * @param scale * @param fontsize */ void CSailDevelPrinter::print(CTextPainter *painter, int page, real scale, real fontsize) const { // set scale CRect3d logicalRect = CRect3d(CPoint3d(0, 0, 0), CPoint3d(painter->device()->widthMM(), painter->device()->heightMM(), 0)) * (1/scale); // center view logicalRect = logicalRect + (sail.boundingRect().center() - logicalRect.center()); // set coordinate system to match the logical viewport painter->setWindow(logicalRect); painter->setFontSize(fontsize, 1); painter->setPenColor(Qt::black); painter->setPenWidth(); painter->draw(sail[page]); if (showLabels) painter->drawLabels(sail[page]); painter->drawMarkers(sail[page]); // mark corners of cloth rectangle const QPen oldPen = painter->pen(); painter->setPenColor(Qt::green); CRect3d rp = sail[page].boundingRect(); painter->drawCross(rp.min, painter->fontMetrics().height() ); painter->drawCoord(rp.min, M_PI ); painter->setPen(oldPen); /* NOTE scale factor on preview screen is not same value as in spinbox * However the correct value equal to spinbox value will be printed */ QString txt = tr("Scale")+" = %1"; txt = txt.arg(scale, 0, 'f', 3); CPoint3d pt = logicalRect.center()+ CVector3d(0,1,0)*0.47*logicalRect.height(); painter->drawTextCentered(pt, txt); } /** Print the drawing of a complete sail. * * @param painter * @param scale * @param fontsize */ void CSailDrawingPrinter::print(CTextPainter *painter, int, real scale, real fontsize) const { // set scale CRect3d logicalRect = CRect3d(CPoint3d(0, 0, 0), CPoint3d(painter->device()->widthMM(), painter->device()->heightMM(), 0)) * (1/scale); // center view logicalRect = logicalRect + (sail.boundingRect().center() - logicalRect.center()); // set coordinate system to match the logical viewport painter->setWindow(logicalRect); painter->setFontSize(fontsize, 1); painter->setPenColor(Qt::black); painter->setPenWidth(); painter->draw(sail); if (showLabels) painter->drawLabels(sail); /* NOTE scale factor on preview screen is not same value as in spinbox * However the correct value equal to spinbox value will be printed */ QString txt = tr("Scale")+" = %1"; txt = txt.arg(scale, 0, 'f', 3); CPoint3d pt = logicalRect.center()+ CVector3d(0,1,0)*0.47*logicalRect.height(); painter->drawTextCentered(pt, txt); } /** Return the scale needed to fit the developed sail in the given device. * * @param device */ double CSailDrawingPrinter::scaleToFit(QPaintDevice* device) const { Q_ASSERT(device->widthMM() > 0 && device->heightMM() > 0); const real w = device->widthMM(); const real h = device->heightMM(); return 0.8 * w / sail.boundingRect().expandToRatio(w / h).width(); } sailcut-1.5.0/src/sailprinter.h000066400000000000000000000064151477005247400164750ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILPRINTER_H #define SAILPRINTER_H #include #include "sailcpp/saildef.h" #include "sailcpp/panelgroup.h" #include "sailpainter.h" /** This is the base class used for printing. */ class CPrinter : public QObject { public: /** Return the number of pages, must be overriden. */ virtual int pages() const = 0; /** Perform the actual printing operation, must be overriden. */ virtual void print(CTextPainter *painter, int page, real scale, real fontsize) const = 0; /** Return the scale needed to fit the developed sail in the given device. * * @param device */ virtual double scaleToFit(QPaintDevice* device) const; }; /** A class for printing sail data. * * All the data is printed on a single page. */ class CSailDataPrinter : public CPrinter { Q_OBJECT public: /** The constructor. * * @param obj the sail definition to print */ CSailDataPrinter(const CSailDef &obj) : saildef(obj) {}; int pages() const { return 1; }; void print(CTextPainter *painter, int, real size, real fontsize) const; protected: /** the sail definition to print */ const CSailDef saildef; }; /** A class for printing a sail. * * All the panels are printed on a single page. */ class CSailDrawingPrinter : public CPrinter { Q_OBJECT public: /** The constructor. * * @param obj the sail to print * @param show_labels should labels be printed? */ CSailDrawingPrinter(const CPanelGroup &obj, bool show_labels = true) : sail(obj), showLabels(show_labels) {}; int pages() const { return 1; }; void print(CTextPainter *painter, int, real scale, real fontsize) const; double scaleToFit(QPaintDevice *device) const; protected: /** the sail to print */ const CPanelGroup sail; /** should the labels be printed? */ bool showLabels; }; /** A class for printing developped sail panels. * * One panel is output per page. */ class CSailDevelPrinter : public CSailDrawingPrinter { Q_OBJECT public: /** The constructor. * * @param obj the sail to print * @param show_labels should labels be printed? */ CSailDevelPrinter(const CPanelGroup &obj, bool show_labels = true) : CSailDrawingPrinter(obj, show_labels) {}; int pages() const { return sail.size(); }; void print(CTextPainter *painter, int page, real scale, real fontsize) const; }; #endif sailcut-1.5.0/src/sailtreeitem.cpp000066400000000000000000000061371477005247400171640ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "sailtreeitem.h" #include "point.xpm" #include "panel.xpm" #include "panelgroup.xpm" #include #include CSailTreeItem::CSailTreeItem(const QList &data, CSailTreeItem *parent) { parentItem = parent; itemData = data; itemIcon = NULL; } CSailTreeItem::CSailTreeItem(const CPanelGroup &data, QString name, CSailTreeItem *parent) { parentItem = parent; itemData << name; itemIcon = panelgroup_xpm; appendChild(new CSailTreeItem(data.title, "title", this)); appendChild(new CSailTreeItem(std::vector(data), "panel", this)); if (data.child.size() > 0) appendChild(new CSailTreeItem(data.child, "child", this)); } CSailTreeItem::CSailTreeItem(const CPanel &data, QString name, CSailTreeItem *parent) { parentItem = parent; itemData << name; itemIcon = panel_xpm; appendChild(new CSailTreeItem(data.left, "left", this)); appendChild(new CSailTreeItem(data.right, "right", this)); appendChild(new CSailTreeItem(data.top, "top", this)); appendChild(new CSailTreeItem(data.bottom, "bottom", this)); } CSailTreeItem::CSailTreeItem(const CPoint3d &data, QString name, CSailTreeItem *parent) { parentItem = parent; itemIcon = point_xpm; itemData << name << data.x() << data.y() << data.z(); } CSailTreeItem::CSailTreeItem(const std::string &data, QString name, CSailTreeItem *parent) { parentItem = parent; itemIcon = NULL; itemData << name << QString::fromStdString(data); } CSailTreeItem::~CSailTreeItem() { qDeleteAll(childItems); } void CSailTreeItem::appendChild(CSailTreeItem *item) { childItems.append(item); } CSailTreeItem *CSailTreeItem::child(int row) { return childItems.value(row); } int CSailTreeItem::childCount() const { return childItems.count(); } int CSailTreeItem::columnCount() const { return itemData.count(); } QVariant CSailTreeItem::data(int column) const { return itemData.value(column); } QIcon CSailTreeItem::icon() const { if (itemIcon != NULL) return QIcon(QPixmap(itemIcon)); else return QIcon(); } CSailTreeItem *CSailTreeItem::parent() { return parentItem; } int CSailTreeItem::row() const { if (parentItem) return parentItem->childItems.indexOf(const_cast(this)); return 0; } sailcut-1.5.0/src/sailtreeitem.h000066400000000000000000000044441477005247400166300ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILTREEITEM_H #define SAILTREEITEM_H #include "sailcpp/panelgroup.h" #include #include class QIcon; class CSailTreeItem { public: CSailTreeItem(const QList &data, CSailTreeItem *parent = 0); CSailTreeItem(const CPanelGroup& data, QString name, CSailTreeItem *parent = 0); CSailTreeItem(const CPanel& data, QString name, CSailTreeItem *parent = 0); CSailTreeItem(const CPoint3d& data, QString name, CSailTreeItem *parent = 0); CSailTreeItem(const std::string& data, QString name, CSailTreeItem *parent = 0); /** Constructs a CSailTreeItem representing a vector of elements. * * @param v the vector * @param name the name of the vector * @param parent the parent node */ template CSailTreeItem(const std::vector& v, QString name, CSailTreeItem *parent) { parentItem = parent; itemData << name; itemIcon = NULL; for (unsigned int i = 0; i < v.size(); i++) appendChild(new CSailTreeItem(v[i], QString::number(i), this)); } ~CSailTreeItem(); void appendChild(CSailTreeItem *child); CSailTreeItem *child(int row); int childCount() const; int columnCount() const; QVariant data(int column) const; QIcon icon() const; int row() const; CSailTreeItem *parent(); private: QList childItems; QList itemData; const char **itemIcon; CSailTreeItem *parentItem; }; #endif sailcut-1.5.0/src/sailtreemodel.cpp000066400000000000000000000061711477005247400173240ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "sailtreemodel.h" CSailTreeModel::~CSailTreeModel() { delete rootItem; } int CSailTreeModel::columnCount(const QModelIndex &parent) const { if (parent.isValid()) return static_cast(parent.internalPointer())->columnCount(); else return rootItem->columnCount(); } QVariant CSailTreeModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); CSailTreeItem *item = static_cast(index.internalPointer()); switch (role) { case Qt::DisplayRole: return item->data(index.column()); case Qt::DecorationRole: if (index.column() == 0) return item->icon(); break; default: break; } return QVariant(); } Qt::ItemFlags CSailTreeModel::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::ItemIsEnabled; return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } QVariant CSailTreeModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) return rootItem->data(section); return QVariant(); } QModelIndex CSailTreeModel::index(int row, int column, const QModelIndex &parent) const { CSailTreeItem *parentItem; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast(parent.internalPointer()); CSailTreeItem *childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); else return QModelIndex(); } QModelIndex CSailTreeModel::parent(const QModelIndex &index) const { if (!index.isValid()) return QModelIndex(); CSailTreeItem *childItem = static_cast(index.internalPointer()); CSailTreeItem *parentItem = childItem->parent(); if (parentItem == rootItem) return QModelIndex(); return createIndex(parentItem->row(), 0, parentItem); } int CSailTreeModel::rowCount(const QModelIndex &parent) const { CSailTreeItem *parentItem; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast(parent.internalPointer()); return parentItem->childCount(); } sailcut-1.5.0/src/sailtreemodel.h000066400000000000000000000037611477005247400167730ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILTREEMODEL_H #define SAILTREEMODEL_H #include #include #include #include "sailtreeitem.h" class CSailTreeModel : public QAbstractItemModel { Q_OBJECT public: template CSailTreeModel(const myType &data, QString name, QObject *parent = 0) : QAbstractItemModel(parent) { QList rootData; rootData << "Name" << "x" << "y" << "z"; rootItem = new CSailTreeItem(rootData); rootItem->appendChild(new CSailTreeItem(data, name, rootItem)); } ~CSailTreeModel(); QVariant data(const QModelIndex &index, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; private: CSailTreeItem *rootItem; }; #endif sailcut-1.5.0/src/sailviewer-panel.cpp000066400000000000000000000130611477005247400177360ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "sailviewer-panel.h" #include "sailcpp/panelgroup.h" #include #include #include #include #include /** * Constructs a CSailViewerPanel object. * * @param parent The parent widget * @param viewMode The viewing mode (shaded or wireframe) * @param show_sliders Should the elevation and azimuth sliders be displayed? * @param show_labeling Should the "Labeling" button be displayed? */ CSailViewerPanel::CSailViewerPanel(QWidget *parent, enumViewMode viewMode, bool show_sliders, bool show_labeling) : QWidget(parent), showSliders(show_sliders) { /* parameters groupbox */ if (showSliders) { /* display parameters groupbox */ grpParams = new QGroupBox( this ); QGridLayout* grpParamsLayout = new QGridLayout( grpParams ); lblAzimuthStatic = new QLabel( grpParams ); grpParamsLayout->addWidget( lblAzimuthStatic, 0, 0 ); lblAzimuth = new QLabel( grpParams ); grpParamsLayout->addWidget( lblAzimuth, 0, 1 ); lblElevationStatic = new QLabel( grpParams ); grpParamsLayout->addWidget( lblElevationStatic, 1, 0 ); lblElevation = new QLabel( grpParams ); grpParamsLayout->addWidget( lblElevation, 1, 1 ); } else { grpParams = NULL; lblAzimuthStatic = NULL; lblAzimuth = NULL; lblElevationStatic = NULL; lblElevation = NULL; } /* the drawing area */ sailDisp = new CSailViewer(this, viewMode, showSliders); sailDisp->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); /* controls groupbox */ grpControls = new QGroupBox( this ); QVBoxLayout *grpControlsLayout = new QVBoxLayout( grpControls ); btnResetView = new QPushButton( grpControls ); grpControlsLayout->addWidget( btnResetView ); btnZoomIn = new QPushButton( grpControls ); grpControlsLayout->addWidget( btnZoomIn ); btnZoomOut = new QPushButton( grpControls ); grpControlsLayout->addWidget( btnZoomOut ); if (viewMode == WIREFRAME && show_labeling) { btnLabeling = new QPushButton( grpControls ); grpControlsLayout->addWidget( btnLabeling ); } else { btnLabeling = NULL; } /* put it all together */ QHBoxLayout *layout = new QHBoxLayout( this ); layout->addWidget( sailDisp ); QVBoxLayout *vbox = new QVBoxLayout(); vbox->addWidget( grpControls ); vbox->addItem( new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding) ); if (showSliders) { vbox->addWidget( grpParams ); } layout->addLayout( vbox ); /* set language */ connect(qApp, SIGNAL(languageChanged()), this, SLOT(languageChange())); languageChange(); /* connect signals */ connect( sailDisp, SIGNAL( azimuthChanged(real) ), this, SLOT(slotAzimuth(real)) ); connect( sailDisp, SIGNAL( elevationChanged(real) ), this, SLOT(slotElevation(real)) ); if (btnLabeling) { connect( (QWidget*) btnLabeling, SIGNAL( clicked() ), sailDisp, SLOT( slotLabeling() )); } connect( (QWidget*) btnResetView, SIGNAL( clicked() ), sailDisp, SLOT( slotResetView() )); connect( (QWidget*) btnZoomIn, SIGNAL( clicked() ), sailDisp, SLOT( slotZoomIn() )); connect( (QWidget*) btnZoomOut, SIGNAL( clicked() ), sailDisp, SLOT( slotZoomOut() )); } /** * We received a keypress, we pass it down to the CSailViewer. */ void CSailViewerPanel::keyPressEvent ( QKeyEvent * e ) { sailDisp->keyPressEvent(e); } /** * Sets the strings of the subwidgets using the current language. */ void CSailViewerPanel::languageChange() { if (showSliders) { grpParams->setTitle( tr( "Display parameters" ) ); lblElevationStatic->setText( tr( "elevation" ) ); lblAzimuthStatic->setText( tr( "azimuth" ) ); } grpControls->setTitle( tr( "Controls" ) ); btnResetView->setText( tr( "Reset view" ) ); if (btnLabeling) { btnLabeling->setText( tr( "Labeling" ) ); } btnZoomIn->setText( tr( "Zoom in" ) ); btnZoomOut->setText( tr( "Zoom out" ) ); } /** * Change the displayed object. * * @param obj the new object to display */ void CSailViewerPanel::setObject(const CPanelGroup &obj) { sailDisp->setObject(obj); } /** * The azimuth was changed, update the corresponding label. * * @param azimuth */ void CSailViewerPanel::slotAzimuth(real azimuth) { if (lblAzimuth) { lblAzimuth->setText(QString::number(azimuth) + " " +tr("deg")); } } /** * The elevation changed, update the corresponding label. * * @param elevation */ void CSailViewerPanel::slotElevation(real elevation) { if (lblElevation) { lblElevation->setText(QString::number(elevation) + " " +tr("deg")); } } sailcut-1.5.0/src/sailviewer-panel.h000066400000000000000000000042771477005247400174140ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILVIEWER_PANEL_H #define SAILVIEWER_PANEL_H #include "sailviewer.h" // forward definitions class QGroupBox; class QLabel; class QPushButton; /** The main dialog of the Sailcut application. */ class CSailViewerPanel : public QWidget { Q_OBJECT public: CSailViewerPanel(QWidget *parent, const enumViewMode viewMode, bool show_sliders, bool show_labeling = true); void setObject(const CPanelGroup &obj); void keyPressEvent ( QKeyEvent * e ); // slots public slots: virtual void slotAzimuth(real azimuth); virtual void slotElevation(real azimuth); private slots: void languageChange(); // member variables protected: /** groupbox for parameters */ QGroupBox* grpParams; /** label for current azimuth */ QLabel* lblAzimuth; /** label for current elevation */ QLabel* lblElevation; /** static label saying "elevation" */ QLabel* lblElevationStatic; /** static label saying "azimuth" */ QLabel* lblAzimuthStatic; /** groupbox for the view controls */ QGroupBox* grpControls; /** Reset View button */ QPushButton* btnResetView; /** Labeling button */ QPushButton* btnLabeling; /** Zoom In button */ QPushButton* btnZoomIn; /** Zoom Out button */ QPushButton* btnZoomOut; /** display area for the 3d sail */ CSailViewer *sailDisp; private: bool showSliders; }; #endif sailcut-1.5.0/src/sailviewer-tabs.cpp000066400000000000000000000037341477005247400175760ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "sailviewer-panel.h" #include "sailviewer-tabs.h" /** * Constructs a tabbed widget to hold sail viewers. * * @param parent the parent widget */ CSailViewerTabs::CSailViewerTabs(QWidget *parent) : QTabWidget(parent) { addViewer(new CSailViewerPanel(NULL, SHADED, true)); addViewer(new CSailViewerPanel(NULL, WIREFRAME, true)); // set language connect(qApp, SIGNAL(languageChanged()), this, SLOT(languageChange())); languageChange(); } /** * Adds a tab with a new sail viewer. */ void CSailViewerTabs::addViewer(CSailViewerPanel *viewer) { // add viewer panel.push_back(viewer); // add tab addTab(viewer,""); } /** * Sets the strings of the subwidgets using the current * language. */ void CSailViewerTabs::languageChange() { int tabidx = 0; setTabText(tabidx++, tr("shaded view")); setTabText(tabidx++, tr("wireframe view")); } /** * Change the displayed object. * * @param obj the new object to display */ void CSailViewerTabs::setObject(const CPanelGroup &obj) { int tabidx = 0; panel[tabidx++]->setObject(obj); panel[tabidx++]->setObject(obj); } sailcut-1.5.0/src/sailviewer-tabs.h000066400000000000000000000024631477005247400172410ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILVIEWER_TABS_H #define SAILVIEWER_TABS_H #include #include "sailviewer-panel.h" /** Collection of tabs holding several CSailViewerPanel. */ class CSailViewerTabs : public QTabWidget { Q_OBJECT public: CSailViewerTabs(QWidget *parent); void addViewer(CSailViewerPanel *viewer); void setObject(const CPanelGroup &obj); private slots: void languageChange(); public: /** the widgets of each view */ std::vector panel; }; #endif sailcut-1.5.0/src/sailviewer.cpp000066400000000000000000000105231477005247400166410ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "sailviewer.h" #include "saildisplabel.h" #include "saildispgl.h" #include #include #include /** Constructs a CSailViewer object. */ CSailViewer::CSailViewer( QWidget *parent, enumViewMode viewMode, bool show_sliders ) : QWidget(parent) { sailDispLayout = new QGridLayout( this ); int xpos = 0, ypos = 0; if (show_sliders) { sliderElevation = new QSlider( this ); sliderElevation->setMinimum( -180 ); sliderElevation->setMaximum( 180 ); sliderElevation->setOrientation( Qt::Vertical ); sliderElevation->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); sailDispLayout->addWidget( sliderElevation, 0, 0 ); xpos++; sliderAzimuth = new QSlider( this ); sliderAzimuth->setMinimum( -180 ); sliderAzimuth->setMaximum( 180 ); sliderAzimuth->setOrientation( Qt::Horizontal ); sliderAzimuth->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); sailDispLayout->addWidget( sliderAzimuth, 1, 1 ); ypos++; } else { sliderElevation = NULL; sliderAzimuth = NULL; } /* create the drawing area */ switch (viewMode) { case SHADED: lblDraw = new CSailDispGL( this ); sailDispLayout->addWidget( (CSailDispGL*)(lblDraw), 0, xpos ); break; case WIREFRAME: default: lblDraw = new CSailDispLabel( this ); sailDispLayout->addWidget( (CSailDispLabel*)(lblDraw), 0, xpos ); break; } //((QWidget*)lblDraw)->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // signals and slots connections if (sliderElevation) connect( sliderElevation, SIGNAL( valueChanged(int) ), this, SLOT( slotElevation(int) ) ); if (sliderAzimuth) connect( sliderAzimuth, SIGNAL( valueChanged(int) ), this, SLOT( slotAzimuth(int) ) ); } /** We received a keypress. This is used to zoom in and out. */ void CSailViewer::keyPressEvent ( QKeyEvent * e ) { // zoom in/out by keyboard shortcut if (e->modifiers() & Qt::ControlModifier) { if (e->text()=="+") slotZoomIn(); if (e->text()=="=") slotZoomIn(); if (e->text()=="-") slotZoomOut(); } } /** Changes the displayed object. * * @param obj the new object to be displayed */ void CSailViewer::setObject(const CPanelGroup &obj) { lblDraw->setObject(obj); lblDraw->redraw(); } void CSailViewer::slotAzimuth(int azimuth) { azimuthChanged(azimuth); lblDraw->setAzimuth(azimuth); lblDraw->redraw(); } void CSailViewer::slotElevation(int elevation) { elevationChanged(elevation); lblDraw->setElevation(elevation); lblDraw->redraw(); } /** Draws the panel labels */ void CSailViewer::slotLabeling() { // invert the drawLabels flag, then ask for a redraw lblDraw->drawLabels = ! lblDraw->drawLabels; lblDraw->redraw(); } /** Resets the angle and center of the CSailDisp to their default values. */ void CSailViewer::slotResetView() { if (sliderElevation) sliderElevation->setValue(0); if (sliderAzimuth) sliderAzimuth->setValue(0); lblDraw->resetZoomCenter(); lblDraw->redraw(); } /** This event occurs when the user presses the "zoom in" button. */ void CSailViewer::slotZoomIn() { lblDraw->zoomIn(); lblDraw->redraw(); } /** This event occurs when the user presses the "zoom out" button. */ void CSailViewer::slotZoomOut() { lblDraw->zoomOut(); lblDraw->redraw(); } sailcut-1.5.0/src/sailviewer.h000066400000000000000000000041001477005247400163000ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILVIEWER_H #define SAILVIEWER_H #include #include "sailcpp/panelgroup.h" class QSlider; class QLabel; class CPanelGroup; class CSailDisp; class QGridLayout; // enumerated types enum enumViewMode { WIREFRAME, SHADED }; /** This class is used to display a sail. It has a display * area as well as an elevation and an azimuth slider. */ class CSailViewer : public QWidget { Q_OBJECT public: CSailViewer(QWidget *parent, enumViewMode viewMode, bool show_sliders = true); void setObject( const CPanelGroup &obj ); void keyPressEvent ( QKeyEvent * e ); protected slots: void slotAzimuth(int); void slotElevation(int); void slotLabeling(); void slotZoomIn(); void slotZoomOut(); public slots: void slotResetView(); signals: /** Signals that the azimuth has changed. */ void azimuthChanged(real azimuth); /** Signals that the elevation has changed. */ void elevationChanged(real elevation); protected: /** The drawing area */ CSailDisp *lblDraw; /** The slider that controls the viewing elevation */ QSlider *sliderElevation; /** The slider that controls the viewing azimuth */ QSlider *sliderAzimuth; /** The widget's layout */ QGridLayout* sailDispLayout; }; #endif sailcut-1.5.0/src/sailwriter-carlson.cpp000066400000000000000000000115131477005247400203130ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "sailwriter-carlson.h" #include #include #include #define CRLF "\r\n" /** Write the draw message * * @param out the output stream * @param ct number of points to be written */ void CSailCarlsonWriter::writeDraw(std::ofstream &out, unsigned int ct) const { out.setf(std::ios::left, std::ios::adjustfield); out<< std::setw(16) <<"draw"<< ct << CRLF; } /** Write the cut message * * @param out the output stream * @param ct number of points to be written */ void CSailCarlsonWriter::writeCut(std::ofstream &out, unsigned int ct) const { out.setf(std::ios::left, std::ios::adjustfield); out<< std::setw(16) <<"cut"<< ct << CRLF; } /** Write a point * * @param out the output stream * @param p0 3d point to be written */ void CSailCarlsonWriter::writePoint(std::ofstream &out, CPoint3d p0) const { real x=0, y=0; x= p0.x(); y= p0.y(); out.setf(std::ios::left, std::ios::adjustfield); out << std::setw(16) << x << y << CRLF; } /** Write panel header to Carlson plotter format * * @param out the output stream * @param panel the number of the panel to write * */ void CSailCarlsonWriter::writePanelHeader(std::ofstream &out, const CPanel &panel) const { //char identity; //identity = panel.label.name; unsigned int pencolor = panel.label.color; unsigned int htx = panel.label.height; // text height in mm real xoff =0 , yoff = 0, rtx=0; // position and text rotation from x axis. xoff= panel.label.origin.x(); yoff= panel.label.origin.y(); //rtx = atn2( xoff= panel.label.direction.y(), xoff= _sail[panel].label.direction.x()); out << "panel, "<< panel.label.name <<", "< -1; j--) { writePoint( out, right[j] ); } //// panel bottom edge for (j = btm.size() -1; j > -1; j--) { writePoint( out, btm[j] ); } //// header for cut line writeCut ( out, left.size()+top.size()+right.size()+btm.size() ); // left edge for (i = 0; i < left.size(); i++) { writePoint( out, cleft[i] ); } // panel top edge for (i = 0; i < top.size(); i++) { writePoint( out, ctop[i] ); } // panel right edge for (j = right.size() -1; j > - 1; j--) { writePoint( out, cright[j] ); } // panel bottom edge for (j = btm.size() -1; j > -1; j--) { writePoint( out, cbtm[j] ); } } sailcut-1.5.0/src/sailwriter-carlson.h000066400000000000000000000032001477005247400177520ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILWRITER_CARLSON_H #define SAILWRITER_CARLSON_H #include "filewriter.h" #include "sailcpp/panelgroup.h" #include /** A class for writing to Carlson plotter files. * * @ingroup FileIo */ class CSailCarlsonWriter : public CFileWriter { public: /** The constructor. */ CSailCarlsonWriter() : CFileWriter(".sp4","Carlson plotter files") {} ; void write(const CPanelGroup &sail, const QString &filename) const; void writePanel(std::ofstream &out, const CPanel &panel) const; void writePanelHeader(std::ofstream &out, const CPanel &panel) const; void writeDraw(std::ofstream &out, unsigned int ct) const; void writeCut(std::ofstream &out, unsigned int ct) const; void writePoint(std::ofstream &out, CPoint3d p0) const; }; #endif sailcut-1.5.0/src/sailwriter-dxf.cpp000066400000000000000000000410131477005247400174310ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "sailwriter-dxf.h" #include #define DXF_ENTITY 0 #define DXF_NAME 2 #define DXF_LINE 6 #define DXF_LAYER 8 #define DXF_X 10 #define DXF_Y 20 #define DXF_Z 30 #define DXF_COLOR 62 #define DXF_FLAG 70 #define DXF_COMMENT 999 #define DXF_BLACK "0" #define DXF_RED "1" #define DXF_YELLOW "2" #define DXF_GREEN "3" #define DXF_CYAN "4" #define DXF_BLUE "5" #define DXF_MAGENTA "6" #define DXF_WHITE "7" /*********************************** DXF components ***********************************/ /** Write a DXF atom to the file output stream. * * @param out the output stream * @param code atom code * @param content atom content */ void CSailDxfWriter::writeAtom(std::ofstream &out, int code, const QString& content) const { out << code << std::endl << std::string(content.toLocal8Bit()) << std::endl; } /** Open the given file, then write comment and header section. * * @param out the output stream * @param filename the output file name */ void CSailDxfWriter::writeBegin(std::ofstream &out, const QString &filename) const { out.open(QFile::encodeName(filename), std::ios::out); if (!out.is_open()) throw write_error("CSailDxfWriter::writeBegin : unable to write to specified file"); // write comment writeAtom(out, DXF_COMMENT, "DXF created by Sailcut CAD"); // write header section writeAtom(out, DXF_ENTITY, "SECTION"); writeAtom(out, DXF_NAME, "HEADER"); writeAtom(out, DXF_ENTITY, "ENDSEC"); } /** Write end of file then close file. * * @param out the output stream */ void CSailDxfWriter::writeEnd(std::ofstream &out) const { writeAtom(out, DXF_ENTITY, "EOF"); out.close(); } /** Write a triangular face to the file output stream. * * @param out the output stream * @param p0 first point * @param p1 second point * @param p2 third point * @param layer */ void CSailDxfWriter::writeFace(std::ofstream &out, CPoint3d p0, CPoint3d p1, CPoint3d p2, unsigned int layer) const { // skip empty face real area = CVector3d::crossProduct(p1 - p0, p2 - p0).length(); //std::cout << "area : " << area << std::endl; if ( area <= EPS ) { std::cout << "CSailDxfWriter::writeFace : skipping empty face" << std::endl; return; } writeAtom(out, DXF_ENTITY, "3DFACE"); // set the layer writeAtom(out, DXF_LAYER, QString::number(layer)); // set the points writeAtom(out, DXF_X, QString::number(p0.x())); writeAtom(out, DXF_Y, QString::number(p0.y())); writeAtom(out, DXF_Z, QString::number(p0.z())); writeAtom(out, DXF_X + 1, QString::number(p1.x())); writeAtom(out, DXF_Y + 1, QString::number(p1.y())); writeAtom(out, DXF_Z + 1, QString::number(p1.z())); writeAtom(out, DXF_X + 2, QString::number(p2.x())); writeAtom(out, DXF_Y + 2, QString::number(p2.y())); writeAtom(out, DXF_Z + 2, QString::number(p2.z())); // duplicate last point for stupid AutoCAD writeAtom(out, DXF_X + 3, QString::number(p2.x())); writeAtom(out, DXF_Y + 3, QString::number(p2.y())); writeAtom(out, DXF_Z + 3, QString::number(p2.z())); } /** Write a DXF layer to the file output stream. * * @param out the output stream * @param layer * @param color the color */ void CSailDxfWriter::writeLayer(std::ofstream &out, unsigned int layer, const QString &color) const { writeAtom(out, DXF_ENTITY, "LAYER"); writeAtom(out, DXF_NAME, QString::number(layer)); writeAtom(out, DXF_FLAG, "64"); writeAtom(out, DXF_COLOR, color); writeAtom(out, DXF_LINE, "CONTINUOUS"); } /** Write a DXF Polyline header to the file output stream. * * @param out the output stream * @param layer * @param color the color */ void CSailDxfWriter::writePolyline(std::ofstream &out, unsigned int layer, const QString &color) const { writeAtom(out, DXF_ENTITY, "POLYLINE"); // set the layer writeAtom(out, DXF_LAYER, QString::number(layer)); // set color writeAtom(out, DXF_COLOR, color); // set vertice follows flag writeAtom(out, 66, "1"); // set line type writeAtom(out, DXF_LINE, "CONTINUOUS"); } /** Write a 2D DXF Vertex to the file output stream. * * @param out the output stream * @param pt point * @param layer */ void CSailDxfWriter::writeVertex(std::ofstream &out, CPoint3d pt, unsigned int layer) const { writeAtom(out, DXF_ENTITY, "VERTEX"); // set the layer writeAtom(out, DXF_LAYER, QString::number(layer)); // set 3D flag //writeAtom(out, DXF_FLAG, "32"); // flag 3D vertex // set the points writeAtom(out, DXF_X, QString::number(pt.x())); writeAtom(out, DXF_Y, QString::number(pt.y())); //writeAtom(out, DXF_Z, QString::number(pt.z())); // for 3D } /*********************************** 2D DXF export ***********************************/ /** Writes a CPanelGroup to a simple DXF file. * * @param sail the sail to write * @param filename the file to write to */ void CSailDxfWriter2d::write(const CPanelGroup &sail, const QString &filename) const { switch (type) { case NORMAL: writeNormal(sail, filename); break; case BLOCKS: writeBlocks(sail, filename); break; case SPLIT: writeSplit(sail, filename); break; } } /** Writes a CPanelGroup to a simple 2D DXF file, one panel per layer. * * @param sail the sail to write * @param filename the file to write to */ void CSailDxfWriter2d::writeNormal(const CPanelGroup &sail, const QString &filename) const { std::ofstream out; unsigned int pn; // open file, write comment and header writeBegin(out, filename); // write tables section writeAtom(out, DXF_ENTITY, "SECTION"); writeAtom(out, DXF_NAME, "TABLES"); writeAtom(out, DXF_ENTITY, "TABLE"); writeAtom(out, DXF_NAME, "LAYER"); writeAtom(out, DXF_FLAG, "6"); for (pn = 0; pn < sail.size(); pn++) writeLayer(out, pn+1, DXF_GREEN); writeAtom(out, DXF_ENTITY, "ENDTAB"); writeAtom(out, DXF_ENTITY, "ENDSEC"); // write entities section writeAtom(out, DXF_ENTITY, "SECTION"); writeAtom(out, DXF_NAME, "ENTITIES"); // loop over panels //////// for (pn = 0; pn < sail.size(); pn++) writePanel(out, sail[pn], pn+1); writeAtom(out, DXF_ENTITY, "ENDSEC"); // end of file writeEnd(out); } /** Writes a CPanelGroup to a 2D DXF file with one block per panel on different layer. * * @param sail the sail to write * @param filename the file to write to */ void CSailDxfWriter2d::writeBlocks(const CPanelGroup &sail, const QString &filename) const { std::ofstream out; unsigned int pn; // open file, write comment and header writeBegin(out, filename); // write tables section writeAtom(out, DXF_ENTITY, "SECTION"); writeAtom(out, DXF_NAME, "TABLES"); writeAtom(out, DXF_ENTITY, "TABLE"); writeAtom(out, DXF_NAME, "LAYER"); writeAtom(out, DXF_FLAG, "16"); for (pn = 0; pn < sail.size(); pn++) writeLayer(out, pn+1, DXF_GREEN); writeAtom(out, DXF_ENTITY, "ENDTAB"); writeAtom(out, DXF_ENTITY, "ENDSEC"); // write entities section writeAtom(out, DXF_ENTITY, "SECTION"); writeAtom(out, DXF_NAME, "BLOCKS"); for (pn = 0; pn < sail.size(); pn++) { writeAtom(out, DXF_ENTITY, "BLOCK"); writeAtom(out, 100, "AcDbEntity"); writeAtom(out, DXF_LAYER, QString::number(pn+1)); writeAtom(out, 100, "AcDbBlockBegin"); writeAtom(out, DXF_NAME, "panel "+QString::number(pn+1)); writeAtom(out, DXF_FLAG, "1"); writeAtom(out, DXF_X, "0"); writeAtom(out, DXF_Y, "0"); writeAtom(out, DXF_Z, "0"); writeAtom(out, 3, "panel "+QString::number(pn+1)); writePanel(out, sail[pn], pn+1); writeAtom(out, DXF_ENTITY, "ENDBLCK"); writeAtom(out, 100, "AcDbBlockEnd"); } writeAtom(out, DXF_ENTITY, "ENDSEC"); // end of BLOCKS section // end of file writeEnd(out); } /** Writes a CPanelGroup to a 2D DXF file with one file per panel. * * @param sail the sail to write * @param filename the file to write to */ void CSailDxfWriter2d::writeSplit(const CPanelGroup &sail, const QString &basename) const { std::ofstream out; unsigned int pn; for (pn = 0; pn < sail.size(); pn++) { QString filename = basename; filename.replace(".dxf", QString("-%1.dxf").arg(pn)); // open file, write comment and header writeBegin(out, filename); // write tables section writeAtom(out, DXF_ENTITY, "SECTION"); writeAtom(out, DXF_NAME, "TABLES"); writeAtom(out, DXF_ENTITY, "TABLE"); writeAtom(out, DXF_NAME, "LAYER"); writeAtom(out, DXF_FLAG, "6"); writeLayer(out, 1, DXF_CYAN); writeAtom(out, DXF_ENTITY, "ENDTAB"); writeAtom(out, DXF_ENTITY, "ENDSEC"); // write entities section writeAtom(out, DXF_ENTITY, "SECTION"); writeAtom(out, DXF_NAME, "ENTITIES"); writePanel(out, sail[pn], 1); writeAtom(out, DXF_ENTITY, "ENDSEC"); // end of file writeEnd(out); } } /** Write a single 2D DXF developed panel draw and cut edges to the file output stream. * * @param out the output stream * @param panel the panel to be written * @param layer the layer on which the panel is written */ void CSailDxfWriter2d::writePanel(std::ofstream &out, const CPanel &panel, unsigned int layer) const { //writeAtom(out, DXF_COMMENT, panel.label.name); CSide top = panel.top; CSide btm = panel.bottom; CSide left = panel.left; CSide right = panel.right; CSide ctop = panel.cutTop; CSide cbtm = panel.cutBottom; CSide cleft = panel.cutLeft; CSide cright = panel.cutRight; CPoint3d pt; CVector3d V; unsigned int i=0; int j=0; //// polyline header for draw line writePolyline(out, layer, DXF_BLUE); // left edge pt = left[0]; writeVertex(out, pt, layer); for (i = 1; i < left.size(); i++) { V= left[i] - pt; if (V.length() > EPS) { pt = left[i]; writeVertex(out, pt, layer); } } // panel top edge for (i = 0; i < top.size(); i++) { V = top[i] - pt; if (V.length() > EPS) { pt = top[i]; writeVertex(out, pt, layer); } } // panel right edge for (j = right.size()-1; j > - 1; j--) { V = right[j] - pt; if (V.length() > EPS) { pt = right[j]; writeVertex(out, pt, layer); } } // panel bottom edge for (j = btm.size()-1; j > -1; j--) { V = btm[j] - pt; if (V.length() > EPS) { pt = btm[j]; writeVertex(out, pt, layer); } } // close the circuit to start point pt = left[0]; writeVertex(out, pt, layer); writeAtom(out, DXF_ENTITY, "SEQEND"); // end draw line //// polyline header for cut line writePolyline(out, layer, DXF_RED); // left edge pt = cleft[0]; writeVertex(out, pt, layer); for (i = 1; i < left.size(); i++) { V= cleft[i] - pt; if (V.length() > EPS) { pt = cleft[i]; writeVertex(out, pt, layer); } } // panel top edge for (i = 0; i < top.size(); i++) { V = ctop[i] - pt; if (V.length() > EPS) { pt = ctop[i]; writeVertex(out, pt, layer); } } // panel right edge for (j = right.size()-1; j > - 1; j--) { V = cright[j] - pt; if (V.length() > EPS) { pt = cright[j]; writeVertex(out, pt, layer); } } // panel bottom edge for (j = btm.size()-1; j > -1; j--) { V = cbtm[j] - pt; if (V.length() > EPS) { pt = cbtm[j]; writeVertex(out, pt, layer); } } // close the circuit to start point pt = cleft[0]; writeVertex(out, pt, layer); writeAtom(out, DXF_ENTITY, "SEQEND"); // end cut line } /*********************************** 3D DXF export ***********************************/ /** Writes a 3D CPanelGroup to a 3D DXF file. * * @param sail the sail to write * @param filename the file to write to */ void CSailDxfWriter3d::write(const CPanelGroup &sail, const QString &filename) const { switch (type) { case NORMAL: writeNormal(sail, filename); break; case SPLIT: writeSplit(sail, filename); break; } } /** Writes a 3D CPanelGroup to a 3D DXF file with one panel per layer. * * @param sail the sail to write * @param filename the file to write to */ void CSailDxfWriter3d::writeNormal(const CPanelGroup &sail, const QString &filename) const { std::ofstream out; unsigned int pn; // open file, write comment and header writeBegin(out, filename); // write tables section writeAtom(out, DXF_ENTITY, "SECTION"); writeAtom(out, DXF_NAME, "TABLES"); writeAtom(out, DXF_ENTITY, "TABLE"); writeAtom(out, DXF_NAME, "LAYER"); writeAtom(out, DXF_FLAG, "6"); for (pn = 0; pn < sail.size(); pn++) writeLayer(out, pn + 1, (pn % 2) ? DXF_YELLOW : DXF_CYAN); writeAtom(out, DXF_ENTITY, "ENDTAB"); writeAtom(out, DXF_ENTITY, "ENDSEC"); // write entities section writeAtom(out, DXF_ENTITY, "SECTION"); writeAtom(out, DXF_NAME, "ENTITIES"); for (pn = 0; pn < sail.size(); pn++) writePanel(out, sail[pn], pn + 1); writeAtom(out, DXF_ENTITY, "ENDSEC"); // end of file writeEnd(out); } /** Write a single 3D DXF panel to the file output stream. * * @param out the output stream * @param panel the number of the panel to be written * @param layer the layer on which the panel is written */ void CSailDxfWriter3d::writePanel(std::ofstream &out, const CPanel &panel, unsigned int layer) const { //writeAtom(out, DXF_COMMENT, panel.label.name); //writeAtom(out, DXF_COMMENT, QString("panel : ") + QString::number(panel)); CSide top = panel.top; CSide btm = panel.bottom; CSide left = panel.left; CSide right = panel.right; CPoint3d pt; unsigned int i=0; // left triangle fan pt = (left[0]+left[left.size()-1])*0.5; for (i = 1; i < left.size(); i++) writeFace(out, pt, left[i-1], left[i], layer); // panel triangle strip for (i = 1; i < top.size(); i++) { writeFace(out, top[i-1], btm[i-1], top[i], layer); writeFace(out, top[i], btm[i], btm[i-1], layer); } // right triangle fan pt = (right[0]+right[right.size()-1])*0.5; for (i = 1; i < right.size(); i++) writeFace(out, pt, right[i-1], right[i], layer); } /** Writes a 3D CPanelGroup to a 3D DXF file with one file per panel. * * @param sail the sail to write * @param filename the file to write to */ void CSailDxfWriter3d::writeSplit(const CPanelGroup &sail, const QString &basename) const { std::ofstream out; for (unsigned int pn = 0; pn < sail.size(); pn++) { QString filename = basename; filename.replace(".dxf", QString("-%1.dxf").arg(pn)); // open file, write comment and header writeBegin(out, filename); // write tables section writeAtom(out, DXF_ENTITY, "SECTION"); writeAtom(out, DXF_NAME, "TABLES"); writeAtom(out, DXF_ENTITY, "TABLE"); writeAtom(out, DXF_NAME, "LAYER"); writeAtom(out, DXF_FLAG, "6"); writeLayer(out, 1, DXF_CYAN); writeAtom(out, DXF_ENTITY, "ENDTAB"); writeAtom(out, DXF_ENTITY, "ENDSEC"); // write entities section writeAtom(out, DXF_ENTITY, "SECTION"); writeAtom(out, DXF_NAME, "ENTITIES"); writePanel(out, sail[pn], 1); writeAtom(out, DXF_ENTITY, "ENDSEC"); // end of file writeEnd(out); } } sailcut-1.5.0/src/sailwriter-dxf.h000066400000000000000000000061011477005247400170750ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILWRITER_DXF_H #define SAILWRITER_DXF_H #include "filewriter.h" #include "sailcpp/panelgroup.h" #include #include /** An abstract class containing the methods needed for DXF writing. */ class CSailDxfWriter : public CFileWriter { public: /** The constructor. */ CSailDxfWriter() : CFileWriter(".dxf", "DXF files") {} ; void writeBegin(std::ofstream &out, const QString &filename) const; void writeEnd(std::ofstream &out) const; void writeAtom(std::ofstream &out, int code, const QString& content) const; void writeFace(std::ofstream &out, CPoint3d p0, CPoint3d p1, CPoint3d p2, unsigned int layer) const; void writeLayer(std::ofstream &out, unsigned int layer, const QString &color) const; void writePolyline(std::ofstream &out, unsigned int layer, const QString &color) const; void writeVertex(std::ofstream &out, CPoint3d p0, unsigned int layer) const; }; /** A class used to write a CPanelGroup to a 2D DXF file. * * @ingroup FileIo */ class CSailDxfWriter2d : public CSailDxfWriter { public: enum Dxf2dType { NORMAL, BLOCKS, SPLIT, }; CSailDxfWriter2d(enum Dxf2dType format) : type(format) {}; void write(const CPanelGroup &sail, const QString &filename) const; protected: void writePanel(std::ofstream &out, const CPanel &panel, unsigned int layer) const; void writeNormal(const CPanelGroup &sail, const QString &filename) const; void writeBlocks(const CPanelGroup &sail, const QString &filename) const; void writeSplit(const CPanelGroup &sail, const QString &filename) const; Dxf2dType type; }; /** A class used to write a CPanelGroup to a 3D DXF file. * * @ingroup FileIo */ class CSailDxfWriter3d : public CSailDxfWriter { public: enum Dxf3dType { NORMAL, SPLIT, }; CSailDxfWriter3d(enum Dxf3dType format) : type(format) {}; void write(const CPanelGroup &sail, const QString &filename) const; protected: void writePanel(std::ofstream &out, const CPanel &panel, unsigned int layer) const; void writeNormal(const CPanelGroup &sail, const QString &filename) const; void writeSplit(const CPanelGroup &sail, const QString &filename) const; Dxf3dType type; }; #endif sailcut-1.5.0/src/sailwriter-hand.cpp000066400000000000000000000044361477005247400175720ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "sailwriter-hand.h" #include #include /** Write sail to TXT "hand" format. * * @param sail the panel group to write * @param filename the file to write to */ void CSailHandWriter::write(const CPanelGroup &sail, const QString &filename) const { // open the output file std::ofstream myOut; myOut.open(QFile::encodeName(filename), std::ios::out); if (!myOut.is_open()) throw write_error("CSailWriter::write : unable to write to specified file"); // write the name of the sail myOut << sail.title << std::endl; // TODO : modify code to write actual hand output // // sail is the sail, loop over its panels for (unsigned int i=0; i < sail.size(); i++) { myOut << "===== CPanel : " << i << " ====" << std::endl; myOut << sail[i].label; myOut << "== CSide : left ==" << std::endl << sail[i].left; myOut << "== CSide : top ==" << std::endl << sail[i].top; myOut << "== CSide : right ==" << std::endl << sail[i].right; myOut << "== CSide : bottom ==" << std::endl << sail[i].bottom; if (sail[i].hasHems) { myOut << "== CSide : cutLeft ==" << std::endl << sail[i].cutLeft; myOut << "== CSide : cutTop ==" << std::endl << sail[i].cutTop; myOut << "== CSide : cutRight ==" << std::endl << sail[i].cutRight; myOut << "== CSide : cutBottom ==" << std::endl << sail[i].cutBottom; } } myOut.close(); } sailcut-1.5.0/src/sailwriter-hand.h000066400000000000000000000023501477005247400172300ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILWRITER_HAND_H #define SAILWRITER_HAND_H #include "sailwriter-txt.h" /** This class allows you to write a developed sail by using * the deviation of the edge from the straight line instead * of using absolute coordinates to a TXT file. * * @ingroup FileIo */ class CSailHandWriter : public CSailTxtWriter { public: virtual void write(const CPanelGroup &sail, const QString &filename) const; }; #endif sailcut-1.5.0/src/sailwriter-svg.cpp000066400000000000000000000024371477005247400174560ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "sailwriter-svg.h" #include "sailprinter.h" #include /** * Write a 3D sail to 2D SVG format. * * @param sail the sail to write * @param filename the file to write to */ void CSailSvgWriter::write(const CPanelGroup &sail, const QString &filename) const { // SVG generator QSvgGenerator generator; generator.setFileName(filename); CTextPainter painter(&generator); CSailDrawingPrinter(sail, false).print(&painter, 0, 1.0, 10); } sailcut-1.5.0/src/sailwriter-svg.h000066400000000000000000000024041477005247400171150ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILWRITER_SVG_H #define SAILWRITER_SVG_H #include "filewriter.h" #include "sailcpp/panelgroup.h" /** A class used to output a CPanelGroup to an SVG file. * * @ingroup FileIo */ class CSailSvgWriter : public CFileWriter { public: /** The constructor. */ CSailSvgWriter() : CFileWriter(".svg", "SVG files") {} ; void write(const CPanelGroup &sail, const QString &filename) const; }; #endif sailcut-1.5.0/src/sailwriter-txt.cpp000066400000000000000000000025371477005247400174770ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "sailwriter-txt.h" #include #include /** Write sail to TXT format. * * @param sail the panel group to write * @param filename the file to write to */ void CSailTxtWriter::write(const CPanelGroup &sail, const QString &filename) const { std::ofstream myOut; myOut.open(QFile::encodeName(filename), std::ios::out); if (!myOut.is_open()) throw write_error("CSailTxtWriter::write : unable to write to specified file"); myOut << sail.title << std::endl; myOut << sail; myOut.close(); } sailcut-1.5.0/src/sailwriter-txt.h000066400000000000000000000024031477005247400171340ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef TXTWRITER_H #define TXTWRITER_H #include "filewriter.h" #include "sailcpp/panelgroup.h" /** A class used to output a CPanelGroup to a TXT file. * * @ingroup FileIo */ class CSailTxtWriter : public CFileWriter { public: /** The constructor. */ CSailTxtWriter() : CFileWriter(".txt","Text files") {} ; virtual void write(const CPanelGroup &sail, const QString &filename) const; }; #endif sailcut-1.5.0/src/sailwriter-xml.h000066400000000000000000000075171477005247400171300ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SAILWRITER_XML_H #define SAILWRITER_XML_H #include "filewriter.h" #include "saildoc.h" /** This class allows you to write sailcut objects to * an XML file. * * @ingroup FileIo * @see CPanelGroupXmlWriter * @see CSailDefXmlWriter */ template class XmlWriterTempl : public CFileWriter { protected : /** the object's name */ QString _name; public: /** The constructor. * * @param name the object's name * @param ext the file extension to show (defaults to ".xml") * @param desc a description of the file type (defaults to "XML files") */ XmlWriterTempl(const QString &name, const QString ext = ".xml", const QString desc = "XML files") : CFileWriter(ext, desc), _name(name) {} ; /** Write object to XML format. * * @param obj the object to write * @param filename the file to write to */ virtual void write(const objtype &obj, const QString &filename) const { CSailDoc doc; doc.put(doc.top, obj, _name); doc.toFile(filename); }; /** Read object from an XML file. * * @param filename the file we read from */ const objtype read(const QString &filename) const { CSailDoc doc(filename); objtype obj; doc.get(doc.top, obj, _name); return obj; }; }; /** A class used to output a CPanelGroup to an XML file. */ class CPanelGroupXmlWriter : public XmlWriterTempl { public: /** The constructor. */ CPanelGroupXmlWriter() : XmlWriterTempl("panelgroup", ".panel3d", "3D sails or hulls") {} ; }; /** A class used to output a CHullDef to an XML file. */ class CHullDefXmlWriter : public XmlWriterTempl { public: /** The constructor. */ CHullDefXmlWriter() : XmlWriterTempl("hulldef", ".hulldef", "Hull definitions") {} ; }; /** A class used to output a CSailDef to an XML file. */ class CSailDefXmlWriter : public XmlWriterTempl { public: /** The constructor. */ CSailDefXmlWriter() : XmlWriterTempl("saildef", ".saildef", "Sail definitions") {} ; }; /** A class used to output a CBoatDef to an XML file. */ class CBoatDefXmlWriter : public XmlWriterTempl { public: /** The constructor. */ CBoatDefXmlWriter() : XmlWriterTempl("boatdef", ".boatdef", "Boat definitions") {} ; }; /** A class used to output a CRigDef to an XML file. */ class CRigDefXmlWriter : public XmlWriterTempl { public: /** The constructor. */ CRigDefXmlWriter() : XmlWriterTempl("rigdef", ".rigdef", "Rig definitions") {} ; }; /** A class used to output a CPrefs to an XML file. */ class CPrefsXmlWriter : public XmlWriterTempl { public: /** The constructor. */ CPrefsXmlWriter() : XmlWriterTempl("prefs") {} ; }; #endif sailcut-1.5.0/src/src.pro000066400000000000000000000102221477005247400152700ustar00rootroot00000000000000include(../sailcut.pri) QT += openglwidgets printsupport svg xml INCLUDEPATH += ../icons TARGET = sailcut DESTDIR = $$BUILD_APP_PATH VERSION = $$SAILCUT_VERSION DEFINES += SAILCUT_VERSION=\\\"$${SAILCUT_VERSION}\\\" DEFINES += SAILCUT_DATA_PATH=\\\"$${SAILCUT_DATA_PATH}\\\" DEFINES += SAILCUT_DOC_PATH=\\\"$${SAILCUT_DOC_PATH}\\\" mac { TARGET = "Sailcut CAD" } FORMS += \ formhulldefbase.ui \ formrigdefbase.ui \ formsaildefbase.ui HEADERS += \ geocpp/geocpp.h \ geocpp/matrix.h \ geocpp/matrix4x4.h \ geocpp/rect.h \ geocpp/subspace.h \ geocpp/vector.h \ sailcpp/boatdef.h \ sailcpp/hulldef.h \ sailcpp/hullworker.h \ sailcpp/panelgroup.h \ sailcpp/panel.h \ sailcpp/rigdef.h \ sailcpp/rigworker.h \ sailcpp/sailcalc.h \ sailcpp/saildef.h \ sailcpp/sailmould.h \ sailcpp/sailworker.h \ app.h \ boatdef-panel.h \ filewriter.h \ formboat.h \ formhulldef.h \ formhull.h \ formmain.h \ formmould.h \ formpanelgroup.h \ formprint.h \ formrigdef.h \ formrig.h \ formsaildef.h \ formsail.h \ prefs.h \ saildispgl.h \ saildisp.h \ saildisplabel.h \ saildoc.h \ sailpainter.h \ sailprinter.h \ sailtreeitem.h \ sailtreemodel.h \ sailviewer.h \ sailviewer-panel.h \ sailviewer-tabs.h \ sailwriter-carlson.h \ sailwriter-dxf.h \ sailwriter-hand.h \ sailwriter-svg.h \ sailwriter-txt.h \ sailwriter-xml.h \ widgetprofile.h \ widgetprofilevert.h SOURCES += \ geocpp/matrix.cpp \ geocpp/matrix4x4.cpp \ geocpp/rect.cpp \ geocpp/subspace.cpp \ geocpp/vector.cpp \ sailcpp/boatdef.cpp \ sailcpp/hulldef.cpp \ sailcpp/hullworker.cpp \ sailcpp/panel.cpp \ sailcpp/panelgroup.cpp \ sailcpp/rigdef.cpp \ sailcpp/rigworker.cpp \ sailcpp/sailcalc.cpp \ sailcpp/saildef.cpp \ sailcpp/sailmould.cpp \ sailcpp/sailworker.cpp \ app.cpp \ boatdef-panel.cpp \ formboat.cpp \ formhull.cpp \ formhulldef.cpp \ formmain.cpp \ formmould.cpp \ formpanelgroup.cpp \ formprint.cpp \ formrig.cpp \ formrigdef.cpp \ formsail.cpp \ formsaildef.cpp \ main.cpp \ prefs.cpp \ saildisp.cpp \ saildispgl.cpp \ saildisplabel.cpp \ saildoc.cpp \ sailpainter.cpp \ sailprinter.cpp \ sailtreeitem.cpp \ sailtreemodel.cpp \ sailviewer.cpp \ sailviewer-panel.cpp \ sailviewer-tabs.cpp \ sailwriter-carlson.cpp \ sailwriter-dxf.cpp \ sailwriter-hand.cpp \ sailwriter-svg.cpp \ sailwriter-txt.cpp \ widgetprofile.cpp \ widgetprofilevert.cpp TRANSLATIONS = \ ts/sailcut_de.ts \ ts/sailcut_dk.ts \ ts/sailcut_fr.ts \ ts/sailcut_it.ts \ ts/sailcut_nl.ts \ ts/sailcut_no.ts \ ts/sailcut_pt.ts \ ts/sailcut_ru.ts win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\lrelease.exe else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease updateqm.input = TRANSLATIONS updateqm.output = $$BUILD_DATA_PATH/${QMAKE_FILE_BASE}.qm isEmpty(vcproj):updateqm.variable_out = PRE_TARGETDEPS updateqm.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} updateqm.CONFIG += no_link QMAKE_EXTRA_COMPILERS += updateqm # Installation QMAKE_TARGET_BUNDLE_PREFIX="com.sailcut" QMAKE_TARGET_COPYRIGHT="Copyright (c) Robert Lainé & Jeremy Lainé" QMAKE_TARGET_PRODUCT="Sailcut CAD" mac { ICON = ../icons/sailcut.icns QMAKE_POST_LINK += $$[QT_INSTALL_BINS]/macdeployqt $$shell_quote($$DESTDIR/$${TARGET}.app) } else:win32 { RC_ICONS = ../icons/sailcut.ico QMAKE_POST_LINK += $$[QT_INSTALL_BINS]/windeployqt $$shell_quote($$DESTDIR/$${TARGET}.exe) } else:unix { target.path = $$PREFIX/bin translations.files = $$BUILD_DATA_PATH translations.path = $$PREFIX/share INSTALLS += target translations # Generating documentation requires some extra tools system(which fig2dev && which xsltproc) { docs.commands = $$SAILCUT_SOURCE_TREE/doc/makedocs $$BUILD_DOC_PATH docs.files = $$BUILD_DOC_PATH docs.path = $$PREFIX/share/doc/sailcut QMAKE_EXTRA_TARGETS += docs INSTALLS += docs } } sailcut-1.5.0/src/ts/000077500000000000000000000000001477005247400144105ustar00rootroot00000000000000sailcut-1.5.0/src/ts/refresh000077500000000000000000000001321477005247400157700ustar00rootroot00000000000000#!/bin/sh set -e echo "Refreshing translations" lupdate ../*.cpp ../*.h ../*.ui -ts *.ts sailcut-1.5.0/src/ts/sailcut_de.ts000066400000000000000000002462011477005247400171010ustar00rootroot00000000000000 CBoatElementWidget Sail information Information des Segels file Datei name Bezeichnung Reload neu laden Remove Entfernen Update Aktualisieren Element information Elementeinformationen CFileIO Open Öffnen Save Speichern CFileWriter error Fehler There was an error writing to the selected file. Beim Schreiben in die gewählte Datei ist ein Fehler aufgetreten. Open Öffnen There was an error reading from the selected file. Beim Lesen aus der gewählten Datei ist ein Fehler aufgetreten. Save Speichern CFormBoat boat Boot &Add &beitragen file Datei Open Öffnen CFormHull hull Rumpf &Dimensions &Abmessungen CFormHullDefBase Dialog Dialog Deck and bottom Deck und Rumpf Planking Beplankung Automatic planking Automatische Beplankung lower plank angle Unterer Plankenwinkel top plank angle Oberer Plankenwinkel Number of planks Anzahl der Planken Bottom Boden Bottom sweep angle Unterer Anstellwinkel % % Max Width Max. Breite Forward shape Bug-Form Length Länge Forward height Bug-Höhe Max Width position Position max. Breite Stem angle Vorsteven-Winkel Transom angle Heckspiegel-Winkel Aft height Heck-Höhe Aft width Heck-Breite Aft shape Heckform Hull name Rumpfname Deck Deck Forward height Bug-Höhe Plank 5 Planke 5 Chine angle Unterer Rumpf-Winkel?? Sweep angle Kiel-Winkel Plank angle Plankenwinkel Plank 4 Planke 4 Plank 3 Planke 3 Plank 2 Planke 2 Plank 1 Planke 1 Plank 6 Planke 6 Check Prüfen OK OK Cancel Abbruch Dimensions are in millimeters and angles in degrees measured from horizontal Alle Massangaben sind in Millimeter und Grad zur Horizontalen Planks Planken txt_BBW txt_BfwdHeight txt_BLWL txt_BaftW txt_BaftHeight Dead rise angle txt_HullID txt_DaftHeight txt_DfwdHeight Side angle Seitenwinkel CFormMain to &DXF &DXF to &TXT sail &TXT Segel to &XML sail &XML Segel &New &Neu &Open Ö&ffnen &Save &Speichern Save &As Speichern &unter &Quit Be&enden &Dimensions &Abmessungen &Mould &Form &Patches &Verstärkungen &Rig &Rigg &File &Datei &View &Ansicht &Help &Hilfe About Sailcut CAD Über Sailcut CAD error Fehler There was an error writing to the selected file Beim Schreiben in die gewählte Datei ist ein Fehler aufgetreten About &Qt Über &Qt About &Sailcut CAD Über &Sailcut CAD Language Sprache Open &recent Zuletzt geöffnete P&rojekte E&xport 3D sail E&xport 3D-Segel to &Carlson plotter &Carlson Plotter Sailcut CAD &Handbook Sailcut CAD &Handbuch shaded view schattierte Ansicht wireframe view Ansicht als Drahtmodell development Entwicklung created new sail neu erstelltes Segel loaded '%1' geladen '%1' error loading '%1' Fehler beim Laden von '%1' wrote '%1' gespeichert '%1' There was a data printing error Beim Schreiben in die gewählte Datei ist ein Fehler aufgetreten There was a development printing error Fehler beim Drucken der Entwicklungsansicht There was a drawing printing error Fehler beim drucken der Zeichnung data Daten drawing Zeichnung &Print Dr&ucken Sail type Segeltyp Mainsail Großsegel Jib Fock Sail layout Segelschnitt Cross Cut Kreuzschnitt Horizontal Cut Horizontalschnitt Radial Cut Radialschnitt Twist Foot Cut Twist-Foot Schnitt Vertical Cut Vertikalschnitt Mitre Cut Gehrungsschnitt sections, Segmente, Rig Rigg Boat LOA Bootslänge LüA Fore triangle hoist I Höhe I des Vorsegeldreiecks Fore triangle base J Basis J des Vorsegeldreiecks Tack position X Segelhalsposition X Tack height Y Segelhalshöhe Y Sail dimensions Segelabmessungen Luff length Länge des Vorlieks Gaff angle wrt luff Gaffelwinkel relativ zum Vorliek Gaff length Länge der Gaffel Foot length Länge des Unterlieks Leech length Länge des Achterlieks Luff round Vorliek-Bogen Gaff round Gaffel-Bogen Leech round Achterliek-Bogen Foot round Unterliek-Bogen Luff round position Position des Vorliekbogens Gaff round position Position des Gaffelbogens Leech round position Position des Achterliekbogens Foot round position Position des Unterliekbogens Sail settings Eigenschaften des Segels Twist angle Verwindungswinkel Sheeting angle Winkel der Segelbahn Cloth seams and hems Bahnennähte und Säume Cloth width Bahnbreite Seams width Nahtbreite Leech hem width Breite des Achterlieksaumes Other hem width andere Saumbreiten Sail mould Segelform Luff factor Vorliegsfaktor Depth Tiefe Leech factor Achterlieksfaktor Top profile Oberes Profil Mid profile at h = Mittleres Profil bei Höhe h = Bottom profile Unteres Profil Mast/Luff rake Neigung der Mastspur head gores, Radialkeile im Kopfabschnitt Wing Tragfläche luff gores. Radialkeile beginnend am Kopf und endend am Segelhals. deg ° Export &development Export &Entwicklung to &Hand-plotting format ins &Hand-Plotterformat sail Segel hull Rumpf rig Rigg boat Boot &Window &Fenster &Close Be&enden Close &All Beenden &alles &Tile &Fliesen &Cascade &Kaskade unknown document type '%1' Fehler document type %1 Open Öffnen CFormMould &Cancel &Abbrechen Vertical repartition Senkrechte Teilung Sail mould Segelform &Help &Hilfe &OK &OK Top profile Oberes Profil Middle profile Mittleres Profil Bottom profile Unteres Profil CFormPanelGroup panels Tafeln CFormPrint &Print Dr&ucken &Cancel &Abbrechen Scale Skala CFormRig Rig Rigg &New &Neu sail &definition &Definition des Segels 3D &sail 3D &Segel &Add sail neues Segel &hinzufügen &Open Ö&ffnen Open &recent zuletzt geöffnete P&rojekte &Save &Speichern Save &As Speichern &unter &Close Be&enden &File &Datei error Fehler There was an error writing to the selected file Beim Schreiben in die gewählte Datei ist ein Fehler aufgetreten rig Rigg &Dimensions &Abmessungen CFormRigDefBase Rig dimensions Riggabmessungen Cancel Abbruch OK OK Spreaders Salinge = SPNB = SPNB Number of spreaders Anzahl der Sahlinge Spreader height Saling-Höhe txt_SPH2 txt_SPH1 txt_SPH3 SPH2 SPH3 SPH1 Spreader length Saling-Länge SPW3 txt_SPW3 SPW1 txt_SPW1 SPW2 txt_SPW2 Shrouds Wanten Cap shroud base width Basisweite der Oberwanten = CSH = CSH Lower shroud base width Basisweite der Unterwanten txt_LSB txt_CSH = CSB = CSB Cap shroud height Oberwanten-Höhe txt_CSB = LSB = LSB Fore triangle Vorsegel-Dreieck txt_foreI = I = I txt_foreJ = J = J Fore triangle base Basis des Vorsegeldreiecks Fore triangle hoist Höhe des Vorsegeldreiecks Mast Mast Mast width Mastbreite = MW = MW txt_MW txt_MC = MC = MC Mast cord Mastschnur lbl_MRkD = MRkD = MRkD Mast rake angle Mastfallwinkel txt_MH txt_MRnd Mast rake Mastfall = MRkM = MRkM txt_MRkM Mast height Masthöhe = MH = MH = MRnd = MRnd Mast round Mast-Bogen = MRndPos = MRndPos Mast round position Position des mastbogens Mainsail Großsegel lbl_MS_LuffRP @ @ lbl_MS_LuffR lbl_MS_TackY Y = Y = lbl_MS_TackX X = X = Tack Segelhals lbl_MS_LuffL = MSL = MSL Luff length Länge des Vorlieks Luff round Vorliek-Bogen lbl_MS_Rake = MSR = MSR Luff rake Neigung der Vorliek Tack height Segelhalshöhe txt_BAD = BAD = BAD Head height Höhe des Segelkopfes = HAD = HAD txt_HAD Check Prüfen All dimensions are in millimeter and angles in degrees Alle Massangaben sind in Millimeter und Grad Description of rig Beschreibung des Riggs Rig name Name des Riggs CFormSail sail Segel &Print Dr&ucken data Daten drawing Zeichnung development Entwicklung E&xport 3D sail E&xport 3D-Segel to &DXF &DXF to &TXT sail &TXT Segel to &XML sail &XML Segel Export &development Export &Entwicklung to &Carlson plotter &Carlson Plotter to &Hand-plotting format ins &Hand-Plotterformat &Dimensions &Abmessungen &Mould &Form &Patches &Verstärkungen error Fehler There was a data printing error Beim Schreiben in die gewählte Datei ist ein Fehler aufgetreten There was a development printing error Fehler beim Drucken der Entwicklungsansicht There was a drawing printing error Fehler beim drucken der Zeichnung to &SVG &SVG to DXF (split) DXF (geteilt) CFormSailDef Sail corners coordinates Eckpunktkoordinaten des Segels tack Segelhals clew Schothorn head Kopf peak Nock IRC width measurements IRC - Breite Sail width measurements Segel breite CFormSailDefBase Sail definition Definition des Segels Sail dimensions Segelabmessungen mm mm Round position Position des Bogens Luff length Länge des Vorlieks Foot length Länge des Unterlieks Leech length Länge des Achterlieks Gaff length Länge der Gaffel Leech round Achterliek-Bogen Gaff round Gaffel-Bogen Luff round Vorliek-Bogen Foot round Unterliek-Bogen % % deg ° Gaff angle from luff Gaffelwinkel relativ zum Vorliek Rig geometry Geometrie der Takelage Fore triangle base J Basis J des Vorsegeldreiecks Tack height Segelhalshöhe Distance tack to stem Abstand zwischen Segelhals und Vorsteven Main sail Großsegel Jib Fock Fore triangle hoist I Höhe I des Vorsegeldreiecks Boat length LOA Bootslänge LüA Mast / Luff rake Neigung der Mastspur Cloth Material Seam width Nahtbreite Cloth width Bahnbreite Layout Schnitt Mitre cut Gehrungsschnitt Cross cut Kreuzschnitt Twist foot Twist-Foot Schnitt Horizontal cut Horizontalschnitt Number of sections Anzahl der Segmente Number of radial gores Anzahl der Radialkeile Radial cut Radialschnitt Vertical cut Vertikalschnitt Sail shape Segelform Top depth Obere Segeltiefe Mid depth Mittlere Segeltiefe Foot depth Untere Segeltiefe Twist angle Verwindungswinkel OK OK Cancel Abbruch Leech hem Achterlieksaum Other hems Andere Säume Sheeting angle Winkel der Segelbahn Sail area Segelfläche Diagonal Diagonale Compute Berechnen Sail ID Segel ID Number of luff gores Anzahl der Radialkeile beginnend am Kopf und endend am Segelhals Dihedral angle Öffnungswinkel Wing Tragfläche Sail identifier Segelnummer m2 m2 Sail name Name von Segel Luff rake Neigung der Vorliek Mitre cut 2 Gehrungsschnitt 2 Foot hem Unterlieksaum CRigSailWidget Sail information Information des Segels file Datei name Bezeichnung Reload neu laden Remove Entfernen Update Aktualisieren error Fehler There was an error reading from the selected file. Beim Lesen aus der gewählten Datei ist ein Fehler aufgetreten. CSailDataPrinter Sailcut CAD data sheet Sailcut CAD Datenblatt Mainsail Großsegel Jib Fock Wing Tragfläche deg ° Sail type Segeltyp Cross Cut Kreuzschnitt Horizontal Cut Horizontalschnitt Radial Cut Radialschnitt sections Segmente head gores Radialkeile im Kopfabschnitt luff gores Radialkeile beginnend am Kopf und endend am Segelhals Twist Foot Cut Twist-Foot Schnitt Vertical Cut Vertikalschnitt Mitre Cut Gehrungsschnitt Mitre Cut 2 Gehrungsschnitt 2 Sail layout Segelschnitt Rig Rigg Boat LOA Bootslänge LüA Mast/Luff rake Neigung der Mastspur Tack position X Segelhalsposition X Tack height Y Segelhalshöhe Y Fore triangle hoist I Höhe I des Vorsegeldreiecks Fore triangle base J Basis J des Vorsegeldreiecks Sail dimensions Segelabmessungen Luff length Länge des Vorlieks Foot length Länge des Unterlieks Leech length Länge des Achterlieks Gaff length Länge der Gaffel Gaff angle wrt luff Gaffelwinkel relativ zum Vorliek Shape of edges Gestalt von Rändern Luff round Vorliek-Bogen Luff round position Position des Vorliekbogens Foot round Unterliek-Bogen Foot round position Position des Unterliekbogens Leech round Achterliek-Bogen Leech round position Position des Achterliekbogens Gaff round Gaffel-Bogen Gaff round position Position des Gaffelbogens Sail settings Eigenschaften des Segels Twist angle Verwindungswinkel Sheeting angle Winkel der Segelbahn Cloth seams and hems Bahnennähte und Säume Cloth width Bahnbreite Seams width Nahtbreite Leech hem width Breite des Achterlieksaumes Foot hem width Breite des Unterlieksaumes Other hems width andere Saumbreiten Sail mould Segelform Luff factor Vorliegsfaktor Depth Tiefe Leech factor Achterlieksfaktor Top profile Oberes Profil Mid profile at h = Mittleres Profil bei Höhe h = Bottom profile Unteres Profil Luff rake Neigung der Vorliek CSailDevelPrinter Scale Skala CSailDispGL This system has no OpenGL support. Dieses System hat keine OpenGL Unterstützung. CSailDrawingPrinter Scale Skala CSailPrinter Sailcut CAD data sheet Sailcut CAD Datenblatt Mainsail Großsegel Jib Fock Wing Tragfläche deg ° Sail type Segeltyp Cross Cut Kreuzschnitt Horizontal Cut Horizontalschnitt Radial Cut Radialschnitt sections Segmente head gores Radialkeile im Kopfabschnitt luff gores Radialkeile beginnend am Kopf und endend am Segelhals Twist Foot Cut Twist-Foot Schnitt Vertical Cut Vertikalschnitt Mitre Cut Gehrungsschnitt Sail layout Segelschnitt Rig Rigg Boat LOA Bootslänge LüA Mast/Luff rake Neigung der Mastspur Tack position X Segelhalsposition X Tack height Y Segelhalshöhe Y Fore triangle hoist I Höhe I des Vorsegeldreiecks Fore triangle base J Basis J des Vorsegeldreiecks Sail dimensions Segelabmessungen Luff length Länge des Vorlieks Foot length Länge des Unterlieks Leech length Länge des Achterlieks Gaff length Länge der Gaffel Gaff angle wrt luff Gaffelwinkel relativ zum Vorliek Shape of edges Gestalt von Rändern Luff round Vorliek-Bogen Luff round position Position des Vorliekbogens Foot round Unterliek-Bogen Foot round position Position des Unterliekbogens Leech round Achterliek-Bogen Leech round position Position des Achterliekbogens Gaff round Gaffel-Bogen Gaff round position Position des Gaffelbogens Sail settings Eigenschaften des Segels Twist angle Verwindungswinkel Sheeting angle Winkel der Segelbahn Cloth seams and hems Bahnennähte und Säume Cloth width Bahnbreite Seams width Nahtbreite Leech hem width Breite des Achterlieksaumes Other hem width andere Saumbreiten Sail mould Segelform Luff factor Vorliegsfaktor Depth Tiefe Leech factor Achterlieksfaktor Top profile Oberes Profil Mid profile at h = Mittleres Profil bei Höhe h = Bottom profile Unteres Profil CSailViewerPanel Display parameters Anzeigeparameter elevation vertikal azimuth horizontal Controls Darstellung Reset view Ansicht zurücksetzen Labeling Segelzeichen Zoom in Einzoomen Zoom out Auszoomen deg ° CSailViewerTabs shaded view schattierte Ansicht wireframe view Ansicht als Drahtmodell CWidgetProfile % % Luff shape Vorliekform Depth Tiefe Leech shape Achterliekform degrees ° cord Schnur Dialog Dialog Dialog XmlReaderTempl error Fehler There was an error reading from the selected file. Beim Lesen aus der gewählten Datei ist ein Fehler aufgetreten. sailcut-1.5.0/src/ts/sailcut_dk.ts000066400000000000000000002643051477005247400171140ustar00rootroot00000000000000 CBoatElementWidget Sail information Sejl information file fil name navn Reload Genindlæs Remove Fjern Update Opdater Element information CFileIO Open Åben Save Gem CFileWriter error Fejl There was an error writing to the selected file. Det var ikke muligt at skrive til den ønskede fil. Open Åben There was an error reading from the selected file. Det var ikke muligt at læse den ønskede fil. Save Gem CFormBoat boat båden &Add &Tilføj file fil Open Åben CFormHull hull &Dimensions &Dimensionering CFormHullDefBase Dialog Deck and bottom Planking Automatic planking lower plank angle top plank angle Number of planks Bottom Bottom sweep angle % % Max Width Forward shape Length Forward height Max Width position Stem angle Transom angle Aft height Aft width Aft shape Hull name Deck Forward height Plank 5 Chine angle Sweep angle Plank angle Plank 4 Plank 3 Plank 2 Plank 1 Plank 6 Check OK OK Cancel Annuller Dimensions are in millimeters and angles in degrees measured from horizontal Planks txt_BBW txt_BfwdHeight txt_BLWL txt_BaftW txt_BaftHeight Dead rise angle txt_HullID txt_DaftHeight txt_DfwdHeight Side angle CFormMain &New &Ny &Open &Åben Open &recent Åben &seneste data data drawing tegning develop design &Print &Udskriv &Save &Gem Save &As Gem &Som to &DXF til &DXF format to &TXT sail til &TXT format to &XML sail til &XML format E&xport 3D sail E&ksporter 3D sejl to &Carlson plotter til C&arlson plotter Export &development Eksporter &design sæt &Quit &Afslut &Dimensions &Dimensionering &Mould &Form &Patches &Hjørnelapper &Rig &Rig Language Sprog Sailcut CAD &Handbook Sailcut CAD &Håndbog About &Qt Om &Qt About &Sailcut CAD Om &Sailcut CAD &File &Fil &View &Vælg &Help &Hjælp shaded view 3D visning wireframe view Trådramme visning development Design sæt loaded '%1' Åbnet '%1' created new sail udviklet nyt sejl About Sailcut CAD Om Sailcut CAD error loading '%1' Fejl i åbning '%1' Sail type Sejl type Mainsail Storsejl Jib Fok Sail layout Sejl layout Cross Cut Cross Cut Horizontal Cut Horisontal Cut Radial Cut Radial Cut Twist Foot Cut Twistet Foot Cut Vertical Cut Vertikal Cut Mitre Cut Mitre Cut sections, sektioner head gores, hoved kiler luff gore. forli kiler. Rig Rig Boat LOA Bådens LOA Fore triangle hoist I Forstags længde I mål Fore triangle base J Afstand fra forstævn til mast, J mål Tack position X Halsbarm position X Tack height Y Halsbarm højde Y Sail dimensions Sejl dimensioner Luff length Forli længde Mast/Luff rake Maste/Forli hældning Gaff angle wrt luff Gaffel vinkel fra forli Gaff length Gaffel længde Foot length Sejlfod længde Leech length Bagli længde Shape of edges Kanternes form Luff round Forli runding Gaff round Gaffel runding Leech round Bagli runding Foot round Sejlfod runding Luff round position Forli rundings position Gaff round position Position af Gaffel runding Leech round position Bagli rundings position Foot round position Sejlfods rundings position Sail settings Sejl egenskaber Twist angle Tvist vinkel Sheeting angle Lag vinkel Cloth seams and hems Sømme og kantninger Cloth width Tekstil bredde Seams width Sømbredde Leech hem width Bredde på bagli søm Other hem width Andre søm bredde Sail mould Sejl form Luff factor Forli faktor Depth Dybde Leech factor Bagli faktor Top profile Øverste profil Mid profile at h = Midter profil ved h = Bottom profile Nederste profil error fejl There was a data printing error Der var fejl ved udskrivning af data There was a development printing error Der var fejl ved udskrivning af design sæt There was a drawing printing error Der var fejl ved udskrivning af tegning wrote '%1' skrevet '%1' There was an error writing to the selected file Det var ikke muligt at skrive til den valgte fil Wing Vinge luff gores. forli kiler. deg grd to &Hand-plotting format &Håndplotting format sail Sejl hull rig boat båden &Window &Close &Luk Close &All &Tile &Cascade unknown document type '%1' Open Åben CFormMould Top profile Øverste profil Middle profile Mellemste profil Bottom profile Nederste profil Sail mould Sejl form &Help &Hjælp &OK &OK &Cancel &Annuller Vertical repartition Vertikal omopdeling CFormPanelGroup panels CFormPrint &Print &Udskriv &Cancel &Annuller Scale CFormRig Rig Rig &New &Ny sail &definition sejl &defination 3D &sail 3D &sejl &Add sail &Tilføj sejl &Open &Åbne Open &recent Åbne &seneste &Save &Gem Save &As Gem &Som &Close &Luk &File &Fil error Fejl There was an error writing to the selected file Det var ikke muligt at skrive til den ønskede fil rig Rig &Dimensions &Dimensionering CFormRigDefBase Rig dimensions Rig dimensioner Cancel Annuller OK OK Spreaders = SPNB Number of spreaders Spreader height txt_SPH2 txt_SPH1 txt_SPH3 SPH2 SPH3 SPH1 Spreader length SPW3 txt_SPW3 SPW1 txt_SPW1 SPW2 txt_SPW2 Shrouds Cap shroud base width = CSH Lower shroud base width txt_LSB txt_CSH = CSB Cap shroud height txt_CSB = LSB Fore triangle txt_foreI = I txt_foreJ = J Fore triangle base Fore triangle hoist Mast Mast width = MW txt_MW txt_MC = MC Mast cord lbl_MRkD = MRkD Mast rake angle txt_MH txt_MRnd Mast rake = MRkM txt_MRkM Mast height = MH = MRnd Mast round = MRndPos Mast round position Mainsail Storsejl lbl_MS_LuffRP @ lbl_MS_LuffR lbl_MS_TackY Y = lbl_MS_TackX X = Tack lbl_MS_LuffL = MSL Luff length Luff round Forli runding lbl_MS_Rake = MSR Luff rake Forli hældning Tack height txt_BAD = BAD Head height = HAD txt_HAD Check All dimensions are in millimeter and angles in degrees Description of rig Rig name CFormSail sail Sejl &Print &Udskriv data data drawing tegning development Design sæt E&xport 3D sail E&ksporter 3D sejl to &DXF til &DXF format to &TXT sail til &TXT format to &XML sail til &XML format Export &development Eksporter &design sæt to &Carlson plotter til C&arlson plotter to &Hand-plotting format &Håndplotting format &Dimensions &Dimensionering &Mould &Form &Patches &Hjørnelapper error Fejl There was a data printing error Der var fejl ved udskrivning af data There was a development printing error Der var fejl ved udskrivning af design sæt There was a drawing printing error Der var fejl ved udskrivning af tegning to &SVG &SVG to DXF (split) CFormSailDef Sail corners coordinates Sejllhjørne koordinator tack halsbarm clew klampe head hoved peak top IRC width measurements IRC med målinger Sail width measurements Sejl med målinger CFormSailDefBase Sail definition Sejl defination Sail shape Sejl form % % Top depth Top dybde Mid depth Mellem dybde Foot depth Sejlfod dybde Twist angle Tvist vinkel Sheeting angle Lag vinkel deg grd Sail dimensions Sejl dimension mm mm Round position Rundings position Luff length Forli længde Foot length Sejlfod længde Leech length Bagli længde Gaff length Gaffel længde Leech round Bagli runding Luff round Forli runding Foot round Fodrunding Gaff round Gaffel runding Gaff angle from luff Gaffel vinkel fra forli Diagonal Diagonal Sail area Sejl areal Compute Beregn OK OK Cancel Annuller Layout Layout Mitre cut Mitre cut Cross cut Cross cut Twist foot Vridning ved fod Horizontal cut Horisontal cut Vertical cut Vertikal cut Number of luff gores Antal af forli kiler Number of radial gores Antal af radiale kiler Number of sections Antal af sektioner Radial cut Radial Cut Cloth Tekstil Cloth width Tekstil bredde Leech hem Bagli kantning Other hems Andre kantning Seam width Søm bredde Rig geometry Rig geometri Fore triangle hoist I Forstags længde L mål Mast / Luff rake Mast/forli hældning Fore triangle base J Afstand fra forstævn til mast, J mål Distance tack to stem Afstand fra halsbarm til for stævn Tack height Halsbarm højde Boat length LOA Bådlængde LOA Sail ID Sejl ID Main sail Storsejl Jib Fok Dihedral angle Toplansvinkel Wing Vinge Sail identifier Sejl identifikation m2 m2 Sail name Luff rake Forli hældning Mitre cut 2 Mitre cut 2 Foot hem Sejlfod kantning CRigSailWidget Sail information Sejl information file fil name navn Reload Genindlæs Remove Fjern Update Opdater error fejl There was an error reading from the selected file. Det var ikke muligt at læse den ønskede fil. CSailDataPrinter Sailcut CAD data sheet Sailcut CAD data side Mainsail Storsejl Jib Fok Wing Vinge deg grd Sail type Sejl type Cross Cut Cross Cut Horizontal Cut Horisontal Cut Radial Cut Radial Cut sections sektioner head gores hoved kiler luff gores forli kiler Twist Foot Cut Twistet Foot Cut Vertical Cut Vertikal Cut Mitre Cut Mitre Cut Mitre Cut 2 Mitre cut 2 Sail layout Sejl layout Rig Rig Boat LOA Bådens LOA Mast/Luff rake Maste/Forli hældning Tack position X Halsbarm position X Tack height Y Halsbarm højde Y Fore triangle hoist I Forstags længde I mål Fore triangle base J Afstand fra forstævn til mast, J mål Sail dimensions Luff length Forli længde Foot length Sejlfod længde Leech length Bagli længde Gaff length Gaffel længde Gaff angle wrt luff Gaffel vinkel fra forli Shape of edges Kanternes form Luff round Forli runding Luff round position Forli rundings position Foot round Sejlfod runding Foot round position Sejlfods rundings position Leech round Bagli runding Leech round position Bagli rundings position Gaff round Gaffel runding Gaff round position Position af Gaffel runding Sail settings Sejl egenskaber Twist angle Tvist vinkel Sheeting angle Lag vinkel Cloth seams and hems Sømme og kantninger Cloth width Tekstil bredde Seams width Sømbredde Leech hem width Bredde på bagli søm Foot hem width Other hems width Andre søm bredde Sail mould Sejl form Luff factor Forli faktor Depth Dybde Leech factor Bagli faktor Top profile Øverste profil Mid profile at h = Midter profil ved h = Bottom profile Nederste profil Luff rake Forli hældning CSailDevelPrinter Scale CSailDispGL This system has no OpenGL support. Dette system understøtter ikke OpenGL. CSailDrawingPrinter Scale CSailPrinter Sailcut CAD data sheet Sailcut CAD data side Mainsail Storsejl Jib Fok Wing Vinge deg grd Sail type Sejl type Cross Cut Cross Cut Horizontal Cut Horisontal Cut Radial Cut Radial Cut sections sektioner head gores hoved kiler luff gores forli kiler Twist Foot Cut Twistet Foot Cut Vertical Cut Vertikal Cut Mitre Cut Mitre Cut Sail layout Sejl layout Rig Rig Boat LOA Bådens LOA Mast/Luff rake Maste/Forli hældning Tack position X Halsbarm position X Tack height Y Halsbarm højde Y Fore triangle hoist I Forstags længde I mål Fore triangle base J Afstand fra forstævn til mast, J mål Sail dimensions Sejl dimension Luff length Forli længde Foot length Sejlfod længde Leech length Bagli længde Gaff length Gaffel længde Gaff angle wrt luff Gaffel vinkel fra forli Shape of edges Kanternes form Luff round Forli runding Luff round position Forli rundings position Foot round Fodrunding Foot round position Sejlfods rundings position Leech round Bagli runding Leech round position Bagli rundings position Gaff round Gaffel runding Gaff round position Position af Gaffel runding Sail settings Sejl egenskaber Twist angle Tvist vinkel Sheeting angle Lag vinkel Cloth seams and hems Sømme og kantninger Cloth width Tekstil bredde Seams width Sømbredde Leech hem width Bredde på bagli søm Other hem width Andre søm bredde Sail mould Sejl form Luff factor Forli faktor Depth Dybde Leech factor Bagli faktor Top profile Øverste profil Mid profile at h = Midter profil ved h = Bottom profile Nederste profil CSailViewerPanel Display parameters Vis parameter elevation højde azimuth azimut Controls Kontroller Reset view Nulstil visning Labeling Bane nummerering Zoom in Forstør Zoom out Formindsk deg grd CSailViewerTabs shaded view 3D visning wireframe view Trådramme visning CWidgetProfile Luff shape Forli form Depth Dybde % % Leech shape Bagli form degrees grader cord Dialog XmlReaderTempl error fejl There was an error reading from the selected file. Det var ikke muligt at læse den ønskede fil. sailcut-1.5.0/src/ts/sailcut_fr.ts000066400000000000000000002520171477005247400171220ustar00rootroot00000000000000 CBoatElementWidget Sail information Informations sur la voile file fichier name nom Reload Recharger Remove Retirer Update Mettre à jour Element information Information sur l'élément CFileIO Open Ouvrir Save Enregistrer CFileWriter error erreur There was an error writing to the selected file. Une erreur s'est produite lors de l'écriture du fichier. Open Ouvrir There was an error reading from the selected file. Il y a eu une erreur de lecture du fichier choisi. Save Enregistrer CFormBoat boat bateau &Add &Ajouter file fichier Open Ouvrir CFormHull hull coque &Dimensions &Dimensions CFormHullDefBase Dialog Dialogue Deck and bottom Pont et fond Planking Bordé Automatic planking Bordage automatique lower plank angle angle du bordé inférieur top plank angle angle du bordé supérieur Number of planks Nombre de bordés Bottom Fond Bottom sweep angle Angle d'avance du fond % % Max Width Largeur maximum Bottom dead rise angle Angle du fond Forward shape Forme avant Length Longueur Forward height Hauteur avant Max Width position Position de la largeur maximum Side slope angle Inclinaison latérale Stem angle Angle de l'étrave Transom angle Angle du tableau Aft height Hauteur arrière Aft width Largeur arrière Aft shape Forme arrière Hull name Nom de la coque Deck Pont Forward height Hauteur avant Side Planks Bordés Plank 5 Bordé 5 Chine angle angle du bouchain Sweep angle angle d'avance Plank angle angle du bordé Plank 4 Bordé 4 Plank 3 Bordé 3 Plank 2 Bordé 2 Plank 1 Bordé 1 Plank 6 Bordé 6 Check Vérifier OK OK Cancel Annuler Dimensions are in millimeters and angles in degrees measured from horizontal Les dimensions sont en millimètres et les angles en degrés par rapport à l'horizontale Planks Bordés txt_BBW txt_BfwdHeight txt_BLWL txt_BaftW txt_BaftHeight Dead rise angle Angle du fond txt_HullID txt_DaftHeight txt_DfwdHeight Side angle CFormMain to &DXF &DXF to &TXT sail voile &TXT to &XML sail voile &XML &New &Nouveau &Open &Ouvrir &Save &Enregistrer Save &As Enregistrer &sous &Quit &Quitter &Dimensions &Dimensions &Mould &Moule &Patches &Renforts &Rig &Gréement &File &Fichier &View &Vue &Help &Aide About Sailcut CAD A propos de Sailcut CAD error erreur There was an error writing to the selected file Une erreur s'est produite lors de l'écriture du fichier About &Qt A propos de &Qt About &Sailcut CAD A propos de &Sailcut CAD to &Carlson plotter table traçante &Carlson shaded view vue rendu 3D wireframe view vue fil de fer development développement created new sail nouvelle voile créée E&xport 3D sail E&xport voile 3D Export &development Export &développement Sailcut CAD &Handbook &Manuel de Sailcut CAD Open &recent Ouvrir fichier &récent loaded '%1' chargé '%1' error loading '%1' erreur de chargement '%1' wrote '%1' écrit '%1' There was a data printing error Erreur lors de l'impression des données There was a development printing error Erreur lors de l'impression du développement There was a drawing printing error Erreur lors de l'impression du dessin data données drawing dessin develop développement &Print &Imprimer Sail type Type de voile Mainsail Grand-voile Jib Foc Sail layout Type de coupe Cross Cut Coupe transverse Horizontal Cut Coupe horizontale Radial Cut Coupe radiale Twist Foot Cut Coupe twist Foot Vertical Cut Coupe verticale Mitre Cut Coupe à mitre sections, sections, head gores. fuseaux de tête. Rig Gréement Boat LOA Longueur du bateau Fore triangle hoist I Hauteur I du triangle avant Fore triangle base J Base J du triangle avant Tack position X Position X de l'amure Tack height Y Hauteur Y de l'amure Sail dimensions Dimensions de la voile Luff length Longueur guindant Mast rake Quête du mat Gaff angle wrt luff Angle vergue / guindant Gaff length Longueur vergue Foot length Longueur bordure Leech length Longueur chute Shape of edges Forme des bords Luff round Rond du guindant Gaff round Rond de la vergue Leech round Rond de la chute Foot round Rond de la bordure Luff round position Position du rond de guindant Gaff round position Position du rond de la gaffe Leech round position Position du rond de chute Foot round position Position du rond de bordure Sail settings Réglage de la voile Twist angle Angle de vrillage Sheeting angle Angle d'ouverture Cloth seams and hems Tissu, coutures et ourlets Cloth width Largeur du tissu Seams width Largeur des coutures Leech hem width Largeur pour ourlet chute Other hem width Largeur pour autres ourlets Sail mould Moule de voile Luff factor Forme guindant Depth Creux Leech factor Forme chute Top profile Profil supérieur Mid profile at h = Profil médian à h = Bottom profile Profil inférieur Language Langue Mast/Luff rake Quête du mât / guidant head gores, fuseaux de tête, luff gore. fuseau coté guindant. Wing Aile luff gores. fuseaux de guindant. E&xport &development E&xport développement to &hand-plotting format format coupe &manuelle deg deg to &Hand-plotting format pour traçage &manuel sail voile hull coque rig gréement boat bateau &Window F&enêtre &Close &Fermer Close &All &Tout fermer &Tile &Mosaic &Cascade &Cascade unknown document type '%1' Document inconnu type '%1' Open Ouvrir CFormMould &Cancel &Annuler Vertical repartition Répartition verticale Sail mould Moule de voile &Help &Aide &OK &OK Top profile Profil supérieur Middle profile Profil médian Bottom profile Profil inférieur CFormPanelGroup panels panneau CFormPrint &Print &Imprimer &Cancel &Annuler Scale Echelle CFormRig &New &Nouveau sail &definition &définition de voile 3D &sail &voile 3D &Add sail &Ajouter une voile &Open &Ouvrir &Save &Enregistrer Save &As Enregistrer &sous &Close &Fermer &File &Fichier error erreur There was an error writing to the selected file Une erreur s'est produite lors de l'écriture du fichier Rig Gréement Open &recent Ouvrir fichier &récent rig gréement &Dimensions &Dimensions CFormRigDefBase Rig dimensions Dimension du gréement Cancel Annuler OK OK Spreaders Barres de flèche = SPNB = SPNB Number of spreaders Nombre de barres de flèche Spreader height Hauteur barre de flèche txt_SPH2 txt_SPH1 txt_SPH3 SPH2 SPH2 SPH3 SPH3 SPH1 SPH1 Spreader length Longueur barre de flèche SPW3 SPW3 txt_SPW3 SPW1 SPW1 txt_SPW1 SPW2 SPW2 txt_SPW2 Shrouds Hauban Cap shroud base width Base du hauban de tête = CSH = CSH Lower shroud base width Base bas hauban txt_LSB txt_CSH = CSB = CSB Cap shroud height Hauteur hauban de tête txt_CSB = LSB = LSB Fore triangle Triangle avant txt_foreI = I = I txt_foreJ = J = J Fore triangle base Base triangle avant Fore triangle hoist Hauteur triangle avant Mast Mât Mast width Largeur du mât = MW = MW txt_MW txt_MC = MC = MC Mast cord Corde du mât lbl_MRkD = MRkD = MRkD Mast rake angle Angle de quête du mât txt_MH txt_MRnd Mast rake Quête du mât = MRkM = MRkM txt_MRkM Mast height Hauteur du mât = MH = MH = MRnd = MRnd Mast round Rond du mât = MRndPos = MRndPos Mast round position Position du rond du mât Mainsail Grand-voile lbl_MS_LuffRP @ @ lbl_MS_LuffR lbl_MS_TackY Y = Y = lbl_MS_TackX X = X = Tack Amure lbl_MS_LuffL = MSL = MSL Luff length Longueur du guindant Luff round Rond du guindant lbl_MS_Rake = MSR = MSR Luff rake Inclinaison du guindant Tack height Hauteur de l'amure txt_BAD = BAD = BAD Head height Hauteur de tête = HAD = HAD txt_HAD Check Vérifier All dimensions are in millimeter and angles in degrees Toutes les dimensions sont en millimetre et les angles en degrés Rig ID Identification du gréement Description of rig Description du gréement Rig name Nom du gréement CFormSail sail voile &Print &Imprimer data données drawing dessin development développement E&xport 3D sail E&xport voile 3D to &DXF &DXF to &TXT sail voile &TXT to &XML sail voile &XML Export &development Export &développement to &Carlson plotter table traçante &Carlson to &Hand-plotting format pour traçage &manuel &Dimensions &Dimensions &Mould &Moule &Patches &Renforts error erreur There was a data printing error Erreur lors de l'impression des données There was a development printing error Erreur lors de l'impression du développement There was a drawing printing error Erreur lors de l'impression du dessin to &SVG &SVG to DXF (split) DXF (divisé) CFormSailDef Sail corners coordinates Coordonnées des coins de la voile tack amure clew écoute head tête peak pic IRC width measurements Largeurs mesurées IRC Sail width measurements Mesures de la largeur de la voile CFormSailDefBase Sail definition Définition de la voile Sail dimensions Dimensions de la voile mm mm Round position Position du rond Luff length Longueur guindant Foot length Longueur bordure Leech length Longueur chute Gaff length Longueur vergue Leech round Rond de la chute Gaff round Rond de la vergue Luff round Rond du guindant Foot round Rond de la bordure % % deg deg Gaff angle from luff Angle vergue / guindant Rig geometry Géométrie du gréement Fore triangle base J Base J du triangle avant Tack height Hauteur du point d'amure Distance tack to stem Distance étrave-amure Main sail Grand-voile Jib Foc Fore triangle hoist I Hauteur I du triangle avant Boat length LOA Longueur du bateau Mast / Luff rake Quête du mât / guidant Cloth Tissus Seam width Largeur coutures Cloth width Largeur tissu Layout Coupe Mitre cut Coupe mître Cross cut Coupe transversale Twist foot Coupe twist Horizontal cut Coupe horizontale Number of sections Nbre de sections Number of radial gores Nbre de fuseaux radiaux Radial cut Coupe radiale Vertical cut Coupe verticale Sail shape Forme de voile Top depth Creux en haut Mid depth Creux au milieu Foot depth Creux de bordure Twist angle Angle de vrillage OK OK Cancel Annuler Leech hem Ourlet chute Other hems Ourlet autres Sheeting angle Ouverture de la voile Sail area Surface de la voile Diagonal Diagonale Compute Calculer Sail ID Identification de la voile Number of luff gores Nombre de fuseaux guindant Dihedral angle Angle de dièdre Wing Aile Sail identifier Identifiant de la voile m2 m2 Luff rake Quête du guindant Mitre cut 2 Coupe mître 2 Foot hem Ourlet bordure Sail name Nom de la voile CRigSailWidget Sail information Informations sur la voile file fichier name nom Remove Retirer Update Mettre a jour Reload Recharger error erreur There was an error reading from the selected file. Une erreur s'est produite lors de la lecture du fichier sélectionné. CSailDataPrinter Sailcut CAD data sheet Données Sailcut CAD Mainsail Grand-voile Jib Foc Wing Aile deg deg Sail type Type de voile Cross Cut Coupe transverse Horizontal Cut Coupe horizontale Radial Cut Coupe radiale sections sections head gores fuseaux de tête luff gores fuseaux de guindant Twist Foot Cut Coupe twist foot Vertical Cut Coupe verticale Mitre Cut Coupe à mitre Mitre Cut 2 Coupe à mître 2 Sail layout Type de coupe Rig Gréement Boat LOA Longueur du bateau Mast/Luff rake Quête du mât / guidant Tack position X Position X de l'amure Tack height Y Hauteur Y de l'amure Fore triangle hoist I Hauteur I du triangle avant Fore triangle base J Base J du triangle avant Sail dimensions Dimensions de la voile Luff length Longueur guindant Foot length Longueur bordure Leech length Longueur chute Gaff length Longueur vergue Gaff angle wrt luff Angle vergue / guindant Shape of edges Forme des bords Luff round Rond du guindant Luff round position Position du rond de guindant Foot round Rond de la bordure Foot round position Position du rond de bordure Leech round Rond de la chute Leech round position Position du rond de chute Gaff round Rond de la vergue Gaff round position Position du rond de la gaffe Sail settings Réglage de la voile Twist angle Angle de vrillage Sheeting angle Angle de tire Cloth seams and hems Tissu, coutures et ourlets Cloth width Largeur du tissu Seams width Largeur des coutures Leech hem width Largeur pour ourlet chute Foot hem width Largeur pour ourlet bordure Other hems width Largeur pour autres ourlets Sail mould Moule de voile Luff factor Forme guindant Depth Creux Leech factor Forme chute Top profile Profil supérieur Mid profile at h = Profil médian à h = Bottom profile Profil inférieur Luff rake CSailDevelPrinter Scale Echelle CSailDispGL This system has no OpenGL support. OpenGL n'est pas disponible sur cette machine. CSailDrawingPrinter Scale Echelle CSailPrinter Sailcut CAD data sheet Données Sailcut CAD Mainsail Grand-voile Jib Foc Wing Aile deg deg Sail type Type de voile Cross Cut Coupe transverse Horizontal Cut Coupe horizontale Radial Cut Coupe radiale sections sections head gores fuseaux de tête luff gores fuseaux de guindant Twist Foot Cut Coupe twist foot Vertical Cut Coupe verticale Mitre Cut Coupe à mitre Sail layout Type de coupe Rig Gréement Boat LOA Longueur du bateau Mast/Luff rake Quête du mât / guidant Tack position X Position X de l'amure Tack height Y Hauteur Y de l'amure Fore triangle hoist I Hauteur I du triangle avant Fore triangle base J Base J du triangle avant Sail dimensions Dimensions de la voile Luff length Longueur guindant Foot length Longueur bordure Leech length Longueur chute Gaff length Longueur vergue Gaff angle wrt luff Angle vergue / guindant Shape of edges Forme des bords Luff round Rond du guindant Luff round position Position du rond de guindant Foot round Rond de la bordure Foot round position Position du rond de bordure Leech round Rond de la chute Leech round position Position du rond de chute Gaff round Rond de la vergue Gaff round position Position du rond de la gaffe Sail settings Réglage de la voile Twist angle Angle de vrillage Sheeting angle Ouverture de la voile Cloth seams and hems Tissu, coutures et ourlets Cloth width Largeur du tissu Seams width Largeur des coutures Leech hem width Largeur pour ourlet chute Other hem width Largeur pour autres ourlets Sail mould Moule de voile Luff factor Forme guindant Depth Creux Leech factor Forme chute Top profile Profil supérieur Mid profile at h = Profil médian à h = Bottom profile Profil inférieur CSailViewerPanel Display parameters Paramètres d'affichage elevation élévation azimuth azimuth Controls Controles Reset view Réinitialiser la vue Labeling Etiquettes Zoom in Zoom avant Zoom out Zoom arrière deg deg CSailViewerTabs shaded view vue rendu 3D wireframe view vue fil de fer CWidgetProfile % % Luff shape Forme guindant Depth Creux Leech shape Forme chute degrees degrés cord corde Dialog Dialog Dialogue All panels in a single file Tous les panneaux dans un seul fichier One file per panel Un fichier par panneau XmlReaderTempl error erreur There was an error reading from the selected file. Une erreur s'est produite à la lecture du fichier sélectionné. sailcut-1.5.0/src/ts/sailcut_it.ts000066400000000000000000002466021477005247400171320ustar00rootroot00000000000000 CBoatElementWidget Sail information Informazioni vela file file name nome Reload Ricarica Remove Cancella Update Aggiorna Element information Informazioni elemento CFileIO Open Aprire Save Salvare CFileWriter error errore There was an error writing to the selected file. Errore di scrittura sul file selezionato. Open Aprire There was an error reading from the selected file. Errore di lettura dal file selezionato. Save Salvare CFormBoat boat barca &Add &Aggiungi file file Open Aprire CFormHull hull buccia &Dimensions &Dimensioni CFormHullDefBase Dialog Dialogo Deck and bottom Ponte e fondo Planking Automatic planking lower plank angle top plank angle Number of planks Bottom Fondo Bottom sweep angle % % Max Width Forward shape Length Lunghezza Forward height Max Width position Stem angle Transom angle Aft height Aft width Aft shape Hull name Nome della buccia Deck Ponte Forward height Plank 5 Chine angle Sweep angle Plank angle Plank 4 Plank 3 Plank 2 Plank 1 Plank 6 Check Controllo OK OK Cancel Cancellare Dimensions are in millimeters and angles in degrees measured from horizontal Planks txt_BBW txt_BfwdHeight txt_BLWL txt_BaftW txt_BaftHeight Dead rise angle txt_HullID txt_DaftHeight txt_DfwdHeight Side angle CFormMain to &DXF &DXF to &TXT sail vela &TXT to &XML sail vela &XML &New &Nuovo &Open &Aprire &Save &Salvare Save &As Salvare &sotto &Quit &Uscire &Dimensions &Dimensioni &Mould &Profilo &Patches &Rinforzi &Rig &Attrezzatura &File &File &View &Vista &Help &Aiuto About Sailcut CAD A proposito di Sailcut CAD error errore There was an error writing to the selected file Errore di scrittura sul file selezionato About &Qt A proposito di &Qt About &Sailcut CAD A proposito di &Sailcut CAD Language Lingua Open &recent Apri &recente Export &3D sail Esporta &vela 3D to &Carlson plotter al plotter &Carlson Export &development Esporta &svilupppo Sailcut CAD &Handbook Manuale &Sailcut CAD shaded view vista in chiaroscuro wireframe view vista spigoli development sviluppo created new sail nuova vela creata loaded '%1' caricata '%1' error loading '%1' errore caricamento '%1' wrote '%1' ha scritto '%1' There was a data printing error Errore di stampa dati There was a development printing error Errore di stampa sviluppo There was a drawing printing error Errore di stampa disegno data dati drawing disegno develop sviluppa &Print &Stampa Sail type Tipo vela Main sail Randa Jib Fiocco Sail layout Taglio vela Cross Cut Taglio cross-cut Horizontal Cut Taglio orizzontale Radial Cut Taglio radiale Twist Foot Cut Taglio twist foot Vertical Cut Taglio verticale Mitre Cut Taglio a spina di pesce sections, sezioni, head gores. altezza pannelli. Rig Attrezzatura Boat LOA Lunghezza della barca Fore triangle hoist I Altezza I del triangolo di prua Fore triangle base J Base J del triangolo di prua Tack position X Posizione X del punto di mura Tack height Y Altezza Y del punto di mura Sail dimensions Dimensioni della vela Luff length Lunghezza del ghindante Gaff angle wrt luff Angolo tra picco e ghindante Gaff length Lunghezza del picco Foot length Lunghezza della base Leech length Lunghezza della balumina Shape of edges Forma dei bordi Luff round Allunamento del ghindante Gaff round Allunamento del picco Leech round Allunamento della balumina Foot round Allunamento della base Luff round position Posizione allunamento ghindante Gaff round position Posizione allunamento picco Leech round position Posizione allunamento balumina Foot round position Posizione allunamento base Sail settings Regolazioni vela Twist angle Angolo di svergolamento Sheeting angle Angolo caduta vela Cloth seams and hems Vivagni e vaine tessuto vela Cloth width Larghezza del tessuto vela Seams width Larghezza vivagni Leech hem width Larghezza vaina balumina Other hems width Larghezza altre vaine Sail mould Profilo della vela Luff factor Fattore ghindante Depth Profondita' Leech factor Fattore balumina Top profile Profilo superiore Mid profile at h = Profilo mediano ad "h" Bottom profile Profilo inferiore Mast/Luff rake Inclinazione albero/ghindante E&xport 3D sail Esporta &vela 3D Mainsail Randa deg deg sail vela hull buccia rig attrezzatura boat barca &Window &Finestra &Close &Chiudere Close &All Chiudere &Tutto &Tile &Piastrella &Cascade &Cascata unknown document type '%1' tipo di documento '%1' sconosciuto Open Aprire CFormMould &Cancel &Cancellare Vertical repartition Ripartizione verticale Sail mould Profilo della vela &Help &Aiuto &OK &OK Top profile Profilo superiore Middle profile Profilo mediano Bottom profile Profilo inferiore CFormPanelGroup panels pannelli CFormPrint &Print &Stampa &Cancel &Cancellare Scale Scala CFormRig Rig Attrezzatura &New &Nuovo sail &definition definizione &vela 3D &sail vela &3D &Add sail Aggiungi vela &Open &Aprire Open &recent Apri &recente &Save &Salvare Save &As Salvare &sotto &Close &Chiudere &File &File error errore There was an error writing to the selected file Errore di scrittura sul file selezionato rig attrezzatura &Dimensions &Dimensioni CFormRigDefBase Rig dimensions Dimensioni attrezzatura Cancel Cancellare OK OK Spreaders = SPNB Number of spreaders Spreader height txt_SPH2 txt_SPH1 txt_SPH3 SPH2 SPH3 SPH1 Spreader length SPW3 txt_SPW3 SPW1 txt_SPW1 SPW2 txt_SPW2 Shrouds Cap shroud base width = CSH Lower shroud base width txt_LSB txt_CSH = CSB Cap shroud height txt_CSB = LSB Fore triangle txt_foreI = I txt_foreJ = J Fore triangle base Base del triangolo di prua Fore triangle hoist Altezza del triangolo di prua Mast Albero Mast width = MW txt_MW txt_MC = MC Mast cord lbl_MRkD = MRkD Mast rake angle Angolo albero txt_MH txt_MRnd Mast rake Inclinazione albero = MRkM txt_MRkM Mast height = MH = MRnd Mast round Allunamento del albero = MRndPos Mast round position Posizione allunamento albero Mainsail Randa lbl_MS_LuffRP @ lbl_MS_LuffR lbl_MS_TackY Y = lbl_MS_TackX X = Tack lbl_MS_LuffL = MSL Luff length Lunghezza del ghindante Luff round Allunamento del ghindante lbl_MS_Rake = MSR Luff rake Inclinazione ghindante Tack height Altezza del punto di mura txt_BAD = BAD Head height = HAD txt_HAD Check Controllo All dimensions are in millimeter and angles in degrees Description of rig Descrizione di attrezzatura Rig name Nome attrezzatura CFormSail sail vela &Print &Stampa data dati drawing disegno development sviluppo E&xport 3D sail Esporta &vela 3D to &DXF &DXF to &TXT sail vela &TXT to &XML sail vela &XML Export &development Esporta &svilupppo to &Carlson plotter al plotter &Carlson to &Hand-plotting format &Dimensions &Dimensioni &Mould &Profilo &Patches &Rinforzi error errore There was a data printing error Errore di stampa dati There was a development printing error Errore di stampa sviluppo There was a drawing printing error Errore di stampa disegno to &SVG &SVG to DXF (split) CFormSailDef Sail corners coordinates Vela circonda coordinate tack chiodino clew indizio head testa peak vetta IRC width measurements IRC misure di ampiezza Sail width measurements Vela misure di ampiezza CFormSailDefBase Sail definition Definizione della vela Sail dimensions Dimensioni della vela mm mm Round position Posizione dell'allunamento Luff length Lunghezza del ghindante Foot length Lunghezza della base Leech length Lunghezza della balumina Gaff length Lunghezza del picco Leech round Allunamento della balumina Gaff round Allunamento del picco Luff round Allunamento del ghindante Foot round Allunamento della base % % deg deg Gaff angle from luff Angolo tra picco e ghindante Rig geometry Geometria dell'attrezzatura Fore triangle base J Base J del triangolo di prua Tack height Altezza del punto di mura Distance tack to stem Distanza prua-punto di mura Main sail Randa Jib Fiocco Fore triangle hoist I Altezza I del triangolo di prua Boat length LOA Lunghezza della barca Mast / Luff rake Inclinazione albero/ghindante Cloth Tessuto vela Seam width Larghezza vivagno Cloth width Larghezza del tessuto vela Layout Taglio Mitre cut Taglio a spina di pesce Cross cut Taglio cross-cut Twist foot Twist foot Horizontal cut Taglio orizzontale Number of sections Numero di sezioni Number of radial gores Numero di pannelli radiali Radial cut Taglio radiale Vertical cut Taglio verticale Sail shape Forma della vela Top depth Profondita' in alto Mid depth Profondita' al centro Foot depth Profondita' alla base Twist angle Angolo di svergolamento OK OK Cancel Cancellare Leech hem Vaina balumina Other hems Altre vaine Sheeting angle Angolo caduta vela Sail area Area della vela Diagonal Diagonale Compute Calcola Sail ID Nome della vela Number of luff gores Numero di ghindante pannelli radiali Fore triangle base J Base J del triangolo di prua Dihedral angle Wing Ala Sail identifier m2 m2 Sail name Nome della vela Luff rake Inclinazione ghindante Mitre cut 2 Taglio a spina di pesce 2 Foot hem Vaina alla base CRigSailWidget Sail information Informazioni vela file file name nome Reload Ricarica Remove Cancella Update Aggiorna error errore There was an error reading from the selected file. Errore di lettura dal file selezionato. CSailDataPrinter Sailcut CAD data sheet Scheda dati Sailcut CAD Mainsail Randa Jib Fiocco Wing Ala deg deg Sail type Tipo vela Cross Cut Taglio cross-cut Horizontal Cut Taglio orizzontale Radial Cut Taglio radiale sections sezioni head gores altezza pannelli luff gores ghindante pannelli Twist Foot Cut Taglio twist foot Vertical Cut Taglio verticale Mitre Cut Taglio a spina di pesce Mitre Cut 2 Taglio a spina di pesce 2 Sail layout Taglio vela Rig Attrezzatura Boat LOA Lunghezza della barca Mast/Luff rake Inclinazione albero/ghindante Tack position X Posizione X del punto di mura Tack height Y Altezza Y del punto di mura Fore triangle hoist I Altezza I del triangolo di prua Fore triangle base J Base J del triangolo di prua Sail dimensions Dimensioni della vela Luff length Lunghezza del ghindante Foot length Lunghezza della base Leech length Lunghezza della balumina Gaff length Lunghezza del picco Gaff angle wrt luff Angolo tra picco e ghindante Shape of edges Forma dei bordi Luff round Allunamento del ghindante Luff round position Posizione allunamento ghindante Foot round Allunamento della base Foot round position Posizione allunamento base Leech round Allunamento della balumina Leech round position Posizione allunamento balumina Gaff round Allunamento del picco Gaff round position Posizione allunamento picco Sail settings Regolazioni vela Twist angle Angolo di svergolamento Sheeting angle Angolo caduta vela Cloth seams and hems Vivagni e vaine tessuto vela Cloth width Larghezza del tessuto vela Seams width Larghezza vivagni Leech hem width Larghezza vaina balumina Foot hem width Larghezza vaina base Other hems width Larghezza altre vaine Sail mould Profilo della vela Luff factor Fattore ghindante Depth Profondita' Leech factor Fattore balumina Top profile Profilo superiore Mid profile at h = Profilo mediano ad "h" Bottom profile Profilo inferiore Luff rake Inclinazione ghindante CSailDevelPrinter Scale Scala CSailDispGL This system has no OpenGL support. Il supporto OpenGL non e' disponibile su questo sistema. CSailDrawingPrinter Scale Scala CSailPrinter Sailcut CAD data sheet Scheda dati Sailcut CAD Mainsail Randa Jib Fiocco deg deg Sail type Tipo vela Cross Cut Taglio cross-cut Horizontal Cut Taglio orizzontale Radial Cut Taglio radiale sections sezioni head gores altezza pannelli luff gores ghindante pannelli Twist Foot Cut Taglio twist foot Vertical Cut Taglio verticale Mitre Cut Taglio a spina di pesce Sail layout Taglio vela Rig Attrezzatura Boat LOA Lunghezza della barca Mast/Luff rake Inclinazione albero/ghindante Tack position X Posizione X del punto di mura Tack height Y Altezza Y del punto di mura Fore triangle hoist I Altezza I del triangolo di prua Fore triangle base J Base J del triangolo di prua Sail dimensions Dimensioni della vela Luff length Lunghezza del ghindante Foot length Lunghezza della base Leech length Lunghezza della balumina Gaff length Lunghezza del picco Gaff angle wrt luff Angolo tra picco e ghindante Shape of edges Forma dei bordi Luff round Allunamento del ghindante Luff round position Posizione allunamento ghindante Foot round Allunamento della base Foot round position Posizione allunamento base Leech round Allunamento della balumina Leech round position Posizione allunamento balumina Gaff round Allunamento del picco Gaff round position Posizione allunamento picco Sail settings Regolazioni vela Twist angle Angolo di svergolamento Sheeting angle Angolo caduta vela Cloth seams and hems Vivagni e vaine tessuto vela Cloth width Larghezza del tessuto vela Seams width Larghezza vivagni Leech hem width Larghezza vaina balumina Other hem width Larghezza altre vaine Sail mould Profilo della vela Luff factor Fattore ghindante Depth Profondita' Leech factor Fattore balumina Top profile Profilo superiore Mid profile at h = Profilo mediano ad "h" Bottom profile Profilo inferiore CSailViewerPanel Display parameters Parametri schermata elevation elevazione azimuth azimuth Controls Controlli Reset view Resettare la vista Labeling Etichette Zoom in Zoom avanti Zoom out Zoom indietro deg deg CSailViewerTabs shaded view vista in chiaroscuro wireframe view vista spigoli CWidgetProfile % % Luff shape Forma ghindante Depth Profondita' Leech shape Forma balumina degrees gradi cord corda Dialog Dialog Dialogo XmlReaderTempl error errore There was an error reading from the selected file. Errore di lettura dal file selezionato. sailcut-1.5.0/src/ts/sailcut_nl.ts000066400000000000000000002462611477005247400171300ustar00rootroot00000000000000 CBoatElementWidget Sail information Zeil informatie file bestand name naam Reload Opnieuw laden Remove Verwijderen Update Verversen Element information Deel informatie CFileIO Open Openen Save Opslaan CFileWriter error fout There was an error writing to the selected file. Er is een fout opgetreden bij het opslaan van het bestand. Open Openen There was an error reading from the selected file. Er is een fout opgetreden bij het lezen van het bestand. Save Opslaan CFormBoat boat boot &Add &Toevoegen file bestand Open Openen CFormHull hull romp &Dimensions &Afmetingen CFormHullDefBase Dialog Dialoog Deck and bottom Dek en bodem Planking Panelen Automatic planking Automatische panelen lower plank angle Onderste paneel hoek top plank angle Bovenste paneel hoek Number of planks Aantal panelen Bottom Bodem Bottom sweep angle Bodem hoek % % Max Width Max Breedte Forward shape Boeg vorm Length Lengte Forward height Boeg hoogte Max Width position Max Breedte positie Stem angle Boeg hoek Transom angle Spiegel hoek Aft height Achtersteven hoogte Aft width Achtersteven breedte Aft shape Achtersteven vorm Hull name Romp naam Deck Dek Forward height Boeg hoogte Plank 5 Paneel 5 Chine angle Kim hoek Sweep angle Zeeg hoek Plank angle Paneel hoek Plank 4 Paneel 4 Plank 3 Paneel 3 Plank 2 Paneel 2 Plank 1 Paneel 1 Plank 6 Paneel 6 Check Controleren OK OK Cancel Opheffen Dimensions are in millimeters and angles in degrees measured from horizontal Afmetingen in millimeters en hoeken in graden t.o.v. horizontaal Planks Panelen txt_BBW txt_BfwdHeight txt_BLWL txt_BaftW txt_BaftHeight Dead rise angle Bodem hoek txt_HullID txt_DaftHeight txt_DfwdHeight Side angle Dolboord hoek CFormMain &New &Nieuw &Open &Openen &Save Op&slaan Save &As Opslaan &Als to &DXF naar &DXF to &TXT sail naar &TXT zeil to &XML sail naar &XML zeil &Quit &Afsluiten &Dimensions &Afmetingen &Mould &Vorm &Patches &Hoekverstevigingen &Rig &Tuigage Language Taal About &Qt Over &Qt About &Sailcut CAD Over &Sailcut CAD &File &Bestand &View Beel&d &Help &Help About Sailcut CAD Over Sailcut CAD error fout There was an error writing to the selected file Er is een fout opgetreden bij het opslaan van het bestand Open &recent Onlangs &geopend E&xport 3D sail 3D zeil e&xporteren to &Carlson plotter naar &Carlson plotter Export &development Zeil&banen exporteren Sailcut CAD &Handbook Sailcut CAD &Handboek shaded view 3D model wireframe view draadmodel development banen created new sail nieuw zeil gecreëerd loaded '%1' '%1' geladen error loading '%1' fout bij het laden van '%1' wrote '%1' '%1' opgeslagen There was a data printing error Er is een fout opgetreden bij het printen van de data There was a development printing error Er is een fout opgetreden bij het printen van banen There was a drawing printing error Er is een fout opgetreden bij het printen van het tekening data data drawing tekening develop banen &Print &Print Sail type Zeil type Mainsail Grootzeil Jib Fok Sail layout Zeilontwerp Cross Cut Schuin gesneden Horizontal Cut Horizontaal gesneden Radial Cut Radiaal gesneden Twist Foot Cut Gedraaid Onderlijk Vertical Cut Verticaal gesneden Mitre Cut Verstek gesneden sections, secties, head gores. top banen. Rig Tuigage Boat LOA Scheepslengte LOA Fore triangle hoist I Voordriehoek hoogte I Fore triangle base J Voordriehoek basis J Tack position X Halshoek positie X Tack height Y Halshoek hoogte Y Sail dimensions Zeil afmetingen Luff length Voorlijk lengte Mast rake Mast helling Gaff angle wrt luff Gaffel-mast hoek Gaff length Gaffel lengte Foot length Onderlijk lengte Leech length Achterlijk lengte Shape of edges Vorm van de randen Luff round Voorlijk ronding Gaff round Gaffel ronding Leech round Achterlijk ronding Foot round Onderlijk ronding Luff round position Voorlijk ronding positie Gaff round position Gaffel ronding positie Leech round position Achterlijk ronding positie Foot round position Onderlijk ronding positie Sail settings Zeil instellingen Twist angle Twist hoek Sheeting angle Schootlijn hoek Cloth seams and hems Doek naden en zomen Cloth width Baan breedte Seams width Naad breedte Leech hem width Achterlijk zoom breedte Other hem width Overige zoom breedte Sail mould Zeilvorm Luff factor Voorlijk factor Depth Diepte Leech factor Achterlijk factor Top profile Top profiel Mid profile at h = Midden profiel bij h = Bottom profile Onderlijk profiel Mast/Luff rake Mast/Voorlijk helling head gores, hoofd banen, luff gore. voorlijk baan. Wing Vleugel luff gores. voorlijk banen. deg gr to &Hand-plotting format naar &Handmatige plotgegevens sail Zeil hull romp rig tuigage boat boot &Window &Venster &Close &Sluiten Close &All &All vensters sluiten &Tile Rangschikken &Cascade Getrapt unknown document type '%1' Onbekend bestandstype '%1' Open Openen CFormMould Top profile Top profiel Middle profile Midden profiel Bottom profile Onderlijk profiel Sail mould Zeilvorm &Help &Help &OK &OK &Cancel Op&heffen Vertical repartition Verticale verdeling CFormPanelGroup panels Panelen CFormPrint &Print &Print &Cancel Op&heffen Scale Schaal CFormRig Rig Tuigage &New &Nieuw sail &definition zeil &definitie 3D &sail 3D &zeil &Add sail Zeil &toevoegen &Open &Openen Open &recent Onlangs &geopend &Save Op&slaan Save &As Opslaan &Als &Close &Sluiten &File &Bestand error fout There was an error writing to the selected file Er is een fout opgetreden bij het opslaan van het bestand rig tuigage &Dimensions &Afmetingen CFormRigDefBase Rig dimensions Tuigage afmetingen Cancel Opheffen OK OK Spreaders Zalingen = SPNB = SPNB Number of spreaders Aantal zalingen Spreader height Zaling hoogte txt_SPH2 txt_SPH1 txt_SPH3 SPH2 SPH3 SPH1 Spreader length Zaling lengte SPW3 txt_SPW3 SPW1 txt_SPW1 SPW2 txt_SPW2 Shrouds Stagen Cap shroud base width Topstagen basis breedte = CSH = CSH Lower shroud base width Onderstagen basis breedte txt_LSB txt_CSH = CSB = CSB Cap shroud height Topstagen hoogte txt_CSB = LSB = LSB Fore triangle Voordriehoek txt_foreI = I = I txt_foreJ = J = J Fore triangle base Voordriehoek basis Fore triangle hoist Voordriehoek hoogte Mast Mast Mast width Mastdikte = MW = MW txt_MW txt_MC = MC = MC Mast cord Mastbuiging lbl_MRkD = MRkD = MRkD Mast rake angle Mast helling hoek txt_MH txt_MRnd Mast rake Mast helling = MRkM = MRkM txt_MRkM Mast height Mast hoogte = MH = MH = MRnd = MRnd Mast round Mast buiging = MRndPos = MRndPos Mast round position Mast buiging positie Mainsail Grootzeil lbl_MS_LuffRP @ @ lbl_MS_LuffR lbl_MS_TackY Y = Y = lbl_MS_TackX X = X = Tack Halshoek lbl_MS_LuffL = MSL = MSL Luff length Voorlijk lengte Luff round Voorlijk ronding lbl_MS_Rake = MSR = MSR Luff rake Voorlijk helling Tack height Halshoek hoogte txt_BAD = BAD = BAD Head height Top hoogte = HAD = HAD txt_HAD Check Controleren All dimensions are in millimeter and angles in degrees All afmetingen in millimeters en hoeken in graden Rig ID Tuigage ID Description of rig Tuigage beschrijving Rig name Tuigage naam CFormSail sail Zeil &Print &Print data data drawing tekening development banen E&xport 3D sail 3D zeil e&xporteren to &DXF naar &DXF to &TXT sail naar &TXT zeil to &XML sail naar &XML zeil Export &development Zeil&banen exporteren to &Carlson plotter naar &Carlson plotter to &Hand-plotting format naar &Handmatige plotgegevens &Dimensions &Afmetingen &Mould &Vorm &Patches &Hoekverstevigingen error fout There was a data printing error Er is een fout opgetreden bij het printen There was a development printing error Er is een fout opgetreden bij het printen There was a drawing printing error Er is een fout opgetreden bij het printen to &SVG naar &SVG to DXF (split) naar DXF (split) CFormSailDef Sail corners coordinates Zeilhoek coördinaten tack halshoek clew halshoek head tophoek peak tophoek IRC width measurements IRC breedtematen Sail width measurements Zeilbreedte afmetingen CFormSailDefBase Sail definition Zeil definitie Sail dimensions Zeil afmetingen mm mm Round position Ronding positie Luff length Voorlijk lengte Foot length Onderlijk lengte Leech length Achterlijk lengte Gaff length Gaffel lengte Leech round Achterlijk ronding Gaff round Gaffel ronding Luff round Voorlijk ronding Foot round Onderlijk ronding % % deg gr Gaff angle from luff Gaffel-mast hoek Rig geometry Tuigage geometrie Fore triangle base J Voordriehoek basis J Tack height Halshoek hoogte Distance tack to stem Afstand halshoek-boeg Main sail Grootzeil Jib Fok Fore triangle hoist I Voordriehoek hoogte I Boat length LOA Scheepslengte LOA Mast / Luff rake Mast/Voorlijk helling Cloth Zeildoek Seam width Naad breedte Cloth width Baan breedte Layout Ontwerp Mitre cut Verstek gesneden Cross cut Schuin gesneden Twist foot Gedraaid Onderlijk Horizontal cut Horizontaal gesneden Number of sections Aantal secties Number of radial gores Aantal radiale banen Radial cut Radiaal gesneden Vertical cut Vertikaal gesneden Sail shape Zeilvorm Top depth Top bolling Mid depth Midden bolling Foot depth Onderlijk bolling Twist angle Twist hoek OK OK Cancel Opheffen Leech hem Achterlijk zoom Other hems Overige zomen Sheeting angle Schoothoek Sail area Zeil oppervlak Diagonal Diagonaal Compute Bereken Sail ID Zeil ID Number of luff gores Aantal voorlijk banen Dihedral angle Tweevlakshoek Wing Vleugel Sail identifier Zeil ID m2 m2 Sail name Zeil naam Luff rake Voorlijk helling Mitre cut 2 Verstek 2 gesneden Foot hem Onderlijk zoom CRigSailWidget Sail information Zeil informatie file bestand name naam Reload Opnieuw laden Remove Verwijderen Update Verversen error fout There was an error reading from the selected file. Er is een fout opgetreden bij het lezen van het bestand. CSailDataPrinter Sailcut CAD data sheet Sailcut CAD data sheet Mainsail Grootzeil Jib Fok Wing Vleugel deg gr Sail type Zeil type Cross Cut Schuin gesneden Horizontal Cut Horizontaal gesneden Radial Cut Radiaal gesneden sections secties head gores top banen luff gores voorlijk banen Twist Foot Cut Gedraaid Onderlijk Vertical Cut Verticaal gesneden Mitre Cut Verstek gesneden Mitre Cut 2 Verstek 2 gesneden Sail layout Zeilontwerp Rig Tuigage Boat LOA Scheepslengte LOA Mast/Luff rake Mast/Voorlijk helling Tack position X Halshoek positie X Tack height Y Halshoek hoogte Y Fore triangle hoist I Voordriehoek hoogte I Fore triangle base J Voordriehoek basis J Sail dimensions Zeil afmetingen Luff length Voorlijk lengte Foot length Onderlijk lengte Leech length Achterlijk lengte Gaff length Gaffel lengte Gaff angle wrt luff Gaffel-mast hoek Shape of edges Vorm van de randen Luff round Voorlijk ronding Luff round position Voorlijk ronding positie Foot round Onderlijk ronding Foot round position Onderlijk ronding positie Leech round Achterlijk ronding Leech round position Achterlijk ronding positie Gaff round Gaffel ronding Gaff round position Gaffel ronding positie Sail settings Zeil instellingen Twist angle Twist hoek Sheeting angle Cloth seams and hems Doek naden en zomen Cloth width Baan breedte Seams width Naad breedte Leech hem width Achterlijk zoom breedte Foot hem width Onderlijk zoom breedte Other hems width Overige zoom breedte Sail mould Zeilvorm Luff factor Voorlijk factor Depth Diepte Leech factor Achterlijk factor Top profile Top profiel Mid profile at h = Midden profiel bij h = Bottom profile Onderlijk profiel Luff rake Voorlijk helling CSailDevelPrinter Scale Schaal CSailDispGL This system has no OpenGL support. Dit systeem ondersteunt geen OpenGL. CSailDrawingPrinter Scale Schaal CSailPrinter Sailcut CAD data sheet Sailcut CAD data sheet Mainsail Grootzeil Jib Fok Wing Vleugel deg gr Sail type Zeil type Cross Cut Schuin gesneden Horizontal Cut Horizontaal gesneden Radial Cut Radiaal gesneden sections secties head gores top banen luff gores voorlijk banen Twist Foot Cut Gedraaid onderlijk Vertical Cut Verticaal gesneden Mitre Cut Verstek gesneden Sail layout Zeilontwerp Rig Tuigage Boat LOA Scheepslengte LOA Mast/Luff rake Mast/Voorlijk helling Tack position X Halshoek positie X Tack height Y Halshoek hoogte Y Fore triangle hoist I Voordriehoek hoogte I Fore triangle base J Voordriehoek basis J Sail dimensions Zeil afmetingen Luff length Voorlijk lengte Foot length Onderlijk lengte Leech length Achterlijk lengte Gaff length Gaffel lengte Gaff angle wrt luff Gaffel-mast hoek Shape of edges Vorm van de randen Luff round Voorlijk ronding Luff round position Voorlijk ronding positie Foot round Onderlijk ronding Foot round position Onderlijk ronding positie Leech round Achterlijk ronding Leech round position Achterlijk ronding positie Gaff round Gaffel ronding Gaff round position Gaffel ronding positie Sail settings Zeil instellingen Twist angle Twist hoek Sheeting angle Schoothoek Cloth seams and hems Doek naden en zomen Cloth width Baan breedte Seams width Naad breedte Leech hem width Achterlijk zoom breedte Other hem width Overige zoom breedte Sail mould Zeilvorm Luff factor Voorlijk factor Depth Diepte Leech factor Achterlijk factor Top profile Top profiel Mid profile at h = Midden profiel bij h = Bottom profile Onderlijk profiel CSailViewerPanel Display parameters Beeld parameters elevation hoogtehoek azimuth azimut Controls Controleer Reset view Beeld aanpassen Labeling Labels Zoom in Inzoomen Zoom out Uitzoomen deg gr CSailViewerTabs shaded view 3D model wireframe view draadmodel CWidgetProfile Luff shape Voorlijk vorm Depth Diepte % % Leech shape Achterlijk vorm degrees grad cord Koorde Dialog Dialog Dialoog XmlReaderTempl error fout There was an error reading from the selected file. Er is een fout opgetreden bij het lezen van het bestand. sailcut-1.5.0/src/ts/sailcut_no.ts000066400000000000000000002637411477005247400171350ustar00rootroot00000000000000 CBoatElementWidget Sail information Seilinformasjon file fil name navn Reload Forny Remove Fjern Update Oppdater Element information CFileIO Open åpne Save Lagre CFileWriter error feil There was an error writing to the selected file. Feil ved utskrivning av valgte fil. Open åpne There was an error reading from the selected file. Feil ved lesning av valgte fil. Save Lagre CFormBoat boat båten &Add &Legg file fil Open åpne CFormHull hull &Dimensions &Dimensjoner CFormHullDefBase Dialog Deck and bottom Planking Automatic planking lower plank angle top plank angle Number of planks Bottom Bottom sweep angle % % Max Width Forward shape Length Forward height Max Width position Stem angle Transom angle Aft height Aft width Aft shape Hull name Deck Forward height Plank 5 Chine angle Sweep angle Plank angle Plank 4 Plank 3 Plank 2 Plank 1 Plank 6 Check OK OK Cancel Annuler Dimensions are in millimeters and angles in degrees measured from horizontal Planks txt_BBW txt_BfwdHeight txt_BLWL txt_BaftW txt_BaftHeight Dead rise angle txt_HullID txt_DaftHeight txt_DfwdHeight Side angle CFormMain to &DXF &DXF to &TXT sail seil &TXT to &XML sail seil &XML &New &Ny &Open &åpne &Save &Lagre Save &As Lagre &som &Quit &Avslutt &Dimensions &Dimensjoner &Mould &Mal &Patches &Lapper &Rig &Rigg &File &Fil &View &Bilde &Help &Hjelp About Sailcut CAD Informasjon om Sailcut CAD error feil There was an error writing to the selected file Feil ved utskrivning av valgte fil. About &Qt Informasjon om &Qt About &Sailcut CAD Informasjon om &Sailcut CAD Language Språk Open &recent Åpne &siste E&xport 3D sail &Eksporter 3D seil to &Carlson plotter til &Carlson plotter Export &development Eksporter &utvikling Sailcut CAD &Handbook Sailcut &Håndbok CAD shaded view visning i 3D wireframe view visning av omriss development utskytningsoversikt created new sail laget nytt seil loaded '%1' lastet inn '%1' error loading '%1' feil ved lasting av '%1' wrote '%1' skrev '%1' There was a data printing error Feil ved utskrift av data There was a development printing error Feil ved utskrift av paneler There was a drawing printing error Feil ved utskrift av tegning data data drawing tegning develop lag paneler &Print &Skriv ut Sail type Seiltype Mainsail Storseil Jib Fokke Sail layout Seil layout Cross Cut Kryss kutt Horizontal Cut Horisontalt kutt Radial Cut Radial kutt Twist Foot Cut Vridd underlik kutt Vertical Cut Vertikalt kutt Mitre Cut Mitre kutt sections, baner head gores. Antall paneler i topp. Rig Rigg Boat LOA Båtens LOA Fore triangle hoist I Høyde I av framre trekant Fore triangle base J Foten J av framre trekant Tack position X Nedhalets posisjon X Tack height Y Nedhalets høyde Y Sail dimensions Seil dimensjoner Luff length Forlikets lengde Gaff angle wrt luff Gaffelens vinkel på forliket Gaff length Gaffel lengde Foot length Lengde underkant Leech length Akterlikets lengde Shape of edges Form på seilets lik Luff round Forlikets avrunding Gaff round Gaffel avrunding Leech round Akterlikets avrunding Foot round Underlikets avrunding Luff round position Plassering av forlikets avrunding Gaff round position Plassering av gaffelens avrunding Leech round position Plassering av akterlikets avrunding Foot round position Plassering av underlikets avrunding Sail settings Innstillinger for seil Twist angle Tvist vinkel Sheeting angle Skjøtevinkel Cloth seams and hems Stoff søm og bretter Cloth width Stoff bredde Seams width Søm bredde Leech hem width Bredde på akterlikets søm Other hem width Bredde på andre sømmer Sail mould Seil mal Luff factor Forlikets faktor Depth Dybde Leech factor Akterlikets faktor Top profile Topp profil Mid profile at h = Midtre profil h = Bottom profile Nedre profil Mast/Luff rake Mastelogg head gores, Antall paneler i topp, Wing Vinge luff gores. baner i forlik. deg grad sail seil hull rig rigg boat båten &Window &Close &Lukk Close &All &Tile &Cascade unknown document type '%1' Open åpne CFormMould &Cancel &Annuler Vertical repartition Vertikal oppdeling Sail mould Seil mal &Help Hjelp &OK &OK Top profile Topp profil Middle profile Mitre profil Bottom profile Nedre profil CFormPanelGroup panels CFormPrint &Print &Skriv ut &Cancel &Annuler Scale CFormRig Rig Rigg &New &Ny sail &definition seil &definisjoner 3D &sail 3D &seil &Add sail &Legg til seil &Open &åpne Open &recent Åpne &siste &Save &Lagre Save &As Lagre &som &Close &Lukk &File &Fil error feil There was an error writing to the selected file Feil ved utskrivning av valgte fil rig rigg &Dimensions &Dimensjoner CFormRigDefBase Rig dimensions Rigg dimensjoner Cancel Annuler OK OK Spreaders = SPNB Number of spreaders Spreader height txt_SPH2 txt_SPH1 txt_SPH3 SPH2 SPH3 SPH1 Spreader length SPW3 txt_SPW3 SPW1 txt_SPW1 SPW2 txt_SPW2 Shrouds Cap shroud base width = CSH Lower shroud base width txt_LSB txt_CSH = CSB Cap shroud height txt_CSB = LSB Fore triangle txt_foreI = I txt_foreJ = J Fore triangle base Fore triangle hoist Mast Mast width = MW txt_MW txt_MC = MC Mast cord lbl_MRkD = MRkD Mast rake angle txt_MH txt_MRnd Mast rake = MRkM txt_MRkM Mast height = MH = MRnd Mast round = MRndPos Mast round position Mainsail Storseil lbl_MS_LuffRP @ lbl_MS_LuffR lbl_MS_TackY Y = lbl_MS_TackX X = Tack lbl_MS_LuffL = MSL Luff length Forlikets lengde Luff round Forlikets avrunding lbl_MS_Rake = MSR Luff rake Tack height txt_BAD = BAD Head height = HAD txt_HAD Check All dimensions are in millimeter and angles in degrees Description of rig Rig name CFormSail sail seil &Print &Skriv ut data data drawing tegning development utskytningsoversikt E&xport 3D sail &Eksporter 3D seil to &DXF &DXF to &TXT sail seil &TXT to &XML sail seil &XML Export &development Eksporter &utvikling to &Carlson plotter til &Carlson plotter to &Hand-plotting format &Dimensions &Dimensjoner &Mould &Mal &Patches &Lapper error feil There was a data printing error Feil ved utskrift av data There was a development printing error Feil ved utskrift av paneler There was a drawing printing error Feil ved utskrift av tegning to &SVG &SVG to DXF (split) CFormSailDef Sail corners coordinates tack høyde clew head topp peak Sail width measurements CFormSailDefBase Sail definition Definisjon av seilet Sail dimensions Seil dimensjoner mm mm Round position Posisjonen til avrundingen Luff length Forlikets lengde Foot length Lengde underkant Leech length Akterlikets lengde Gaff length Gaffel lengde Leech round Akterlikets avrunding Gaff round Gaffel avrunding Luff round Forlikets avrunding Foot round Underlikets avrunding % % deg grad Gaff angle from luff Gaffel vinkel/forlik Rig geometry Riggens Mål Fore triangle base J Foten J av framre trekant Tack height Høyde på skjøtefeste Distance tack to stem Avstand fra nedhal til skjøtefeste Main sail Storseil Jib Fokke Fore triangle hoist I Høyde I av framre trekant Boat length LOA Lengde på båten Mast / Luff rake Mastelogg Cloth Stoff Seam width Søm bredde Cloth width Stoff bredde Layout Layout Mitre cut Mitre kutt Cross cut Kryss kutt Twist foot Vridd underlik Horizontal cut Horisontalt kutt Number of sections Antall baner Number of radial gores Antall radial paneler Radial cut Radial kutt Vertical cut Vertikal kutt Sail shape Seilets form Top depth Dybde i toppen Mid depth Dybde på midten Foot depth Dybde ved underliket Twist angle Tvist vinkel OK OK Cancel Annuler Leech hem Bretten på akterliket Other hems Andre brett kanter Sheeting angle Skjøtevinkel Sail area Seilets areal Diagonal Diagonal Compute Beregn Sail ID Seil ID Number of luff gores Antall baner i forlik Dihedral angle Vinkel Wing Vinge Sail identifier Seil ID m2 m2 Sail name Luff rake Mitre cut 2 Mitre kutt 2 Foot hem CRigSailWidget Sail information Seilinformasjon file fil name navn Reload Forny Remove Fjern Update Oppdater error feil There was an error reading from the selected file. Feil ved lesning av valgte fil. CSailDataPrinter Sailcut CAD data sheet Sailcut CAD kuttliste Mainsail Storseil Jib Fokke Wing Vinge deg grad Sail type Seiltype Cross Cut Kryss kutt Horizontal Cut Horisontalt kutt Radial Cut Radial kutt sections baner head gores topp baner luff gores forlik baner Twist Foot Cut Vridd underlik kutt Vertical Cut Vertikalt kutt Mitre Cut Mitre kutt Mitre Cut 2 Mitre kutt 2 Sail layout Seil layout Rig Rigg Boat LOA Båtens LOA Mast/Luff rake Mastelogg Tack position X Nedhalets posisjon X Tack height Y Nedhalets høyde Y Fore triangle hoist I Høyde I av framre trekant Fore triangle base J Foten J av framre trekant Sail dimensions Seil dimensjoner Luff length Forlikets lengde Foot length Lengde underkant Leech length Akterlikets lengde Gaff length Gaffel lengde Gaff angle wrt luff Gaffelens vinkel på forliket Shape of edges Form på seilets lik Luff round Forlikets avrunding Luff round position Plassering av forlikets avrunding Foot round Underlikets avrunding Foot round position Plassering av underlikets avrunding Leech round Akterlikets avrunding Leech round position Plassering av akterlikets avrunding Gaff round Gaffel avrunding Gaff round position Plassering av gaffelens avrunding Sail settings Innstillinger for seil Twist angle Tvist vinkel Sheeting angle Skjøtevinkel Cloth seams and hems Stoff søm og bretter Cloth width Stoff bredde Seams width Søm bredde Leech hem width Bredde på akterlikets søm Foot hem width Other hems width Sail mould Seil mal Luff factor Forlikets faktor Depth Dybde Leech factor Akterlikets faktor Top profile Topp profil Mid profile at h = Midtre profil h = Bottom profile Nedre profil Luff rake CSailDevelPrinter Scale CSailDispGL This system has no OpenGL support. OpenGL er ikke tilgjengelig. CSailDrawingPrinter Scale CSailPrinter Sailcut CAD data sheet Sailcut CAD kuttliste Mainsail Storseil Jib Fokke Wing Vinge deg grad Sail type Seiltype Cross Cut Kryss kutt Horizontal Cut Horisontalt kutt Radial Cut Radial kutt sections baner head gores topp baner luff gores forlik baner Twist Foot Cut Vridd underlik kutt Vertical Cut Vertikalt kutt Mitre Cut Mitre kutt Sail layout Seil layout Rig Rigg Boat LOA Båtens LOA Mast/Luff rake Mastelogg Tack position X Nedhalets posisjon X Tack height Y Nedhalets høyde Y Fore triangle hoist I Høyde I av framre trekant Fore triangle base J Foten J av framre trekant Sail dimensions Seil dimensjoner Luff length Forlikets lengde Foot length Lengde underkant Leech length Akterlikets lengde Gaff length Gaffel lengde Gaff angle wrt luff Gaffelens vinkel på forliket Shape of edges Form på seilets lik Luff round Forlikets avrunding Luff round position Plassering av forlikets avrunding Foot round Underlikets avrunding Foot round position Plassering av underlikets avrunding Leech round Akterlikets avrunding Leech round position Plassering av akterlikets avrunding Gaff round Gaffel avrunding Gaff round position Plassering av gaffelens avrunding Sail settings Innstillinger for seil Twist angle Tvist vinkel Sheeting angle Skjøtevinkel Cloth seams and hems Stoff søm og bretter Cloth width Stoff bredde Seams width Søm bredde Leech hem width Bredde på akterlikets søm Other hem width Bredde på andre sømmer Sail mould Seil mal Luff factor Forlikets faktor Depth Dybde Leech factor Akterlikets faktor Top profile Topp profil Mid profile at h = Midtre profil h = Bottom profile Nedre profil CSailViewerPanel Display parameters Vis parametrene elevation elevasjon azimuth azimuth Controls Kontroller Reset view Forny bildet Labeling Etiketter Zoom in Zoom in Zoom out Zoom ut deg grader CSailViewerTabs shaded view visning i 3D wireframe view visning av omriss CWidgetProfile % % Luff shape Forlikets form Depth Dybde Leech shape Akterlikets form degrees cord Dialog XmlReaderTempl error feil There was an error reading from the selected file. Feil ved lesning av valgte fil. sailcut-1.5.0/src/ts/sailcut_pt.ts000066400000000000000000002672111477005247400171400ustar00rootroot00000000000000 CBoatElementWidget Sail information Informação da vela file ficheiro name nome Reload Recarregar Remove Remover Update Actualizar Element information CFileIO Open Abrir Save Salvar CFileWriter error erro There was an error writing to the selected file. Houve um erro ao escrever para o ficheiro seleccionado. Open Abrir There was an error reading from the selected file. Houve um erro ao ler do ficheiro seleccionado. Save Salvar CFormBoat boat barco &Add &Adicionar file ficheiro Open Abrir CFormHull hull &Dimensions &Dimensões CFormHullDefBase Dialog Deck and bottom Planking Automatic planking lower plank angle top plank angle Number of planks Bottom Bottom sweep angle % % Max Width Forward shape Length Forward height Max Width position Stem angle Transom angle Aft height Aft width Aft shape Hull name Deck Forward height Plank 5 Chine angle Sweep angle Plank angle Plank 4 Plank 3 Plank 2 Plank 1 Plank 6 Check OK OK Cancel Cancelar Dimensions are in millimeters and angles in degrees measured from horizontal Planks txt_BBW txt_BfwdHeight txt_BLWL txt_BaftW txt_BaftHeight Dead rise angle txt_HullID txt_DaftHeight txt_DfwdHeight Side angle CFormMain &New &Novo &Open &Abrir Open &recent Abrir &recente data dados drawing desenho develop desenvolvimento &Print &Imprimir &Save &Salvar Save &As Salvar &como to &DXF para &DXF to &TXT sail para vela &TXT to &XML sail para vela &XML E&xport 3D sail E&xportar vela 3D to &Carlson plotter para &Carlson plotter Export &development Exportar &desenvolvimento &Quit Sa&ir &Dimensions &Dimensões &Mould &Molde &Patches &Reforços &Rig &Aparelho Language Linguagem Sailcut CAD &Handbook &Manual do Sailcut CAD About &Qt Acerca de &Qt About &Sailcut CAD Acerca de &Sailcut CAD &File &Ficheiro &View &Ver &Help &Ajuda shaded view Vista sombreada wireframe view vista em grelha development desenvolvimento loaded '%1' carregado '%1' created new sail criada nova vela About Sailcut CAD Acerca do Sailcut CAD error loading '%1' erro ao carregar '%1' Sail type Tipo de vela Mainsail Vela Grande Jib Vela de Estai Sail layout Formato da vela Cross Cut Corte Transversal Horizontal Cut Corte Horizontal Radial Cut Corte Radial Twist Foot Cut Corte "Twist foot" Vertical Cut Corte Vertical Mitre Cut Corte de Meia Esquadria sections, secções, head gores. paineis do topo. Rig Aparelho Boat LOA Comprimento do barco fora-a-fora - LOA Fore triangle hoist I Altura do triângulo de vante - I Fore triangle base J Base do triângulo de vante - J Tack position X Posição do punho da amura X Tack height Y Altura do punho da amura Y Sail dimensions Dimensões da vela Luff length Comprimento da testa Mast rake Caimento do mastro Gaff angle wrt luff Âgulo da gurutil wrt testa Gaff length Comprimento do gurutil Foot length Comprimento da esteira Leech length Comprimento da valuma Shape of edges Forma das extremidades Luff round Curva da testa Gaff round Curva da gurutil Leech round Curva da valuma Foot round Curva da esteira Luff round position Posição da curva da testa Gaff round position Posição da curva do gurutil Leech round position Posição da curva da valuma Foot round position Posição da curva da esteira Sail settings Afinações da vela Twist angle Âgulo de torção Sheeting angle Âgulo de escota Cloth seams and hems Costuras e baínhas do tecido Cloth width Largura do tecido Seams width Largura das costuras Leech hem width Largura da baínha da valuma Other hem width Largura de outras baínhas Sail mould Molde da vela Luff factor Factor da testa Depth Profundidade Leech factor Factor da valuma Top profile Perfil do topo Mid profile at h = Perfil do meio em h = Bottom profile Perfil da base error erro There was a data printing error Houve um erro na impressão de dados There was a development printing error Houve um erro na impressão do desenvolvimento There was a drawing printing error Houve um erro na impressão do desenho wrote '%1' Escreveu '%1' There was an error writing to the selected file Houve um erro ao escrever para o ficheiro seleccionado head gores, Radiais da pena, Mast/Luff rake Caimento mastro/testa Wing Asa luff gores. Radiais da testa. deg graus to &Hand-plotting format para formato de Traçar à &mão sail vela hull rig aparelho boat barco &Window &Close &Fechar Close &All &Tile &Cascade unknown document type '%1' Open Abrir CFormMould Top profile Perfil do topo Middle profile Perfil do meio Bottom profile Perfil da base Sail mould Molde da vela &Help &Ajuda &OK &OK &Cancel &Cancelar Vertical repartition Repartição vertical CFormPanelGroup panels CFormPrint &Print &Imprimir &Cancel &Cancelar Scale CFormRig Rig Aparelho &New &Novo sail &definition &Definição da vela 3D &sail &vela 3D &Add sail &Adicionar vela &Open A&brir Open &recent Abrir &recente &Save &Salvar Save &As Salvar &Como &Close &Fechar &File &Ficheiro error erro There was an error writing to the selected file Houve um erro ao escrever para o ficheiro seleccionado rig aparelho &Dimensions &Dimensões CFormRigDefBase Rig dimensions Dimensões do aparelho Cancel Cancelar OK OK Spreaders = SPNB Number of spreaders Spreader height txt_SPH2 txt_SPH1 txt_SPH3 SPH2 SPH3 SPH1 Spreader length SPW3 txt_SPW3 SPW1 txt_SPW1 SPW2 txt_SPW2 Shrouds Cap shroud base width = CSH Lower shroud base width txt_LSB txt_CSH = CSB Cap shroud height txt_CSB = LSB Fore triangle txt_foreI = I txt_foreJ = J Fore triangle base Base do triângulo de vante Fore triangle hoist Altura do triângulo de vante Mast Mastro Mast width = MW txt_MW txt_MC = MC Mast cord lbl_MRkD = MRkD Mast rake angle txt_MH txt_MRnd Mast rake Caimento do mastro = MRkM txt_MRkM Mast height = MH = MRnd Mast round = MRndPos Mast round position Mainsail Vela Grande lbl_MS_LuffRP @ lbl_MS_LuffR lbl_MS_TackY Y = lbl_MS_TackX X = Tack lbl_MS_LuffL = MSL Luff length Comprimento da testa Luff round Curva da testa lbl_MS_Rake = MSR Luff rake Caimento testa Tack height txt_BAD = BAD Head height = HAD txt_HAD Check All dimensions are in millimeter and angles in degrees Description of rig Rig name CFormSail sail vela &Print &Imprimir data dados drawing desenho development desenvolvimento E&xport 3D sail E&xportar vela 3D to &DXF para &DXF to &TXT sail para vela &TXT to &XML sail para vela &XML Export &development Exportar &desenvolvimento to &Carlson plotter para &Carlson plotter to &Hand-plotting format para formato de Traçar à &mão &Dimensions &Dimensões &Mould &Molde &Patches &Reforços error erro There was a data printing error Houve um erro na impressão de dados There was a development printing error Houve um erro na impressão do desenvolvimento There was a drawing printing error Houve um erro na impressão do desenho to &SVG para &SVG to DXF (split) CFormSailDef Sail corners coordinates Coordenadas dos punhos da vela tack amura clew escota head gurutil peak pena IRC width measurements Larguras IRC Sail width measurements Larguras da vela CFormSailDefBase Sail definition Definição da vela Sail shape Forma da vela % % Top depth Profundidade do topo Mid depth Profundidade do meio Foot depth Profundidade da esteira Twist angle Ângulo de torção Sheeting angle Ângulo de escota deg graus Sail dimensions Dimensões da vela mm mm Round position Posição da curva Luff length Comprimento da testa Foot length Comprimento da esteira Leech length Comprimento da valuma Gaff length Comprimento do gurutil Leech round Curva da valuma Luff round Curva da testa Foot round Curva da esteira Gaff round Curva do gurutil Gaff angle from luff Âgulo da testa com o gurutil Diagonal Diagonal Sail area Área vélica Compute Calcular OK OK Cancel Cancelar Layout Formato Mitre cut Corte de meia esquadria Cross cut Corte transversal Twist foot Corte "twist foot" Horizontal cut Corte horizontal Number of sections Número de secções Number of radial gores Número de radiais Radial cut Corte radial Vertical cut Corte vertical Cloth Tecido Cloth width Largura do tecido Leech hem Baínha da valuma Other hems Outras baínhas Seam width Largura da costura Rig geometry Geometria do aparelho Fore triangle hoist I Altura do triângulo de vante - I Mast / Luff rake Caimento do mastro/testa Fore triangle base J Base do triângulo de vante - J Distance tack to stem Distância do punho da amura à proa Tack height Altura do punho da amura Boat length LOA Comprimento do barco fora-a-fora - LOA Sail ID ID da vela Main sail Vela Grande Jib Vela de estai Number of luff gores Número de radiais da testa Dihedral angle Ângulo diedro Wing Asa Sail identifier Identificação da vela m2 m2 Sail name Luff rake Caimento testa Mitre cut 2 Foot hem CRigSailWidget Sail information Informação da vela file ficheiro name nome Reload Recarregar Remove Remover Update Actualizar error erro There was an error reading from the selected file. Houve um erro ao ler do ficheiro seleccionado. CSailDataPrinter Sailcut CAD data sheet Folha de dados do Sailcut CAD Mainsail Vela Grande Jib Vela de Estai Wing Asa deg graus Sail type Tipo de vela Cross Cut Corte Transversal Horizontal Cut Corte Horizontal Radial Cut Corte Radial sections secções head gores radiais do topo luff gores radiais da testa Twist Foot Cut Corte "Twist foot" Vertical Cut Corte Vertical Mitre Cut Corte de Meia Esquadria Mitre Cut 2 Corte de meia esquadria 2 Sail layout Formato da vela Rig Aparelho Boat LOA Comprimento do barco fora-a-fora - LOA Mast/Luff rake Caimento mastro/testa Tack position X Posição do punho da amura X Tack height Y Altura do punho da amura Y Fore triangle hoist I Altura do triângulo de vante - I Fore triangle base J Base do triângulo de vante - J Sail dimensions Dimensões da vela Luff length Comprimento da testa Foot length Comprimento da esteira Leech length Comprimento da valuma Gaff length Comprimento do gurutil Gaff angle wrt luff Âgulo da gurutil wrt testa Shape of edges Forma das extremidades Luff round Curva da testa Luff round position Posição da curva da testa Foot round Curva da esteira Foot round position Posição da curva da esteira Leech round Curva da valuma Leech round position Posição da curva da valuma Gaff round Curva da gurutil Gaff round position Posição da curva do gurutil Sail settings Afinações da vela Twist angle Âgulo de torção Sheeting angle Âgulo de escota Cloth seams and hems Costuras e baínhas do tecido Cloth width Largura do tecido Seams width Largura das costuras Leech hem width Largura da baínha da valuma Foot hem width Other hems width Sail mould Molde da vela Luff factor Factor da testa Depth Profundidade Leech factor Factor da valuma Top profile Perfil do topo Mid profile at h = Perfil do meio em h = Bottom profile Perfil da base Luff rake Caimento testa CSailDevelPrinter Scale CSailDispGL This system has no OpenGL support. Este sistema não tem suporte OpenGL CSailDrawingPrinter Scale CSailPrinter Sailcut CAD data sheet Folha de dados do Sailcut CAD Mainsail Vela Grande Jib Vela de estai Wing Asa deg graus Sail type Tipo de vela Cross Cut Corte transversal Horizontal Cut Corte horizontal Radial Cut Corte radial sections secções head gores radiais do topo luff gores radiais da testa Twist Foot Cut Corte "Twist foot" Vertical Cut Corte Vertical Mitre Cut Corte de Meia Esquadria Sail layout Formato da vela Rig Aparelho Boat LOA Comprimento do barco fora-a-fora - LOA Mast/Luff rake Caimento mastro/testa Tack position X Posição do punho da amura X Tack height Y Altura do punho da amura Y Fore triangle hoist I Altura do triângulo de vante - I Fore triangle base J Base do triângulo de vante - J Sail dimensions Dimensões da vela Luff length Comprimento da testa Foot length Comprimento da esteira Leech length Comprimento da valuma Gaff length Comprimento do gurutil Gaff angle wrt luff Âgulo da gurutil wrt testa Shape of edges Forma das extremidades Luff round Curva da testa Luff round position Posição da curva da testa Foot round Curva da esteira Foot round position Posição da curva da esteira Leech round Curva da valuma Leech round position Posição da curva da valuma Gaff round Curva da gurutil Gaff round position Posição da curva do gurutil Sail settings Afinações da vela Twist angle Ângulo de torção Sheeting angle Ângulo de escota Cloth seams and hems Costuras e baínhas do tecido Cloth width Largura do tecido Seams width Largura das costuras Leech hem width Largura da baínha da valuma Other hem width Largura de outras baínhas Sail mould Molde da vela Luff factor Factor da testa Depth Profundidade Leech factor Factor da valuma Top profile Perfil do topo Mid profile at h = Perfil do meio em h = Bottom profile Perfil da base CSailViewerPanel Display parameters Mostrar parâmetros elevation elevação azimuth azimute Controls Controlos Reset view Reiniciar vista Labeling Etiquetar Zoom in Aumentar zoom Zoom out Reduzir zoom deg graus CSailViewerTabs shaded view Vista sombreada wireframe view vista em grelha CWidgetProfile Luff shape Forma da testa Depth Profundidade % % Leech shape Forma da valuma degrees graus cord corda Dialog XmlReaderTempl error erro There was an error reading from the selected file. Houve um erro ao ler do ficheiro seleccionado. sailcut-1.5.0/src/ts/sailcut_ru.ts000066400000000000000000003044301477005247400171360ustar00rootroot00000000000000 CBoatElementWidget Sail information Информация о парусе file файл name Имя Reload Перезагрузить Remove Удалить Update Обновить Element information CFileIO Open Открыть Save Сохранить CFileWriter error Ошибка There was an error writing to the selected file. Ошибка записи в выбранный файл. Open Открыть There was an error reading from the selected file. Save Сохранить CFormBoat boat &Add file файл Open Открыть CFormHull hull &Dimensions Размеры CFormHullDefBase Dialog Deck and bottom Planking Automatic planking lower plank angle top plank angle Number of planks Bottom Bottom sweep angle % Max Width Forward shape Length Forward height Max Width position Stem angle Transom angle Aft height Aft width Aft shape Hull name Deck Forward height Plank 5 Chine angle Sweep angle Plank angle Plank 4 Plank 3 Plank 2 Plank 1 Plank 6 Check OK ОК Cancel Отмена Dimensions are in millimeters and angles in degrees measured from horizontal Planks txt_BBW txt_BfwdHeight txt_BLWL txt_BaftW txt_BaftHeight Dead rise angle txt_HullID txt_DaftHeight txt_DfwdHeight Side angle CFormMain &New Новый &Open Открыть Open &recent Открыть предыдущий data Данные drawing Панели в сборе develop Отдельных панелей &Print Печатать &Save Сохранить Save &As Сохранить как to &DXF в DXF формат to &TXT sail в TXT формат to &XML sail в XML формат E&xport 3D sail Экспорт 3D паруса to &Carlson plotter в Carlson плоттер Export &development Экспорт панелей &Quit Выход &Dimensions Размеры &Mould Профили &Patches Накладки &Rig Парусное вооружение Language Язык Sailcut CAD &Handbook Справочник по Sailcut CAD About &Qt О программе Qt About &Sailcut CAD о программе Sailcut CAD &File Файл &View Просмотр &Help Помощь shaded view Внешний вид wireframe view В контурах development Раскрой панелей loaded '%1' Загружен '%1' created new sail Создан новый парус About Sailcut CAD О программе Sailcut CAD error loading '%1' Ошибка загрузки '%1' Sail type Тип паруса Mainsail Грот Jib Стаксель Wing Крыло Sail layout Макет паруса Cross Cut Поперечный крой Horizontal Cut Горизонтальный крой Radial Cut Радиальный крой Twist Foot Cut Поперечный крой , параллельный краю нижней шкаторины Vertical Cut Вертикальный крой Mitre Cut Крой под 45 градусов sections, Секции head gores, Клинья верхней части паруса luff gores. Клинья передней шкаторины Rig Парусное вооружение Boat LOA Габаритный размер лодки Fore triangle hoist I Высота крепления штага на мачте от палубы, величина L Fore triangle base J Проекция штага на палубу, величина J Tack position X Положение галсового угла X Tack height Y Высота галсового угла Y Sail dimensions Размеры паруса Luff length Длина передней шкаторины Mast/Luff rake Наклон мачты/штага Gaff angle wrt luff Угол наклона верхней шкаторины гафеля относительно передней шкаторины Gaff length Длина верхней шкаторины гафеля Foot length Длина нижней шкаторины Leech length Длина задней шкаторины Shape of edges Форма краев Luff round Выпуклость передней шкаторины Gaff round Выпуклость верхней шкаторины гафеля Leech round Выпуклость задней шкаторины Foot round Выпуклость нижней шкаторины Luff round position Положение выпуклости передней шкаторины Gaff round position Положение выпуклости верхней шкаторины гафеля Leech round position Положение выпуклости задней шкаторины Foot round position Положение выпуклости нижней шкаторины Sail settings Настройки паруса Twist angle Угол твиста относительно ДП Sheeting angle Угол между диаметральной плоскостью лодки и линией, соединяющей галсовый и шкотовый углы паруса Cloth seams and hems Ширина швов ткани и подгиба Cloth width Ширина ткани Seams width Ширина шва Leech hem width Ширина подгиба задней шкаторины Other hem width Ширина других подгибов Sail mould Профиль паруса Luff factor Фактор передней шкаторины Depth Глубина Leech factor Фактор задней шкаторины Top profile профиль верхней части Mid profile at h = Профиль средней части на h= Bottom profile Профиль нижней части error Ошибка There was a data printing error Ошибка печати данных There was a development printing error ошибка печати панелей There was a drawing printing error Ошибка печати панелей в сборе wrote '%1' Записан '%1' There was an error writing to the selected file Ошибка записи в выбранный файл deg градус to &Hand-plotting format в форматдля ручного черчения sail hull rig Парусное вооружение boat &Window &Close Закрыть Close &All &Tile &Cascade unknown document type '%1' Open Открыть CFormMould Top profile Профиль верхней части Middle profile Профиль средней части Bottom profile Профиль нижней части Sail mould Профиль паруса &Help Помощь &OK ОК &Cancel Отмена Vertical repartition Вертикальный профиль CFormPanelGroup panels CFormPrint &Print Печатать &Cancel Отмена Scale CFormRig Rig Парусное вооружение &New Новый sail &definition Характеристика паруса 3D &sail Парус в 3D &Add sail Добавить парус &Open Открыть Open &recent Открыть предыдущий &Save Сохранить Save &As Сохранить как &Close Закрыть &File Файл error Ошибка There was an error writing to the selected file Ошибка записи в выбранный файл rig Парусное вооружение &Dimensions Размеры CFormRigDefBase Rig dimensions Cancel Отмена OK ОК Spreaders = SPNB Number of spreaders Spreader height txt_SPH2 txt_SPH1 txt_SPH3 SPH2 SPH3 SPH1 Spreader length SPW3 txt_SPW3 SPW1 txt_SPW1 SPW2 txt_SPW2 Shrouds Cap shroud base width = CSH Lower shroud base width txt_LSB txt_CSH = CSB Cap shroud height txt_CSB = LSB Fore triangle txt_foreI = I txt_foreJ = J Fore triangle base Fore triangle hoist Mast Mast width = MW txt_MW txt_MC = MC Mast cord lbl_MRkD = MRkD Mast rake angle txt_MH txt_MRnd Mast rake = MRkM txt_MRkM Mast height = MH = MRnd Mast round = MRndPos Mast round position Mainsail Грот lbl_MS_LuffRP @ lbl_MS_LuffR lbl_MS_TackY Y = lbl_MS_TackX X = Tack lbl_MS_LuffL = MSL Luff length Длина передней шкаторины Luff round Выпуклость передней шкаторины lbl_MS_Rake = MSR Luff rake Tack height txt_BAD = BAD Head height = HAD txt_HAD Check All dimensions are in millimeter and angles in degrees Description of rig Rig name CFormSail sail &Print Печатать data Данные drawing Панели в сборе development Раскрой панелей E&xport 3D sail Экспорт 3D паруса to &DXF в DXF формат to &TXT sail в TXT формат to &XML sail в XML формат Export &development Экспорт панелей to &Carlson plotter в Carlson плоттер to &Hand-plotting format в форматдля ручного черчения &Dimensions Размеры &Mould Профили &Patches Накладки There was a data printing error Ошибка печати данных There was a development printing error ошибка печати панелей There was a drawing printing error Ошибка печати панелей в сборе to &SVG to DXF (split) CFormSailDef Sail corners coordinates Координаты углов паруса tack галсовый угол clew Шкотовый угол head фаловый угол peak задний нок-бензельный угол Sail width measurements CFormSailDefBase Sail definition Характеристика паруса OK ОК Cancel Отмена Layout Макет Mitre cut Крой под углом 45 градусов Cross cut Поперечный крой Twist foot Разновидность поперечного кроя с нижней панелью, параллельной нижней шкаторине Horizontal cut Горизонтальный крой Vertical cut Вертикальный крой Number of luff gores Количество клиньев передней шкаторины Number of radial gores Количество радиальных клиньев Number of sections Количество секций Radial cut Радиальный крой Sail shape Форма паруса % % (процент) Top depth Глубина передней частипрофиля паруса Mid depth Глубина средней части профиля паруса Foot depth Глубина задней части профиля паруса Twist angle угол твиста Sheeting angle Угол между ДП лодки и линией, соединяющей галсовый и шкотовый углы паруса deg градусов Cloth ткань mm мм Cloth width Ширина ткани Leech hem Подгиб задней шкаторины Other hems Подгиб других кромок Seam width Ширина шва Sail-ID Идентификатор ID Sail ID Идентификатор ID текстового описания паруса Sail dimensions Размерения паруса Luff length Длина передней шкаторины Foot length Длина нижней шкаторины Leech length Длина задней шкаторины Gaff length Длина гафеля Leech round Выпуклость (вогнутость) задней шкаторины Luff round Выпуклость (вогнутость) передней шкаторины Gaff round Выпуклость верхней шкаторины гафеля Gaff angle from luff Угол между гафелем и передней шкаториной Diagonal Диагональ Sail area Площадь паруса кв.м Compute Рассчитать Round position Положение макс. выпуклости ( вогнутости) Foot round Выпуклость нижней шкаторины Rig geometry Геометрия парусной оснастки Distance tack to stem Удаление галсового угла от форштевня Main sail Грот Jib Стаксель Dihedral angle Двугранный угол Wing Крыло Mast / Luff rake Мачта/наклон мачты Tack height Высота галсового угла Fore triangle hoist I Высота крепления штага на мачте от палубы Fore triangle base J Расстояние крепления штага на палубе до мачты Boat length LOA Габаритная длина корпуса лодки m2 кв.м Sail identifier Идентификатор паруса Sail name Luff rake Mitre cut 2 Foot hem CRigSailWidget Sail information Информация о парусе file файл name Имя Reload Перезагрузить Remove Удалить Update Обновить error Ошибка There was an error reading from the selected file. Была обнаружена ошибка чтения выбранного файла CSailDataPrinter Sailcut CAD data sheet Таблица данных Sailcut CAD Mainsail Грот Jib Стаксель Wing Крыло deg Sail type Тип паруса Cross Cut Поперечный крой Horizontal Cut Горизонтальный крой Radial Cut Радиальный крой sections Секции head gores Клинья верхней части паруса luff gores Клинья передней шкаторины Twist Foot Cut Поперечный крой , параллельный краю нижней шкаторины Vertical Cut Вертикальный крой Mitre Cut Крой под 45 градусов Mitre Cut 2 Sail layout Макет паруса Rig Парусное вооружение Boat LOA Габаритный размер лодки Mast/Luff rake Наклон мачты/штага Tack position X Положение галсового угла X Tack height Y Высота галсового угла Y Fore triangle hoist I Высота крепления штага на мачте от палубы, величина L Fore triangle base J Проекция штага на палубу, величина J Sail dimensions Luff length Длина передней шкаторины Foot length Длина нижней шкаторины Leech length Длина задней шкаторины Gaff length Gaff angle wrt luff Угол наклона верхней шкаторины гафеля относительно передней шкаторины Shape of edges Форма краев Luff round Luff round position Положение выпуклости передней шкаторины Foot round Выпуклость нижней шкаторины Foot round position Положение выпуклости нижней шкаторины Leech round Leech round position Положение выпуклости задней шкаторины Gaff round Выпуклость верхней шкаторины гафеля Gaff round position Положение выпуклости верхней шкаторины гафеля Sail settings Настройки паруса Twist angle Sheeting angle Cloth seams and hems Ширина швов ткани и подгиба Cloth width Ширина ткани Seams width Ширина шва Leech hem width Ширина подгиба задней шкаторины Foot hem width Other hems width Sail mould Профиль паруса Luff factor Фактор передней шкаторины Depth Глубина Leech factor Фактор задней шкаторины Top profile Mid profile at h = Профиль средней части на h= Bottom profile Профиль нижней части Luff rake CSailDevelPrinter Scale CSailDispGL This system has no OpenGL support. Эта система не имеет поддержки OpenGL CSailDrawingPrinter Scale CSailPrinter Sailcut CAD data sheet Таблица данных Sailcut CAD Mainsail Грот Jib Стаксель Wing Крыло deg градус Sail type Тип паруса Cross Cut Поперечный крой Horizontal Cut Горизонтальный крой Radial Cut Радиальный крой sections Секции head gores Клинья верхней части паруса luff gores Клинья передней шкаторины Twist Foot Cut Поперечный крой , параллельный краю нижней шкаторины Vertical Cut Вертикальный крой Mitre Cut Крой под 45 градусов Sail layout Макет паруса Rig Парусное вооружение Boat LOA Габаритный размер лодки Mast/Luff rake Наклон мачты/штага Tack position X Положение галсового угла X Tack height Y Высота галсового угла Y Fore triangle hoist I Высота крепления штага на мачте от палубы, величина L Fore triangle base J Проекция штага на палубу, величина J Sail dimensions Размеры паруса Luff length Длина передней шкаторины Foot length Длина нижней шкаторины Leech length Длина задней шкаторины Gaff length Длина гафеля Gaff angle wrt luff Угол наклона верхней шкаторины гафеля относительно передней шкаторины Shape of edges Форма краев Luff round Выпуклость передней шкаторины Luff round position Положение выпуклости передней шкаторины Foot round Выпуклость нижней шкаторины Foot round position Положение выпуклости нижней шкаторины Leech round Выпуклость задней шкаторины Leech round position Положение выпуклости задней шкаторины Gaff round Выпуклость верхней шкаторины гафеля Gaff round position Положение выпуклости верхней шкаторины гафеля Sail settings Настройки паруса Twist angle угол твиста Sheeting angle Угол между диаметральной плоскостью лодки и линией, соединяющей галсовый и шкотовый углы паруса Cloth seams and hems Ширина швов ткани и подгиба Cloth width Ширина ткани Seams width Ширина шва Leech hem width Ширина подгиба задней шкаторины Other hem width Ширина других подгибов Sail mould Профиль паруса Luff factor Фактор передней шкаторины Depth Глубина Leech factor Фактор задней шкаторины Mid profile at h = Профиль средней части на h= Bottom profile Профиль нижней части CSailViewerPanel Display parameters Параметры внешнего вида elevation Профиль azimuth Азимут Controls Управление Reset view К исходному виду Labeling Установка меток Zoom in Увеличить Zoom out Уменьшить deg Градусов CSailViewerTabs shaded view Внешний вид wireframe view В контурах CWidgetProfile Luff shape Форма передней шкаторины Depth Глубина % % Leech shape Форма задней шкаторины degrees cord Dialog XmlReaderTempl error Ошибка There was an error reading from the selected file. Обнаружена ошибка чтения выбранного файла sailcut-1.5.0/src/ts/template.ts000066400000000000000000001741461477005247400166100ustar00rootroot00000000000000 CBoatElementWidget file name Reload Remove Update Element information CFileWriter error There was an error writing to the selected file. Open There was an error reading from the selected file. Save CFormBoat boat &Add file Open CFormHull hull &Dimensions CFormHullDefBase Dialog Deck and bottom Planking Automatic planking lower plank angle top plank angle Number of planks Bottom Bottom sweep angle % Max Width Forward shape Length Forward height Max Width position Stem angle Transom angle Aft height Aft width Aft shape Hull name Deck Forward height Plank 5 Chine angle Sweep angle Plank angle Plank 4 Plank 3 Plank 2 Plank 1 Plank 6 Check OK Cancel Dimensions are in millimeters and angles in degrees measured from horizontal Planks txt_BBW txt_BfwdHeight txt_BLWL txt_BaftW txt_BaftHeight Dead rise angle txt_HullID txt_DaftHeight txt_DfwdHeight Side angle CFormMain &File &New &Open Open &recent &Save Save &As &Quit &View Language &Help Sailcut CAD &Handbook About &Qt About &Sailcut CAD loaded '%1' About Sailcut CAD error loading '%1' wrote '%1' sail hull rig boat &Window &Close Close &All &Tile &Cascade unknown document type '%1' Open CFormMould Sail mould &OK &Cancel Vertical repartition Top profile Middle profile Bottom profile CFormPanelGroup panels CFormPrint &Print &Cancel Scale CFormRig rig &Dimensions CFormRigDefBase Rig dimensions Cancel OK Spreaders = SPNB Number of spreaders Spreader height txt_SPH2 txt_SPH1 txt_SPH3 SPH2 SPH3 SPH1 Spreader length SPW3 txt_SPW3 SPW1 txt_SPW1 SPW2 txt_SPW2 Shrouds Cap shroud base width = CSH Lower shroud base width txt_LSB txt_CSH = CSB Cap shroud height txt_CSB = LSB Fore triangle txt_foreI = I txt_foreJ = J Fore triangle base Fore triangle hoist Mast Mast width = MW txt_MW txt_MC = MC Mast cord lbl_MRkD = MRkD Mast rake angle txt_MH txt_MRnd Mast rake = MRkM txt_MRkM Mast height = MH = MRnd Mast round = MRndPos Mast round position Mainsail lbl_MS_LuffRP @ lbl_MS_LuffR lbl_MS_TackY Y = lbl_MS_TackX X = Tack lbl_MS_LuffL = MSL Luff length Luff round lbl_MS_Rake = MSR Luff rake Tack height txt_BAD = BAD Head height = HAD txt_HAD Check All dimensions are in millimeter and angles in degrees Description of rig Rig name CFormSail sail &Print data drawing development E&xport 3D sail to &DXF to &TXT sail to &XML sail Export &development to &Carlson plotter to &Hand-plotting format &Dimensions &Mould &Patches to &SVG to DXF (split) CFormSailDef Sail corners coordinates tack clew head peak Sail width measurements CFormSailDefBase Sail definition OK Cancel Sail dimensions mm Round position Luff length Foot length Leech length Gaff length Leech round Luff round Foot round % deg Gaff round Gaff angle from luff Diagonal Sail area m2 Compute Layout Mitre cut Cross cut Twist foot Vertical cut Radial cut Number of sections Number of radial gores Number of luff gores Horizontal cut Sail shape Top depth Mid depth Foot depth Twist angle Sheeting angle Cloth Cloth width Leech hem Other hems Seam width Sail identifier Rig geometry Wing Jib Main sail Dihedral angle Boat length LOA Distance tack to stem Fore triangle base J Tack height Fore triangle hoist I Sail name Luff rake Mitre cut 2 Foot hem CSailDataPrinter Sailcut CAD data sheet Mainsail Jib Wing deg Sail type Cross Cut Horizontal Cut Radial Cut sections head gores luff gores Twist Foot Cut Vertical Cut Mitre Cut Mitre Cut 2 Sail layout Rig Boat LOA Tack position X Tack height Y Fore triangle hoist I Fore triangle base J Sail dimensions Luff length Foot length Leech length Gaff length Gaff angle wrt luff Shape of edges Luff round Luff round position Foot round Foot round position Leech round Leech round position Gaff round Gaff round position Sail settings Twist angle Sheeting angle Cloth seams and hems Cloth width Seams width Leech hem width Foot hem width Other hems width Sail mould Luff factor Depth Leech factor Top profile Mid profile at h = Bottom profile Luff rake CSailDevelPrinter Scale CSailDrawingPrinter Scale CSailViewerPanel Display parameters elevation azimuth Controls Reset view Labeling Zoom in Zoom out deg CSailViewerTabs shaded view wireframe view CWidgetProfile Luff shape Depth % Leech shape degrees cord Dialog sailcut-1.5.0/src/widgetprofile.cpp000066400000000000000000000221551477005247400173370ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include "widgetprofile.h" #include "widgetprofilevert.h" #include "sailcpp/sailmould.h" /************************************************************************** CLabelProfile class **************************************************************************/ /** The constructor. * * @param parent the parent dialog * @param ptr pointer to the CProfile */ CLabelProfile::CLabelProfile( QWidget *parent, CProfile *ptr) : QLabel(parent), profile(ptr), wasResized(true) { // set the background to white QPalette pal = palette(); pal.setColor( QPalette::Window, Qt::white ); setPalette( pal ); setMinimumSize( QSize( 300, 100 ) ); } /** Display the CProfile in the drawing area. */ void CLabelProfile::paintEvent( QPaintEvent *) { QPainter painter( this ); QPen pen = painter.pen(); pen.setColor(Qt::black); pen.setWidth(0); painter.setPen(pen); QRect vRect = painter.viewport(); painter.eraseRect(vRect); CRect3d objRect; objRect.max = CPoint3d(1, 0.22, 0); if ( wasResized ) { CRect3d viewRect; viewRect.max = CPoint3d(vRect.width() , vRect.height(), 0); lRect = calcLRect(viewRect , objRect, objRect.center(), 0.8); wasResized = 0; } QPoint prev, next; unsigned int nbpoints = 32; real x, z; real scale = vRect.height() / lRect.height(); // do a translation to have from z=0 to z=scale centered painter.translate( (lRect.width() / 2 - objRect.center().x()) * scale, vRect.height() + (objRect.center().y() - lRect.height()/2) * scale ); // flip coordinate system to have the z axis pointing up painter.scale(1,-1); prev = QPoint( 0 , int(scale * profile->z(0) ) ); for (unsigned i = 1; i < nbpoints; i++) { x = real(i) / (nbpoints -1); z = profile->z(x); next = QPoint( int(x * scale) , int(z * scale) ); painter.drawLine(prev , next); prev = next; } } /** The draw area has been resized. */ void CLabelProfile::resizeEvent( QResizeEvent * ) { wasResized = 1; } /************************************************************************** CWidgetProfile class **************************************************************************/ /** The constructor. * * @param parent the parent dialog * @param ptr a pointer to the profile we are displaying / editing * @param caption caption for the profile view (e.g. top,middle..) QLabel* lblLeech; * @param vert the vertical repartition widget */ CWidgetProfile::CWidgetProfile( QWidget *parent, CProfile *ptr, QString caption , CWidgetProfileVert *vert) : QWidget(parent), widgetVert(vert) { // store the pointer profile = ptr; QHBoxLayout *layout = new QHBoxLayout( this ); QGroupBox *grpProfile = new QGroupBox( this ); // grpProfile->setAlignment( int( QGroupBox::AlignCenter | QGroupBox::AlignRight | QGroupBox::AlignLeft ) ); // grpProfile->setColumnLayout(0, Qt::Vertical ); QGridLayout *grpProfileLayout = new QGridLayout( grpProfile ); grpProfileLayout->setAlignment( Qt::AlignTop ); grpProfile->setTitle(caption); //// add the spin boxes for changing profile QHBoxLayout *spinBoxesLayout = new QHBoxLayout(); // luff factor lblLuff = new QLabel( grpProfile ); lblLuff->setAlignment( Qt::AlignVCenter | Qt::AlignRight ); spinBoxesLayout->addWidget( lblLuff ); spinLuff = new QSpinBox( grpProfile ); spinLuff->setMaximum( 18 ); spinLuff->setMinimum( 0 ); spinLuff->setValue( 1 ); spinBoxesLayout->addWidget( spinLuff ); QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum ); spinBoxesLayout->addItem( spacer ); // depth lblDepth = new QLabel( grpProfile ); lblDepth->setAlignment( Qt::AlignVCenter | Qt::AlignRight ); spinBoxesLayout->addWidget( lblDepth ); spinDepth = new QSpinBox( grpProfile ); spinDepth->setMaximum( 40 ); spinDepth->setMinimum( 1 ); spinDepth->setValue( 10 ); spinBoxesLayout->addWidget( spinDepth ); lblPercent = new QLabel( grpProfile ); spinBoxesLayout->addWidget( lblPercent ); QSpacerItem* spacer_2 = new QSpacerItem( 20, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum ); spinBoxesLayout->addItem( spacer_2 ); // leech factor lblLeech = new QLabel( grpProfile ); spinBoxesLayout->addWidget( lblLeech ); spinLeech = new QSpinBox( grpProfile ); spinLeech->setMinimum( -4 ); spinLeech->setMaximum( 20 ); spinBoxesLayout->addWidget( spinLeech ); grpProfileLayout->addLayout( spinBoxesLayout, 1, 0 ); QSpacerItem* spacer_3 = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); grpProfileLayout->addItem( spacer_3, 0, 0 ); //// add the additional data labels QHBoxLayout *dataBoxesLayout = new QHBoxLayout(); lblLuffSlopeValue = new QLabel(grpProfile); dataBoxesLayout->addWidget (lblLuffSlopeValue); lblLuffSlopeDegrees = new QLabel(grpProfile); dataBoxesLayout->addWidget (lblLuffSlopeDegrees); QSpacerItem* spacer_5 = new QSpacerItem( 20, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum ); dataBoxesLayout->addItem( spacer_5 ); lblMaxPosValue = new QLabel(grpProfile); dataBoxesLayout->addWidget (lblMaxPosValue); lblMaxPosCord = new QLabel(grpProfile); dataBoxesLayout->addWidget (lblMaxPosCord); QSpacerItem* spacer_6 = new QSpacerItem( 20, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum ); dataBoxesLayout->addItem( spacer_6 ); lblLeechSlopeValue = new QLabel(grpProfile); dataBoxesLayout->addWidget (lblLeechSlopeValue); lblLeechSlopeDegrees = new QLabel(grpProfile); dataBoxesLayout->addWidget (lblLeechSlopeDegrees); grpProfileLayout->addLayout( dataBoxesLayout, 2, 0 ); /// create the drawing area lblDraw = new CLabelProfile( grpProfile, profile ); grpProfileLayout->addWidget( lblDraw, 0, 0 ); // add the group box that contains all the above elements layout->addWidget( grpProfile ); // we set the "active" flag to false so that we can set the initial // values without slotChanged being triggered active = false; spinLeech->setValue( int(round(profile->getLeech() * 50) ) ); spinLuff->setValue( int(round(profile->getLuff() ) ) ); spinDepth->setValue( int(round(profile->getDepth() * 100) ) ); active = true; // signals and slots connections connect( spinLuff, SIGNAL( valueChanged(int) ), this, SLOT( slotChanged() ) ); connect( spinDepth, SIGNAL( valueChanged(int) ), this, SLOT( slotChanged() ) ); connect( spinLeech, SIGNAL( valueChanged(int) ), this, SLOT( slotChanged() ) ); // set translations and trigger update // NOTE : all the widgets need to be created before doing this connect(qApp, SIGNAL(languageChanged()), this, SLOT(languageChange())); languageChange(); // trigger the computation of profile to update the ancillary data labels slotChanged(); } /** Sets the strings of the subwidgets using the current * language. */ void CWidgetProfile::languageChange() { lblLuff->setText( tr( "Luff shape" ) ); lblDepth->setText( tr( "Depth" ) ); lblPercent->setText( tr( "%" ) ); lblLeech->setText( tr( "Leech shape" ) ); // ancillary data labels lblLuffSlopeDegrees->setText( tr( "degrees" ) ); lblMaxPosCord->setText( tr( "cord") ); lblLeechSlopeDegrees->setText( tr( "degrees" ) ); } /** Called when one of the spinboxes changes value. */ void CWidgetProfile::slotChanged() { if ( active == false ) return; // store the new values *profile = CProfile( real(spinDepth->value())/100, real(spinLeech->value())/50, spinLuff->value() ); // update profile view lblDraw->update(); // display the position of the maximum depth lblLuffSlopeValue->setText( QString::number ( int( 57.29579 * atan(profile->slope(0.0)) ) )); lblMaxPosValue->setText( QString::number (profile->getMaxPos() ) ); lblLeechSlopeValue->setText( QString::number ( int( 57.29579 * atan(profile->slope(1.0)) ) ) ); // update the vertical repartition view widgetVert->updateLabel(); } sailcut-1.5.0/src/widgetprofile.h000066400000000000000000000064021477005247400170010ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef WIDGETPROFILE_H #define WIDGETPROFILE_H #include #include "sailcpp/sailcalc.h" class QSpinBox; class CProfile; class CWidgetProfileVert; /************************************************************************** CLabelProfile class **************************************************************************/ /** Drawing area fpr a CProfile. */ class CLabelProfile : public QLabel { public: CLabelProfile(QWidget *, CProfile *); protected: void paintEvent( QPaintEvent *); void resizeEvent( QResizeEvent * ); private: /** the CProfile we are displaying */ CProfile* profile; /** the logical viewport rectangle */ CRect3d lRect; /** Has the area been resized since last redraw */ bool wasResized; }; /************************************************************************** CWidgetProfile class **************************************************************************/ /** Widget for displaying a CProfile. It has a display area and 3 spinboxes. * * @see CProfile * @see CLabelProfile * @see CWidgetProfileVert */ class CWidgetProfile : public QWidget { Q_OBJECT public: CWidgetProfile( QWidget*, CProfile*, QString, CWidgetProfileVert* ); protected slots: void slotChanged(); private slots: void languageChange(); // member variables public: /** label for luff */ QLabel* lblLuff; /** label for depth */ QLabel* lblDepth; /** label for percent */ QLabel* lblPercent; /** label for leech */ QLabel* lblLeech; /** label for Luff slope value */ QLabel* lblLuffSlopeValue; /** label for Luff slope 'degrees' */ QLabel* lblLuffSlopeDegrees; /** label for max depth position */ QLabel* lblMaxPosValue; /** label for max depth 'cord' */ QLabel* lblMaxPosCord; /** label for leech slope value */ QLabel* lblLeechSlopeValue; /** label for leech slope 'degrees' */ QLabel* lblLeechSlopeDegrees; /** spinbox for luff */ QSpinBox* spinLuff; /** spinbox for depth */ QSpinBox* spinDepth; /** spinbox for leech */ QSpinBox* spinLeech; protected: /** drawing area for the profile */ CLabelProfile* lblDraw; /** widget for the vertical repartition */ CWidgetProfileVert *widgetVert; /** the profile we are displaying */ CProfile* profile; /** active flag to disable slotChanged */ bool active; }; #endif // WIDGETPROFILE_H sailcut-1.5.0/src/widgetprofilevert.cpp000066400000000000000000000125711477005247400202410ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "widgetprofilevert.h" #include "sailcpp/sailcalc.h" #include "sailcpp/sailmould.h" #include #include #include #include /************************************************************************** CLabelProfileVert class **************************************************************************/ /** The constructor. * * @param parent the parent dialog * @param ptr pointer to the CSailMould */ CLabelProfileVert::CLabelProfileVert( QWidget *parent, CSailMould *ptr) : QLabel(parent), mould(ptr), wasResized(true) { // set the background to white QPalette pal = palette(); pal.setColor( QPalette::Window, Qt::white ); setPalette( pal ); setMinimumSize( QSize( 120, 400 ) ); } /** Display the vertical repartition in the drawing area. */ void CLabelProfileVert::paintEvent( QPaintEvent *) { QPainter painter( this ); QPen pen = painter.pen(); pen.setColor(Qt::black); pen.setWidth(0); painter.setPen(pen); QRect vRect = painter.viewport(); painter.eraseRect(vRect); CRect3d objRect; objRect.max = CPoint3d(0.22, 1, 0); if ( wasResized ) { CRect3d viewRect; viewRect.max = CPoint3d(vRect.width(), vRect.height(), 0); m_lRect = calcLRect(viewRect, objRect, objRect.center(), 0.8); wasResized = 0; } QPoint prev, next; unsigned int nbpoints = 32; real z, y; // z is horizontal and y is vertical upward real scale = vRect.height() / m_lRect.height(); // do a translation to have from z=0 to z=scale centered painter.translate( (m_lRect.width() / 2 - objRect.center().x()) * scale, vRect.height() + (objRect.center().y() - m_lRect.height()/2) * scale ); // flip coordinate system to have the y axis pointing up painter.scale(1,-1); prev = QPoint( int(scale * mould->interpol(0).getDepth()), 0 ); for (unsigned i = 1; i < nbpoints; i++) { y = real(i) / (nbpoints-1); z = mould->interpol(y).getDepth(); next = QPoint( int(scale * z) , int(scale * y)); painter.drawLine(prev, next); prev = next; } } /** The draw area has been resized. */ void CLabelProfileVert::resizeEvent( QResizeEvent * ) { wasResized = 1; } /************************************************************************** CWidgetProfileVert class **************************************************************************/ /** The constructor. * * @param parent the parent dialog * @param mouldptr pointer to the CSailMould * @param caption caption for the profile view (e.g. top,middle..) */ CWidgetProfileVert::CWidgetProfileVert(QWidget *parent, CSailMould *mouldptr, QString caption) : QWidget(parent), sailmould(mouldptr) { QHBoxLayout *layout = new QHBoxLayout( this ); grpVertical = new QGroupBox( this ); grpVertical->setTitle(caption); QVBoxLayout *grpVerticalLayout = new QVBoxLayout(grpVertical); //////////// QHBoxLayout *drawVerticalHBox = new QHBoxLayout(); // add depth vertical repartition draw area lblDrawVert = new CLabelProfileVert( grpVertical, sailmould ); drawVerticalHBox->addWidget( lblDrawVert ); // add vertical slider for mid depth position sliderVertical = new QSlider( grpVertical ); sliderVertical->setMinimum( 30 ); sliderVertical->setMaximum( 70 ); sliderVertical->setOrientation( Qt::Vertical ); sliderVertical->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); //sliderVertical->setValue( 100 - sailmould->vertpos ); sliderVertical->setValue( sailmould->vertpos ); drawVerticalHBox->addWidget( sliderVertical ); grpVerticalLayout->addItem( drawVerticalHBox ); ///////////// QHBoxLayout *lblVerticalHBox = new QHBoxLayout(); lblVertical = new QLabel( grpVertical ); lblVertical->setAlignment( Qt::AlignCenter ); lblVerticalHBox->addWidget( lblVertical ); grpVerticalLayout->addItem( lblVerticalHBox ); ///////////// layout->addWidget( grpVertical ); slotSliderVert(); connect( sliderVertical, SIGNAL( valueChanged(int) ), this, SLOT( slotSliderVert() ) ); } /** Trigered when the user moves the vertical repartition slider. */ void CWidgetProfileVert::slotSliderVert() { // store new value of vertical position of mid profile and update label //sailmould->vertpos = 100 - sliderVertical->value(); sailmould->vertpos = sliderVertical->value(); lblVertical->setText( QString::number(sailmould->vertpos) ); // update vertical profile view lblDrawVert->update(); } sailcut-1.5.0/src/widgetprofilevert.h000066400000000000000000000045261477005247400177070ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef WIDGETPROFILEVERT_H #define WIDGETPROFILEVERT_H #include #include #include class QLabel; class QSpinBox; class QGroupBox; class QSlider; class QResizeEvent; class CSailMould; class CLabelProfileVert; class CRect3d; /** Drawing area for the vertical repartition. */ class CLabelProfileVert : public QLabel { public: CLabelProfileVert(QWidget *, CSailMould *); protected: void paintEvent( QPaintEvent *); void resizeEvent( QResizeEvent * ); private: /** The CSailMould we are displaying */ CSailMould *mould; /** The logical viewport */ CRect3d m_lRect; /** Has the area been resized since last redraw */ bool wasResized; }; /** Widget for displaying vertical repartition. * * @see CProfile * @see CLabelProfile * @see CLabelProfileVert */ class CWidgetProfileVert : public QWidget { Q_OBJECT public: CWidgetProfileVert( QWidget*, CSailMould*, QString ); /** redraw the vertical repartion drawing */ void updateLabel() { lblDrawVert->update(); } protected slots: virtual void slotSliderVert(); // member variables protected: /** the CSailMould */ CSailMould *sailmould; /** groupbox for vertical repartition */ QGroupBox* grpVertical; /** label for the vertical repartition */ QLabel* lblVertical; /** slider for the vertical repartition */ QSlider* sliderVertical; /** the vertical repartition drawing area */ CLabelProfileVert * lblDrawVert; }; #endif // WIDGETPROFILEVERT_H sailcut-1.5.0/test-cases/000077500000000000000000000000001477005247400152465ustar00rootroot00000000000000sailcut-1.5.0/test-cases/First-25.7S.hulldef000066400000000000000000000015101477005247400204130ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/Parche-main.saildef000066400000000000000000000035631477005247400207320ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/Vela Parche.saildef000066400000000000000000000036171477005247400206600ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/default-boat.boatdef000066400000000000000000012531601477005247400211530ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/default-genoa.saildef000066400000000000000000000035211477005247400213130ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/default-hull.hulldef000066400000000000000000000014631477005247400212050ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/default-jib.saildef000066400000000000000000000035151477005247400207710ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/default-main.saildef000066400000000000000000000035301477005247400211460ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/default-mizaine.saildef000066400000000000000000000035251477005247400216620ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/default-staysail.saildef000066400000000000000000000035171477005247400220600ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/first-25.7-jib-creux-haut.saildef000066400000000000000000000035561477005247400231550ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/first-25.7-jib-creux.saildef000066400000000000000000000035431477005247400222120ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/first-25.7-jib-moyen.saildef000066400000000000000000000035561477005247400222170ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/first-25.7-jib-plat.saildef000066400000000000000000000035541477005247400220260ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/first-25.7-jib.saildef000066400000000000000000000035451477005247400210700ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/first-25.7S.rigdef000066400000000000000000000017331477005247400202770ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/genoa1.2.4.saildef000066400000000000000000000035441477005247400202610ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/hull1.3.3.hulldef000066400000000000000000000015101477005247400201370ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/jib1.2.4.saildef000066400000000000000000000035421477005247400177320ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/lucyIIIMitre.saildef000066400000000000000000000036121477005247400211110ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/luff-curve.ods000066400000000000000000000432011477005247400200330ustar00rootroot00000000000000PKM>l9..mimetypeapplication/vnd.oasis.opendocument.spreadsheetPKM>Configurations2/statusbar/PKM>'Configurations2/accelerator/current.xmlPKPKM>Configurations2/floater/PKM>Configurations2/popupmenu/PKM>Configurations2/progressbar/PKM>Configurations2/menubar/PKM>Configurations2/toolbar/PKM>Configurations2/images/Bitmaps/PKM> content.xmlr7)TکD3eM6II[3-lPm|}=h&)r&}|@_~}|z1~|~nͿ|=.Wbx>^=-};~6gף|lqlz_Wz^d8bۋE/kvsqC/kQݯ_N~dx9V---~|bqÇMg(>M.ΏInn6?>k]oM3Zx7|@uav!;}unI3:Yqo* W%W??|̵^S7iv?NkUlg/%#+;W"9{hr^F\13&_w"%_ Gx~?ϯF/u2|RL]Y䳱y ~jzd/;<#\>Ë|2k5lTyb6MT\'ݯt80Ͻ+nƋsF]{Gx/fjhEmt3ڂU8_WxG)AOq}Rbʁir{u_}px<-|r-T÷9+uf0!QgneͦZ'V|>{c 'pb|5 o/fyw>' oFƷvhUʩŀf2XS`^M/&mwUe?}f43U*lc03Mﮇ@gM>Fޣw5?j*q] hn|=晇yNzl cu<ƴem34ίb_Q{ڲqbz˛x 7lOo{i`vmi<ѵj *Lٵ6} 8FPㄳKLc}2}C˃F [sn74]oOo V Kn^0S4GFI'#Y [Hɴd5]9 o#{QS~}z#Ʃ=LYB'y+?}-*<V>}wD$ub' |8ZP^|lGnfb>|mߋ.O&}jyl t6~ϛ/e/bhS]ήe/sI›E>7OѾQC-PV^:Z/ kψ.bij,+YEx^؊̦qiwv?Wem>\| oOۛo~>*?i.͸LMJG QնtjƳbL4K3~w>o{p>u;?P҇oBnNAL}Q1ys㮊8,x?lBuo//ogwV膇{֥2q{r6A6_Ga 蠟 jpV?ݭcy?^^ӭۣ &0m\z#r&]u=deo ׍~ݦ2p|Yr t9~} ȵMI`m6vb9B:oQ`p= 1%KLSVdTgQt0:#ͭ< })zU4E}5,eitcIxa'UO)|Y~C4J LWiS(~W*eP̰(#B*vbJq#?7f?7?~_ Дa!- )3P`7~Y_~S2bDkɹJ@[ږi)F0eFxGAQْ2i}hkqPl?* zׅO=q"1Z#ǘ~ aVN%4Fr TO]dC k)t KlO* ЦPU iI5@E:(^Zi CdQ%;P2)+4c HK )\;dcYqigtfa$fEp RLqm̯e~'0bLjk%:nc{X $3{7g(u1kߤ[qlPl\H1;}d( Ǻ7WLz۶ x0`># {YZi!DX`HaBQy0%#W}2rՏ""N4HnO*R2r'U\KALqƵRj[Aq7 T5" #;H0HSB=K\QkZ"rQi VQ( rdS*DV"PDFI`u4 %@dU rigtf\h0\B<^+eq 6* )7#ɀyo/" DvbC6Ѹ;;Щ9`CdX7V8<,K<.cXxzcmavvq/Uqas/K <- x,hM"cEW,W( _ >+ԱV*X< !`8N]q # @H zK$}VkZqB!!I8/3EJTuu:qa tu.B: \)` ̨N5Oqqm̯u1c `|V wјqݮ31*fAc2vwur_i{sVRk&9< Z$f\$XnY~b)OQLB1}LICjLv>hɇ~=,,;r.L M< t l*^ھ <@4Sa-]3$VS@[j 1*lb!sARd ya  "|fϽؚM#59BLXq)2&)t>~mM%y !8||elrv?Ż#sBw^tϤn,pwklM\5,Y꾍qa쮍@ZR/GY;Z\J7[ F LD)C'EIѻJ%z]-Yis7E)oػQ%)ٻ|%(?&˥Mn Zw0b$Z!{ %X;F[ ARx;FP2p #"-EIh8+X+&2`G6EKb7|qߪzG`])MVP, wvʓhyAK?).쵚gEE3 wT(d߿/=ukɵC5Y"p(j`xV'EvPvPvP:ԱÏҡ/nwPvPlvPvKKt(_hVvC!BpFq|2 u@@ӖFJзC$q=yĞU|+8NՄIʸ2L0/`O" ў' _Vfyj(LK19QX 2 *]u ہCvp-5g0ss\];XQY,d̸$ţ ށ$( "`\aX2)Ι3Kޱ(kHEcܹ&37d% j>bwX?m?{;+kQȱ>yyQmEiwX{YYᩕObȍ"$SRn3kQL{:1%<=*.\"6E)J4(~ВaTbH" PhM<0SCڸGFTC:QGيc5b!f0%q1~ѳ ꁃzLCXЖkImXʪϬ|hD Ds$=)"I{ u=c -E%ES Â{l2wZ{=a eIi `J|-Й aczH?GoA֊D 7C:GY^VVxj+,Y!9qHrJ\4%;7]Ʋsӥ"qB3PZ_ΎΜiͩfg&^a#a}{C¢KK1^c4!mKxҖ!-" &3A iԊA{ QH(m@qC]Y,ЎE4?;|e}l,5Aq3`HR=K@L{l2ʚ"Gq{$M"GRHIdKbwyjp_D5FRy\@^{x*h msTVxj+M1o1THنtþZ]KEyoAT-ЯH эeT $϶"G} M@&AXp%#Ŕ wVi[1treu#DQ-ڞ'Źr TkJ QYK-FR+w$@&BQ2",d\ wlb-fhH#9;P l.tfbBRq3s'y|̵K boyS-{+GF\r3XnBy1:$+Il{Lu̾4G\jܔ%6JZ_9 E(EaDL Xvf4 Jl&D@kdrzK Q"G c!e0n>S2 )7@I07#ιP &[r3Xn3c5aT ǎMJ$}Ln&Q =!9#o3١gjVL-=ٱTeLbK'a\zg3g 8BRθwXUKRtqw S<IsMVk3;vvvH)b3lnDBXoZpv 3K"rf-34-n4-Qu'> 2ECVd2I&C*d@v)fv)fv)fv)f]]g3.qHR,e+-ebfbgK1Ѭ*u&E^_7:H vHz;,yK+Өb,$ADei1S#y\2d\gN 3w!9̗UZ$*2X;E("J~laAK>aS9,̹WɴP=c%uGj/氥U :hJ-%i,6)sJu~ɵd닉P{ВHl*%=sԾ)lgl'c=4VV-YP4Ȱ2&͜4t</i40tR@3m.CmkyZM#ٞ1K+GxR8 #%- NE3=e~b)%ۃZ$mv 3s0iGҤ\wuRK,V+sAK>+Rs#4?6iF1d@)"mNZZu_RFr:B .!([sEzFL<0<؞,6G״fwP!9ʪϬ|hDIhjM@mEu'(ecׯ)g).1ao5<v'QkP ;Gj5$h{V'|LdAc?FvVR4g 'h˟,X͸ O|celJan'iT颠}e,LIuFJpP  j4AK>QBt#LSZ@f ,h,$\ڜ >J֜3ɘEڂn(:F[#{=%t >%&S>FCZ0ڞgv =0K\jf Xk0Zf0{hSް(4e{[x.却^RY+v叐ak ڲ(}hoqWdIk!hn W-AGXaI 3(Vr7dII#5]$Ke1E9DEF|WDFL&_,0gXD)NHЍBh˙ЀH7ښAk[֒ nB>?Eh^!4f\rą&ݡ\1yf8ݍ7z*LD~82D34ei/Vo^ לcZFsY9T<>~ہeyݾEP?쾝1rۙ,,?+, m\XbфKu)QQn\cV(Jύ-ЯHύ<3~ ”|3Qga41a&pzJ,>7VP4#)N{xJq!<ᳰxЊ"a=J7d |EsKP CNUOP,| d g>>Gb||3ܲJlN 86J;3 Iho~ + i=Df9mA|EhY!aB ĴDS7cKu rM7a~@ I7(~ВaM2*f뮕 mR P|DH!`PrM\ %w tm1*UƙJPRwjS -'Ш\ĭeZZBKavɎ llVFSdѽe2qBXZ+.(zwIg:L9>MCHD]1I.jwneQUI:#*aƃ1wa5ۮH&y`Petǟ ,WUbyfJPA9!?S+R%].1 KXOhΘPZ_9, (&\ p1$rUBnC styles.xmlYݎ6SDAB 5d`agV*E:N"#ۙ.<}>I; Eb9|1K=Ⴒ|ㆋuHYDd+ƽ~wb.3KOSJƹXW!A:Gk׬ 5Z7kT55঵$G9Xa[~ܴ8:5VXi9,hg;WPXJ֨szmoSV%p; |L:$+~cZ`xs_RA.TӍZV *Bcd MǜrV}}(VWẠ7t{&PyN=Y`:3Y/w&K߃=.>N1qz(M$0*v!Y +gR~7XE{W EAQ_ ;^"J=yR=DXh-uXۨWC\A~m732T2|0M6'\^RãIg  )ֈ]?z څ8zPyΚB ۚ (%OֵNulo2 twww7CQo5TյWhW6ccXA-w(hX tV^p婮.+_ 8,L=Q΂~]XYW-NR{$w`|Rˎ /Mk :Ot#c 0\?Wk+)ou]j_?|0ÿ0PKW+pPKM>rSSmeta.xml OpenOffice.org/2.4$Linux OpenOffice.org_project/680m17$Build-9310Robert Lainé2011-04-26T21:41:33Robert Lainé2011-05-06T11:40:54Robert Lainé2011-05-06T11:39:068PT51M54SPKM>Thumbnails/thumbnail.png{=Xs]g :gDžґq]Lڮˍx{[edwwvs& ߫ȽZwg`:!{͌UQݲmӧ2&r$z zT֕ 2dUKYVV1LyZ z^(<|~C8Wʟ3mCu[.*;ipk䮋g$j33w.#dåcY.Q(3ĴVCj "AS+[>4S/kZ/mO"a~&Aڏɰ3?'L?z S-GTN4-c%x39 櫛p sۘmK\K{\S^smj Z;S$.xД;& ٹl=XV|;vN cYN5-]bz.Gn=lPH@/D= Eϛ^2$n"k6wȍ4 I &=w,"5k5\k7k/F?B~5ܫ-b\ ȅ62/2JNwZ0v`F^iصFE'ilzp $^&k?oUEF1(.k60OL7fQp鄨jUNʡL5yYIG?X޽\)W < /ڇ%jUPh$tW-<\ n/|KFVZj It,IUO&bU7.$)بPrYCQN."LjښP!OJҪ֠/~b۔I6[-X&d6 ~NCEe'A.)U^'-xU?h[_5u;v<5qC:S[! M)0iw7FK8 U_~v_0h^yoIbC҈ +@YsZm~ Ɉv{N*H ߁UWt-47[]' ^x'c& %qIȥQO9 okI XC`<w8fjÃpײ _J:j׌=+sLξL7D2Qg h㴏aqN¡]Jy ҹ$w{]`<;umo U u1'(X'F#ܛ"B΢:-\Jĥa5*fZ7i_WBE9әVY#<䚈<%B4WL^d㜗PkTISRoI^ѽT}#-ZѨJ;cf6+(oFER:?KrK:~Nu_F>no?_j6~CwBUe *:8 ^k"l~pQa3/2v[n?x܄\3T>,uId.y/QӽQԉazHW*3 O+7clA asv4O`3oi(-IA fIY~MRB8ujw+b8\8:{:,юʎ 53eg:2U ]z9s^7-fz/2zpI]FrJ Rꣽ[ArD^%W\pvBBo(-.gq,3`ht"c*Z+Nj:! yJx;dl$3hD|Nd^-L!PfP!,u ?\͟F֌E锎Gq9OS͐r :"Y!h}N<ydIB1׭1(Wj,{;>ιB]2 PK settings.xmlYYs8~_8  p `slɶȒW1ׯ̑"0[[S-׭V_j~[zjG)kUġ.";oU3)J9R' S$'SFpċxS>$;#N 0 ÛkfٜnC͎eϊR("fj>yWB&vz-teyd^H;E,. _{M3@ nP|9PJm-ȇp*.FE]߀9eg9d9BISPN/ G\%G; |'oʁkK*gwe*RPY%U@qMVO(p"9ax)$X#/ׁXZgQm6AY3?; FaM w dt-?EߦRЧ{jbbИFN 7*վ^@+uGz4CEs5@!t\y6܄ ߢ=ot~c8 Xvbυ7E O X"n3gg# 7~Dgwɇ֛ϔ>SodVv,CEyPh˗3l&dH/pXȗlaϬk5}_  gmUeG70v7S2{0|>tԫUձi,+,Eu5V[UݚɨհoSG=z:CVW ZwV pհyoV% +^{aKImm86&ؖ50le4CW6ȯ} &_n˵h羏W}= ;OLRf#ׅ2 8"ʏ^-4m{uDSvb_RĞ3`xFݢfߧ/"IX%z|z><wy2bpN@TJ`{車)D)Vzd#cYuG@/PySdYL ;1zJ<fEgnKPK PKM>META-INF/manifest.xmlKj0@=VU1q-&fW6X; HFi[S0Oͣ)k7vc^aaӠNZu`ZVzEdZ>T yb`yʝ뛣V4"BO[DȐRȻ)o zL =KbDe̡Rbw c!x!|R!|cD*wS)F$B;ߟ Jn&F] Ýr=˩Wo³̿sivE6ٍmHi7 ȜsiǷPKMfBQPKM>l9..mimetypePKM>TConfigurations2/statusbar/PKM>'Configurations2/accelerator/current.xmlPKM>Configurations2/floater/PKM>Configurations2/popupmenu/PKM>QConfigurations2/progressbar/PKM>Configurations2/menubar/PKM>Configurations2/toolbar/PKM>Configurations2/images/Bitmaps/PKM> "/a 4content.xmlPKM>W+p x$styles.xmlPKM>rSS*meta.xmlPKM>/Thumbnails/thumbnail.pngPKM>  ;settings.xmlPKM>MfBQ@META-INF/manifest.xmlPK}Bsailcut-1.5.0/test-cases/main1.2.4.saildef000066400000000000000000000035611477005247400201130ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/main1.3.3.saildef000066400000000000000000000036301477005247400201100ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/main2.saildef000066400000000000000000000036211477005247400176070ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/rig1.3.3.rigdef000066400000000000000000000017301477005247400175750ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/testBugMitre2-100.saildef000066400000000000000000000036321477005247400216010ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/testBugMitre2-800.saildef000066400000000000000000000036171477005247400216130ustar00rootroot00000000000000 sailcut-1.5.0/test-cases/testBugMitre2.saildef000066400000000000000000000036341477005247400213050ustar00rootroot00000000000000 sailcut-1.5.0/tests/000077500000000000000000000000001477005247400143355ustar00rootroot00000000000000sailcut-1.5.0/tests/geocpp/000077500000000000000000000000001477005247400156125ustar00rootroot00000000000000sailcut-1.5.0/tests/geocpp/geocpp.pro000066400000000000000000000003231477005247400176070ustar00rootroot00000000000000include(../tests.pri) TARGET = tst_geocpp SOURCES += \ ../../src/geocpp/matrix.cpp \ ../../src/geocpp/rect.cpp \ ../../src/geocpp/subspace.cpp \ ../../src/geocpp/vector.cpp \ tst_geocpp.cpp sailcut-1.5.0/tests/geocpp/tst_geocpp.cpp000066400000000000000000000103461477005247400204710ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #ifdef DEBUG #include #endif /** Outputs a CMatrix to a stream. */ std::ostream& operator<< (std::ostream &o, const CMatrix &m) { o << "["; for (size_t i = 0 ; i < m.rows() ; ++i) { for (size_t j = 0; j < m.columns(); ++j) o << m(i, j); if ( i != m.rows() - 1 ) o << std::endl; } o << "]"; return o; } class tst_GeoCpp : public QObject { Q_OBJECT private slots: void testVector(); void testRect(); void testSubSpace(); }; void tst_GeoCpp::testVector() { CVector3d u3(1, 2, 3); CVector3d v3(5, 8, 9); QCOMPARE(u3, CVector3d(1, 2, 3)); //QCOMPARE(u3.length(), 3.74166); QCOMPARE(u3.x(), 1.0); QCOMPARE(u3.y(), 2.0); QCOMPARE(u3.z(), 3.0); u3.setX(5); QCOMPARE(u3, CVector3d(5, 2, 3)); QCOMPARE(u3.x(), 5.0); QCOMPARE(u3.y(), 2.0); QCOMPARE(u3.z(), 3.0); QCOMPARE(v3, CVector3d(5, 8, 9)); QCOMPARE(-v3, CVector3d(-5, -8, -9)); QCOMPARE(u3 + v3, CVector3d(10, 10, 12)); QCOMPARE(u3 - v3, CVector3d(0, -6, -6)); QCOMPARE(u3 * 2, CVector3d(10, 4, 6)); QCOMPARE(2 * u3, CVector3d(10, 4, 6)); u3[2] = 456; QCOMPARE(u3, CVector3d(5, 2, 456)); QCOMPARE(u3.x(), 5.0); QCOMPARE(u3.y(), 2.0); QCOMPARE(u3.z(), 456.0); } void tst_GeoCpp::testRect() { CRect3d r(CPoint3d(-2, -2, -2), CPoint3d(1, 1, 1)); QCOMPARE(r.min, CPoint3d(-2, -2, -2)); QCOMPARE(r.max, CPoint3d(1, 1, 1)); QCOMPARE(r.center(), CPoint3d(-0.5, -0.5, -0.5)); QCOMPARE(r.height(), 3.0); QCOMPARE(r.width(), 3.0); CRect3d r2 = r * 3; QCOMPARE(r2.min, CPoint3d(-5, -5, -5)); QCOMPARE(r2.max, CPoint3d(4, 4, 4)); QCOMPARE(r2.center(), CPoint3d(-0.5, -0.5, -0.5)); QCOMPARE(r2.height(), 9.0); QCOMPARE(r2.width(), 9.0); } void tst_GeoCpp::testSubSpace(void) { const CSubSpace L3A = CSubSpace::line(CPoint3d(0,0,1), CVector3d(1,1,0)); const CSubSpace L3B = CSubSpace::line(CPoint3d(0,0,0), CVector3d(1,1,1)); const CSubSpace P3A = CSubSpace::plane(CPoint3d(2,3,7), CVector3d(1,0,5), CVector3d(0,1,0)); const CSubSpace P3B = CSubSpace::plane(CPoint3d(4,-5,1), CVector3d(-3,0,1), CVector3d(0,1,0)); const CPoint3d p3(2,2,2),q3(2,1,2),r3(4,5,7),s3(2,2,1); CSubSpace h; // lines QCOMPARE(L3A.contains(p3), false); QCOMPARE(L3A.contains(s3), true); QCOMPARE(L3B.contains(p3), true); QCOMPARE(L3B.contains(q3), false); // planes QCOMPARE(P3A.contains(p3), false); QCOMPARE(P3A.contains(r3), false); QCOMPARE(P3B.contains(p3), false); QCOMPARE(P3B.contains(r3), false); // line / line intersection h = L3A.intersect(L3B); QCOMPARE(h.getdim(), 0); QCOMPARE(L3A.contains(h.getp()), true); QCOMPARE(L3B.contains(h.getp()), true); // plane / plane intersection h = P3A.intersect(P3B); QCOMPARE(h.getdim(), 1); QCOMPARE(P3A.contains(h.getp()), true); QCOMPARE(P3B.contains(h.getp()), true); // plane / line intersection h = P3A.intersect(L3A); QCOMPARE(h.getdim(), 0); QCOMPARE(P3A.contains(h.getp()), true); QCOMPARE(L3A.contains(h.getp()), true); // line / plane intersection h = L3A.intersect(P3A); QCOMPARE(h.getdim(), 0); QCOMPARE(P3A.contains(h.getp()), true); QCOMPARE(L3A.contains(h.getp()), true); } QTEST_MAIN(tst_GeoCpp) #include "tst_geocpp.moc" sailcut-1.5.0/tests/sailcpp/000077500000000000000000000000001477005247400157705ustar00rootroot00000000000000sailcut-1.5.0/tests/sailcpp/sailcpp.pro000066400000000000000000000005011477005247400201410ustar00rootroot00000000000000include(../tests.pri) TARGET = tst_sailcpp SOURCES += \ ../../src/geocpp/matrix.cpp \ ../../src/geocpp/matrix4x4.cpp \ ../../src/geocpp/rect.cpp \ ../../src/geocpp/subspace.cpp \ ../../src/geocpp/vector.cpp \ ../../src/sailcpp/panel.cpp \ ../../src/sailcpp/sailcalc.cpp \ tst_sailcpp.cpp sailcut-1.5.0/tests/sailcpp/tst_sailcpp.cpp000066400000000000000000000030661477005247400210260ustar00rootroot00000000000000/* * Copyright (C) Robert Lainé & Jeremy Lainé * See AUTHORS file for a full list of contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "geocpp/geocpp.h" #include "sailcpp/panel.h" class tst_SailCpp : public QObject { Q_OBJECT private slots: void testSide(); }; void tst_SailCpp::testSide() { CSide side(0); // Empty. QCOMPARE(side.left(), 0); QCOMPARE(side.bottom(), 0); // 1 point. side.push_back(CPoint3d(1, 2, 3)); QCOMPARE(side.left(), 1); QCOMPARE(side.bottom(), 2); // 2 points side.push_back(CPoint3d(2, 3, 4)); QCOMPARE(side.left(), 1); QCOMPARE(side.bottom(), 2); // 2 points side.push_back(CPoint3d(-1, -2, -3)); QCOMPARE(side.left(), -1); QCOMPARE(side.bottom(), -2); } QTEST_MAIN(tst_SailCpp) #include "tst_sailcpp.moc" sailcut-1.5.0/tests/tests.pri000066400000000000000000000002321477005247400162100ustar00rootroot00000000000000QT -= gui QT += testlib CONFIG -= app_bundle CONFIG += testcase INCLUDEPATH += ../../src # do not install testcases target.CONFIG += no_default_install sailcut-1.5.0/tests/tests.pro000066400000000000000000000000541477005247400162200ustar00rootroot00000000000000TEMPLATE = subdirs SUBDIRS = geocpp sailcpp